如何使PHP-FPM与FastCGI一起与Nginx-proxy一起使用?

时间:2020-07-15 17:26:59

标签: php docker fastcgi jwilder-nginx-proxy

我试图通过php-fpm使nginx-proxythe official php imagefastcgi变体一起工作。不幸的是,我似乎无法这样做。我确定问题只是我不知道的简单问题。

我已尽我所能使用the instructions来使用nginx-proxy,并将其归结为一种非常简单的方法来重新创建问题。这是我的docker-compose.yml文件:

version: "3"

services:
  proxy:
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    environment:
      - DEFAULT_HOST=test.local

  fpm:
    image: php:fpm
    environment:
      - VIRTUAL_HOST=test.local
      - VIRTUAL_PROTO=fastcgi

然后我通过运行以下命令放入一个简单的index.php文件:

docker container exec -it web_fpm_1 /bin/bash -c 'echo "<?php phpinfo(); ?>" > /var/www/html/index.php'

(由于项目位于名为web_的目录中,因此将web/放在前面。)

我还修改了hosts文件,将test.local指向127.0.0.1,因此可以对其进行测试。 但是,每次浏览到test.local的尝试都会导致白页空白。

据我所知,web_proxy_1容器的日志并未显示任何异常:

❯ docker container logs web_proxy_1
WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one
is being generated in the background.  Once the new dhparam.pem is in place, nginx will be reloaded.
forego     | starting dockergen.1 on port 5000
forego     | starting nginx.1 on port 5100
dockergen.1 | 2020/07/20 19:24:54 Generated '/etc/nginx/conf.d/default.conf' from 2 containers
dockergen.1 | 2020/07/20 19:24:54 Watching docker events
dockergen.1 | 2020/07/20 19:24:54 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload'
nginx.1    | test.local 172.18.0.1 - - [20/Jul/2020:19:25:12 +0000] "GET / HTTP/1.1" 200 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
nginx.1    | test.local 172.18.0.1 - - [20/Jul/2020:19:25:13 +0000] "GET /favicon.ico HTTP/1.1" 200 5 "http://test.local/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"

web_fpm_1容器的日志显示,除200响应外,没有其他任何发送内容:

❯ docker container logs web_fpm_1
[20-Jul-2020 19:24:54] NOTICE: fpm is running, pid 1
[20-Jul-2020 19:24:54] NOTICE: ready to handle connections
172.18.0.3 -  20/Jul/2020:19:25:12 +0000 "- " 200
172.18.0.3 -  20/Jul/2020:19:25:13 +0000 "- " 200

我在做什么错了?

偶然地,我在nginx-proxy reponginx-proxy Google Groupphp repo上问了这个问题。我要么没有回应,要么他们不给力。

2 个答案:

答案 0 :(得分:2)

默认生成的nginx-proxy配置无法正常工作。

我认为VIRTUAL_ROOT environment variable有点混乱,因为问题的根源是PHP通过SCRIPT_FILENAME获取了错误的路径(这就是为什么您看不到PHP输出的原因)并且没有{{1 }}和try_files符号(这就是为什么您得到200的所有内容)的原因。

我已经在GitHub中使用=404进行了准备工作,以演示它可以与nginx配置中的现有docker-compose一起使用。

https://github.com/flowl/so6292053

我已将SCRIPT_FILENAME更改为test.local

我认为要使其正常工作,您将不得不为test.localhost使用nginx模板,因此生成的nginx-proxy确实适用于php fpm并包含缺少的fastcgi参数。 / p>

另一种方法是将PHP和手动配置的Web服务器(nginx)打包到一个项目中,并在一个独立的项目中使用自动反向nginx代理。 这将使您花费额外的运行时间,但可以提供更多控制权和更轻松的部署。

或者,您可能想看看default.conf,它与traefik基本上相同。

答案 1 :(得分:1)

Daniel的答案肯定是正确的。我将带有nginx的php-fpm图像用作php网站的主要堆栈。话虽如此,我不使用nginx-proxy docker镜像。相反,我在主机上使用普通的nginx,并配置端口以指向后端php-fpm docker映像。

我也不使用docker-compose。由于它只是运行单个站点的Docker容器,因此我不需要它。这是一个示例docker run命令:

docker rm -f www.example.com || true
docker run -itd -p 9001:9000 -P \
        --name www.example.com \
        --volume /var/www/html/www.example.com:/var/www/html/www.example.com \
        --link mariadb:database.example.com \
        --restart="always" \
        --hostname="example.com" \
    --log-opt max-size=2m \
    --log-opt max-file=5 \
        mck7/php-fpm:7.4.x-wordpress

这是一个示例nginx配置:

server {
  server_name example.com www.example.com;

  location ~ /.well-known {
    allow all;
  }

  location ~ /\.ht {
    deny all;
  }

  root /var/www/html/www.example.com/src;

  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
      return 404;
    }

    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO       $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

    fastcgi_pass   127.0.0.1:9001;
    fastcgi_index  index.php;
  }
}

有关此设置的一些事项很关键。重新映射docker容器的端口。在此示例中,我将端口9001映射到9000。另一个“陷阱”是容器的根必须是主机上的实际位置。我不知道为什么会这样,但是无论出于何种原因,docker认为它所使用的路径也必须实际上是主机上的路径。