带有PHP7 fpm和nginx的多Docker容器 [英] Multi Docker container with PHP7 fpm and nginx
问题描述
我在设置多docker容器环境时遇到问题. 这个想法很标准:
I am having issues with setting up a multi docker container environment. The idea is pretty standard:
- 一个容器正在运行php-fpm
- 另一个是nginx代理
我的phpfpm Docker文件非常简单:
My phpfpm Docker file is as simple as:
FROM php:7.0-fpm
# install the PHP extensions we need
RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* \
&& docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
&& docker-php-ext-install gd mysqli opcache
# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN { \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
echo 'opcache.enable_cli=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
VOLUME /var/www/html
CMD ["php-fpm"]
而Nginx更是如此:
and Nginx is even more so:
FROM nginx
COPY conf.d/* /etc/nginx/conf.d/
conf.d
文件夹中的单个文件default.conf
Where inside the conf.d
folder is a single file default.conf
server {
listen 80;
server_name priz-local.com;
root /var/www/html;
index index.php;
location / {
proxy_pass http://website:9000;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
还有docker-compose.yml
And docker-compose.yml
website:
build: ./website/
ports:
- "9000:9000"
container_name: website
external_links:
- mysql:mysql
nginx-proxy:
build: ./proxy/
ports:
- "8000:80"
container_name: proxy
links:
- website:website
此精确设置完全适用于AWS Elastic Beanstalk.但是,在我的本地docker上,我遇到如下错误:
This exact setup works perfectly on AWS Elastic Beanstalk. However, on my local docker I am getting errors such as:
2016/11/17 09:55:36 [错误] 6#6:* 1 connect()失败(111:连接 拒绝),同时连接到上游,客户端:172.17.0.1,服务器: priz-local.com,请求:"GET/HTTP/1.1",上游: " http://127.0.0.1:9000/",主持人:"priz-local.com:8888 " 172.17.0.1--[17/Nov/2016:09:55:36 +0000]"GET/HTTP/1.1" 502575-""Mozilla/5.0(Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36(KHTML,例如Gecko)Chrome/54.0.2840.71 Safari/537.36"-"
2016/11/17 09:55:36 [error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: priz-local.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9000/", host: "priz-local.com:8888" 172.17.0.1 - - [17/Nov/2016:09:55:36 +0000] "GET / HTTP/1.1" 502 575 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36" "-"
更新 如果我登录到代理容器并尝试卷曲到另一个容器,我将得到此提示:
UPDATE If I log into the proxy container and try curl to the other one I am getting this:
root@4fb46a4713a8:/# curl http://website
curl: (7) Failed to connect to website port 80: Connection refused
root@4fb46a4713a8:/# curl http://website:9000
curl: (56) Recv failure: Connection reset by peer
我尝试的另一件事是:
server {
listen 80;
server_name priz-local.com;
root /var/www/html;
#index index.php;
#charset UTF-8;
#gzip on;
#gzip_http_version 1.1;
#gzip_vary on;
#gzip_comp_level 6;
#gzip_proxied any;
#gzip_types text/plain text/xml text/css application/x-javascript;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location /nginx_status {
stub_status on;
access_log off;
}
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
set $nocache "";
if ($http_cookie ~ (comment_author_.*|wordpress_logged_in.*|wp-postpass_.*)) {
set $nocache "Y";
}
fastcgi_pass website:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
include fastcgi_params;
#fastcgi_cache_use_stale error timeout invalid_header http_500;
#fastcgi_cache_key $host$request_uri;
#fastcgi_cache example;
#fastcgi_cache_valid 200 1m;
#fastcgi_cache_bypass $nocache;
#fastcgi_no_cache $nocache;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
allow all;
expires max;
log_not_found off;
fastcgi_pass wordpress:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
include fastcgi_params;
}
}
该站点开始工作,但是所有资源(js | css | png | jpg | jpeg | gif | ico)现在都返回403
.
The site started to work, but all the resources (js|css|png|jpg|jpeg|gif|ico) are now returning 403
.
我想念什么?
推荐答案
与 R0MANARMY 和一个他的很多帮助,我想我终于了解了问题的根源.
After a very long chat with R0MANARMY and a lot of his help, I think I finally understood the root of the problem.
这里的主要问题是我没有使用docker,因为它本来可以正常工作.
The main issue here is the fact that I was not using docker as it was intended to work.
另一个原因是fpm不是Web服务器,并且代理到它的唯一方法是通过fastcgi(或者不是唯一的方法,但是在这种情况下,简单的proxy_pass不起作用).
Another cause is the fact that fpm is not a webserver, and the only way to proxy into it is through fastcgi (or maybe not the only, but simple proxy_pass does not work in this case).
因此,正确的设置方法是:
So, the correct way of setting it up is:
- 将代码卷安装到两个容器中.
- 通过nginx将
fastcgi
配置为php脚本到php容器中 - 配置虚拟主机以通过nginx直接提供静态资产.
- mounting the code volume into both containers.
- configure
fastcgi
for php scripts through nginx into php container - configure virtual host to serve static assets directly by nginx.
以下是几个示例:
http://geekyplatypus.com/dockerise-your-php-application-with-nginx-and-php7-fpm/
https://ejosh.co/de/2015/08/wordpress-and-docker-the-correct-way/
更新 添加对我有用的实际解决方案:
UPDATE Adding the actual solution that worked for me:
为了更快地进行周转,我决定使用docker-compose和docker-compose.yml用户,如下所示:
For faster turnaround, I decided to user docker-compose and docker-compose.yml looks like this:
website:
build: ./website/
container_name: website
external_links:
- mysql:mysql
volumes:
- ~/Dev/priz/website:/var/www/html
environment:
WORDPRESS_DB_USER: **
WORDPRESS_DB_PASSWORD: ***
WORDPRESS_DB_NAME: ***
WORDPRESS_DB_HOST: ***
proxy:
image: nginx
container_name: proxy
links:
- website:website
ports:
- "9080:80"
volumes:
- ~/Dev/priz/website:/var/www/html
- ./deployment/proxy/conf.d/default.conf:/etc/nginx/conf.d/default.conf
现在,这里最重要的信息是我在两个容器中都安装了完全相同的代码.这样做的原因是因为fastcgi无法提供静态文件(至少据我所知),因此其想法是直接通过nginx提供服务.
Now, the most important piece of information here is the fact that I am mounting exactly the same code to both containers. The reason for that, is because fastcgi cannot serve static files (at least as far as I understand), so the idea is to serve then directly through nginx.
我的default.conf
文件如下所示:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location /nginx_status {
stub_status on;
access_log off;
}
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass website:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_intercept_errors on;
include fastcgi_params;
}
}
因此,此配置通过php请求代理,由fpm容器处理,而其他所有内容均从本地安装的卷中获取.
So, this config, proxies through php request to be handled by fpm container, while everything else is taken from locally mounted volume.
就是这样.我希望它能对某人有所帮助.
That's it. I hope it will help someone.
仅有的几个问题:
- 仅有时
http://localhost:9080
下载index.php文件而不执行该文件 - 从PHP脚本到外部的cURL's花费了很长时间,甚至还不确定如何调试它.
- ONLY sometimes
http://localhost:9080
downloads index.php file instead of executing it - cURL'ing from php script to outside world, takes really long time not sure how to even debug this, at this point.
这篇关于带有PHP7 fpm和nginx的多Docker容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!