在Docker中使用nginx和php-fpm

4
我正在将我的Web服务器/PHP工作流程Docker化。
但是因为我在Windows上,我需要使用虚拟机。我选择了boot2docker,它是在Virtualbox中运行的Tiny Core Linux,并适用于Docker。
我选择了三个容器:
- nginx:官方nginx容器; - jprjr/php-fpm:一个php-fpm容器; - mysql:用于数据库。
在boot2docker中,/www/包含我的Web项目和conf/,其中包含以下树形结构:
conf
│
├───fig
│       fig.yml
│
└───nginx
        nginx.conf
        servers-global.conf
        servers.conf

因为boot2docker不支持docker-compose,所以我必须使用fig来自动化一切。这是我的fig.xml:
mysql:
 image: mysql
 environment:
  - MYSQL_ROOT_PASSWORD=root
 ports:
  - 3306:3306

php:
 image: jprjr/php-fpm
 links:
  - mysql:mysql
 volumes:
  - /www:/srv/http:ro
 ports:
  - 9000:9000

nginx:
 image: nginx
 links:
  - php:php
 volumes:
  - /www:/www:ro
 ports:
  - 80:80
 command: nginx -c /www/conf/nginx/nginx.conf

这是我的 nginx.conf 文件:

daemon off;

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        off;

    keepalive_timeout  65;

    index    index.php index.html index.htm;

    include /www/conf/nginx/servers.conf;

    autoindex on;
}

还有 servers.conf 文件:

server {
    server_name lab.dev;
    root /www/lab/;

    include /www/conf/nginx/servers-global.conf;
}

# Some other servers (vhosts)

还有 servers-global.conf 文件:

listen 80;

location ~* \.php$ {
    fastcgi_index   index.php;
    fastcgi_pass    php:9000;
    include         /etc/nginx/fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME     /srv/http$fastcgi_script_name;
}

现在的问题是(很抱歉需要这么多配置,但我相信这是为了清楚地解释问题):如果我访问lab.dev,没有问题(这表明主机已在Windows中创建),但如果我尝试访问lab.dev/test_autoload/,就会出现文件未找到。我知道这是由于php-fpm无法访问文件引起的,nginx日志也证实了这一点:

nginx_1 | 2015/05/28 14:56:02 [error] 5#5: *3 FastCGI sent in stderr:
"Primary script unknown" while reading response header from upstream,
client: 192.168.59.3, server: lab.dev, request: "GET /test_autoload/ HTTP/1.1",
upstream: "fastcgi://172.17.0.120:9000", host: "lab.dev", referrer: "http://lab.dev/"

我知道在两个容器中的lab/test_autoload/目录下都有一个index.php文件,我已经检查过了。在nginx中,它位于/www/lab/test_autoload/index.php/srv/http/lab/test_autoload/index.php中的php

我相信问题来自于root和/或fastcgi_param SCRIPT_FILENAME,但我不知道该如何解决。

我尝试了很多方法,比如修改root、使用rewrite规则、添加/删除一些/等,但没有任何改变。

再次抱歉为这个配置添麻烦,但我认为描述我的环境是必要的。


我不确定你从哪里得到的信息说docker-compose不能与boot2docker一起工作。它可以很好地运行。 - Abdullah Jibaly
1
很遗憾,这里和那里都有关于编程的内容。 - tleb
哦,我明白了,你想直接在boot2docker中安装它。你可以在一个新的容器中运行docker-compose,我相信那样会起作用。 - Abdullah Jibaly
3个回答

2

我终于找到了答案。

变量$fastcgi_script_name没有考虑根目录(这是合理的,否则它将包括www/)。这意味着全局文件无法工作。以下是一个例子:

# "generated" vhost
server {
    server_name lab.dev;
    root /www/lab/;

    listen 80;

    location ~* \.php$ {
        fastcgi_index   index.php;
        fastcgi_pass    php:9000;
        include         /etc/nginx/fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME     /srv/http$fastcgi_script_name;
        # I need to add /lab after /srv/http because it requests PHP to look at the root of the web files, not in the lab/ folder
        # fastcgi_param   SCRIPT_FILENAME     /srv/http/lab$fastcgi_script_name;
    }
}

这意味着我不能只在一个地方写lab/,我需要在两个不同的地方(根目录和fastcgi_param)写入,所以我决定编写一个小的PHP脚本,使用.json并将其转换为servers.conf文件。如果有人想看一下,只需问一声,我很乐意分享它。

请求共享文件。 - luckydonald
抱歉,我重新安装了系统并且不再使用PHP(也不用Docker)了。 :| - tleb
那么你不再有servers.conf文件了吗? - luckydonald
不好意思,正如问题所示,这只是一系列看起来类似于所示的虚拟主机列表。至于脚本,它只是从JSON(现在建议使用YAML)中获取数据并填充模板。 - tleb

1

There's a mistake here:

fastcgi_param   SCRIPT_FILENAME     /srv/http/$fastcgi_script_name;

好的代码是:

fastcgi_param   SCRIPT_FILENAME     /srv/http$fastcgi_script_name;

这不是同一件事。


我的错。这是我做的许多测试之一,即使使用/srv/http$fastcgi_script_name也不起作用。我会编辑原始帖子。 - tleb

0

你的nginx.conf文件完全为空,缺少daemon off、user nginx、worker_processes等配置项。在运行http之前,nginx需要一些配置文件。

在http conf中,同样缺少mime types、default_type、logs sendfile at on for boot2docker等配置项。

你的问题显然不是Docker的问题,而是nginx配置的问题。在使用fig之前,你是否尝试过使用docker run来运行你的应用程序?它是否正常工作?


我已编辑OP以显示我的整个nginx。正如我所说,我可以访问lab.dev(因为autoindex on),这表明我的配置是有效的,除了当我想通过调用文件夹来访问文件夹的index.php时。 - tleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接