Docker 中的 nginx 和 php-fpm
nginx and php-fpm in Docker
我正在Docker设置我的webserver/php工作流程。
但是因为我在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
因为 docker-compose
不适用于 boot2docker,我必须使用 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
,没有问题(这表明主机是在[=中创建的84=]) 但如果我尝试访问 lab.dev/test_autoload/
,我有一个 File not found.
。我知道这是因为 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
中,在php
中位于/srv/http/lab/test_autoload/index.php
中。
我相信问题来自root
and/or fastcgi_param SCRIPT_FILENAME
,但我不知道如何解决。
我尝试了很多东西,比如修改 root
s,使用 rewrite
规则,adding/removing 一些 /
s 等,但没有任何效果它改变了。
再次抱歉所有这些配置,但我认为需要它来描述我所处的环境。
这里有一个错误:
fastcgi_param SCRIPT_FILENAME /srv/http/$fastcgi_script_name;
好的线路是:
fastcgi_param SCRIPT_FILENAME /srv/http$fastcgi_script_name;
这不是一回事。
你的nginx.conf完全是空的,守护进程在哪里关闭;
用户 nginx 行,worker_processes 等。nginx 在 运行 启用 http.
之前需要一些配置文件
在 http conf 中,同样的事情,缺少 mime 类型,default_type,用于 boot2docker.
的日志发送文件配置
你的问题显然不是Docker的问题,而是nginx配置的问题。在使用 fig 之前,您是否使用 运行ning docker 运行 测试过您的应用程序?有效果吗?
终于找到答案了
变量$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/
,我需要在两个不同的地方写(root 和 fastcgi_param)所以我决定自己写一个小 PHP 使用 .json
并将其转换为 servers.conf
文件的脚本。如果有人想看,尽管问,很高兴分享。
我正在Docker设置我的webserver/php工作流程。
但是因为我在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
因为 docker-compose
不适用于 boot2docker,我必须使用 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
,没有问题(这表明主机是在[=中创建的84=]) 但如果我尝试访问 lab.dev/test_autoload/
,我有一个 File not found.
。我知道这是因为 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
中,在php
中位于/srv/http/lab/test_autoload/index.php
中。
我相信问题来自root
and/or fastcgi_param SCRIPT_FILENAME
,但我不知道如何解决。
我尝试了很多东西,比如修改 root
s,使用 rewrite
规则,adding/removing 一些 /
s 等,但没有任何效果它改变了。
再次抱歉所有这些配置,但我认为需要它来描述我所处的环境。
这里有一个错误:
fastcgi_param SCRIPT_FILENAME /srv/http/$fastcgi_script_name;
好的线路是:
fastcgi_param SCRIPT_FILENAME /srv/http$fastcgi_script_name;
这不是一回事。
你的nginx.conf完全是空的,守护进程在哪里关闭; 用户 nginx 行,worker_processes 等。nginx 在 运行 启用 http.
之前需要一些配置文件在 http conf 中,同样的事情,缺少 mime 类型,default_type,用于 boot2docker.
的日志发送文件配置你的问题显然不是Docker的问题,而是nginx配置的问题。在使用 fig 之前,您是否使用 运行ning docker 运行 测试过您的应用程序?有效果吗?
终于找到答案了
变量$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/
,我需要在两个不同的地方写(root 和 fastcgi_param)所以我决定自己写一个小 PHP 使用 .json
并将其转换为 servers.conf
文件的脚本。如果有人想看,尽管问,很高兴分享。