Docker:Nginx和php5-fpm码头工人没有说话

时间:2014-11-21 06:45:26

标签: nginx docker php coreos

我想做一个完全停靠的Drupal安装。我的第一步是使用基于Debian的Nginx和php5-fpm运行容器。我在CoreOS alpha频道上(使用Digital Ocean。)

我的Dockerfiles如下:

Nginx的:

FROM debian
MAINTAINER fvhemert
RUN apt-get update && apt-get install -y nginx && echo "\ndaemon off;" >> /etc/nginx/nginx.conf
CMD ["nginx"]
EXPOSE 80

这个容器可以很好地构建和运行。我在服务器ip上看到了默认的Nginx页面。

的php5-FPM:

FROM debian
MAINTAINER fvhemert
RUN apt-get update && apt-get install -y \
            php5-fpm \
            && sed 's/;daemonize = yes/daemonize = no/' -i /etc/php5/fpm/php-fpm.conf
CMD ["php5-fpm"]
EXPOSE 9000

此容器也可以毫无问题地构建,并在启动时保持运行。

我先用:

启动php5-fpm容器
docker run -d --name php5-fpm freek/php5-fpm:1

广告然后我开始Nginx ,,链接到php5-fpm:

docker run -d -p 80:80 --link php5-fpm:phpserver --name nginx freek/nginx-php:1

链接似乎有效,/ etc / hosts中有一个名为phpserver的条目。两个码头工人都跑:

core@dockertest ~ $ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
fd1a9ae0f1dd        freek/nginx-php:4   "nginx"             38 minutes ago      Up 38 minutes       0.0.0.0:80->80/tcp   nginx
3bd12b3761b9        freek/php5-fpm:2    "php5-fpm"          38 minutes ago      Up 38 minutes       9000/tcp             php5-fpm

我调整了一些配置文件。对于Nginx容器,我编辑了/ etc / nginx / sites-enabled / default并更改了:

server {
        #listen   80; ## listen for ipv4; this line is default and implied
        #listen   [::]:80 default_server ipv6only=on; ## listen for ipv6

        root /usr/share/nginx/www;
        index index.html index.htm index.php;

(我添加了index.php)

进一步说:

location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
        #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
        #
        #       # With php5-cgi alone:
                fastcgi_pass phpserver:9000;
        #       # With php5-fpm:
        #       fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }

在php5-fpm docker中,我更改了/etc/php5/fpm/php.ini:

cgi.fix_pathinfo=0

php5-fpm运行:

[21-Nov-2014 06:15:29] NOTICE: fpm is running, pid 1
[21-Nov-2014 06:15:29] NOTICE: ready to handle connections

我也将index.html更改为index.php,它看起来像这样(/usr/share/nginx/www/index.php):

<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body bgcolor="white" text="black">
<center><h1>Welcome to nginx!</h1></center>

<?php
phpinfo();
?>

</body>
</html>

我已经从Nginx泊坞窗扫描了9000端口,它显示为已关闭。当然不是一个好兆头:

root@fd1a9ae0f1dd:/# nmap -p 9000 phpserver

Starting Nmap 6.00 ( http://nmap.org ) at 2014-11-21 06:49 UTC
Nmap scan report for phpserver (172.17.0.94)
Host is up (0.00022s latency).
PORT     STATE  SERVICE
9000/tcp closed cslistener
MAC Address: 02:42:AC:11:00:5E (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds

Nginx记录:

root@fd1a9ae0f1dd:/# vim /var/log/nginx/error.log
2014/11/20 14:43:46 [error] 13#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 194.171.252.110, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "128.199.60.95"
2014/11/21 06:15:51 [error] 9#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 145.15.244.119, server: localhost, request: "GET / HTTP/1.0", upstream: "fastcgi://172.17.0.94:9000", host: "128.199.60.95"

是的,出错了,浏览我的Nginx实例时,我一直收到502错误的网关错误。

我的问题是:究竟出了什么问题?我的猜测是我错过了php配置文件中的一些设置。

编辑更多细节: 这是结果(来自php5-fpm容器内部,在apt-get install net-tools之后):

  

root @ 3bd12b3761b9:/ #netstat -tapen
  有效的互联网连接
  (服务器和已建立)Proto Recv-Q Send-Q本地地址
  外部地址状态用户Inode PID /程序名称

从Nginx容器内部:

  

root @ fd1a9ae0f1dd:/ #netstat -tapen
  有效的互联网连接
  (服务器和已建立)Proto Recv-Q Send-Q本地地址外部地址状态用户Inode PID /程序   name tcp 0 0 0.0.0.0:80 0.0.0.0:*
  LISTEN 0 1875387 -

EDIT2: 进展!

在php5-fpm容器中,在文件中:

/etc/php5/fpm/pool.d/www.conf

我将listen参数从某个套接字名称更改为:

listen = 9000

现在,当我访问我的网页时,我收到错误消息: &#34;未指定输入文件。&#34;

可能我在某处有拖尾/错误。我会更仔细地研究它!

EDIT3:

所以我用上面提到的改动重建了码头工人,似乎他们正在谈论。但是,我的网页告诉我:&#34;找不到文件。&#34; 我非常肯定它与nginx发送到php-fpm的文档有关,但我不知道它应该是什么样子。我在使用始终有效的套接字方法时使用了默认值。现在它已经不再适用了。什么应该在/ etc / nginx / sites-enabled / default下位置〜.php $ {?

3 个答案:

答案 0 :(得分:13)

它不起作用的原因是,正如您自己发现的那样,nginx只将PHP文件的路径发送到PHP-FPM,而不是文件本身(这将是非常低效的)。解决方案是使用第三个仅数据的VOLUME容器来托管文件,然后将它安装在两个docker实例上。

FROM debian
VOLUME /var/www
CMD ['true']

构建上面的Dockerfile并创建一个实例(例如调用它:storage-www),然后使用选项运行nginx和PHP-FPM容器:

--volumes-from storage-www

如果您在同一台物理服务器上运行这两个容器,那将会有效。 但是,如果将那个仅数据的容器放在网络文件系统上,例如GlusterFS,你仍然可以使用不同的服务器,这是非常有效的,并且可以通过大规模网络进行分发。

希望有所帮助。

<强>更新

截至2015年,在容器之间建立持久链接的最佳方法是使用docker-compose

答案 1 :(得分:2)

所以,我测试了所有设置,并且没有在docker之间工作,而他们在1台服务器上使用相同的设置(或者也可能在一个docker中)。然后我发现php-fpm没有从nginx获取php文件,它正在接收路径,如果它在自己的容器中找不到相同的文件则会生成“找不到文件”。请参阅此处了解更多信息:https://code.google.com/p/sna/wiki/NginxWithPHPFPM所以这可以解决问题而不是问题,遗憾的是。对于想要使用多个php-fpm服务器进行负载平衡的人来说,这非常烦人,他们必须对所有内容或类似内容进行rsync。我希望有一天我能找到更好的解决方案。谢谢你的答复。

编辑:也许我可以在两个容器中安装相同的卷并使其以这种方式工作。但是,当使用多个服务器时,这不是一个解决方案。

答案 2 :(得分:1)

当您在容器中时

根@ fd1a9ae0f1dd:/# ,检查用于

的端口

netstat -tapen | grep“:9000”

netstat -lntpu | grep“:9000”

或没有grep的相同命令