带有PHP7 fpm和nginx的多Docker容器 [英] Multi Docker container with PHP7 fpm and nginx

查看:136
本文介绍了带有PHP7 fpm和nginx的多Docker容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在设置多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:

  1. 将代码卷安装到两个容器中.
  2. 通过nginx将fastcgi配置为php脚本到php容器中
  3. 配置虚拟主机以通过nginx直接提供静态资产.
  1. mounting the code volume into both containers.
  2. configure fastcgi for php scripts through nginx into php container
  3. 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.

仅有的几个问题:

  1. 仅有时http://localhost:9080下载index.php文件而不执行该文件
  2. 从PHP脚本到外部的cURL's花费了很长时间,甚至还不确定如何调试它.
  1. ONLY sometimes http://localhost:9080 downloads index.php file instead of executing it
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆