分离 nginx 和 php-fpm 到不同的 Docker 上

自己之前在用 Docker 的时候,总是将 PHP 和 Nginx 打包到同一个镜像中,然后运行对应的镜像。近段时间正好想着提升自己的技术,就想着将运行环境细化拆分,以便于之后自己做其他语言开发时替换中间镜像,也提升自己对 PHP 和 Docker 的理解

一、下载 Nginx 和 PHP 的 Docker 镜像

通过命令行直接拉取 Docker 远程镜像回到本地

docker pull nginx:1.21.4-alpine-perl
docker pull php:7.2-fpm

这里不选用最新的 latest 版本,而是指定版本,原因很简单,只是为了版本控制

二、创建 php-fpm 配置文件

docker 默认的 php-fpm 配置文件在 /usr/local/etc/php-fpm.d/www.conf,只要编写好配置文件,然后挂载到对应的目录下即可。这里直接创建一个新的文件保存,我的保存在 /home/wenhsing/php/www.conf 中,注意根据实际情况进行调整修改。

[www]
user = www-data
group = www-data
;listen = 127.0.0.1:9000
;将 listten 改成对应服务器的 IP,因为现在的 127.0.0.1 指向的是 Docker 内部
listen = 0.0.0.0:9000
;出于安全原因,建议配置上允许访问的 IP
;listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

三、运行 PHP Docker

docker run -d --name php_c1 \
    -v /home/wenhsing/php/www.conf:/usr/local/etc/php-fpm.d/www.conf \
    php:7.2-fpm

这里的 /home/wenhsing/php/www.conf 是前一步创建的文件的位置,记得替换成你自己文件所在的位置。

四、创建 Nginx 配置文件

创建 Nginx 配置文件,用以替换 Docker 中默认的配置文件(/etc/nginx/conf.d/default.conf)。我这里先创建在 /home/wenhsing/php/default.conf, 内容可以参考下面的配置。

server {
    listen       80;
    listen  [::]:80;

    server_name  localhost;

    location ~ \.php$ {
       # 注意这里是 fpm 所在服务器上的 *.php 文件路径
       root           /var/www/html;
       # 这里不使用本地回环,因为指向的是容器内部,请改为 php-fpm 服务器所在的 IP 和端口
       # fastcgi_pass   127.0.0.1:9000;
       fastcgi_pass   192.168.0.13:9000;
       fastcgi_index  index.php;
       # 注意修改路径,否则可能会出现访问 404 问题
       # fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
       fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
       include        fastcgi_params;
    }
}

这里假设我电脑的 IP 是 192.168.0.2,请根据自身实际情况进行修改。

五、运行 Nginx Docker

docker run -d -name nginx_c1 \
    -v /home/wenhsing/php/default.conf:/etc/nginx/conf.d/default.conf \
    nginx:1.21.4-alpine-perl

六、测试

以交互式登录 php-fpm 容器,这里使用的是第三步中的指定的容器名(php_c1),实际替换成你自己的。

docker exec -it php_c1 /bin/bash

进入容器后默认会在 /var/www/html 目录下,直接创建一个 index.php 文件用于测试

echo "<?php phpinfo();" > index.php

使用浏览器直接访问 localhost/index.php,查看是否运行成功。

七、遇到的问题

  1. Q: Nginx 错误日志中显示「connect() failed (111: Connection refused) while connecting to upstream...」
    如果你碰到这个问题,说明连接失败了,问题的原因很大可能出现在配置的 php-fpm 服务器上,请检查是否使用了本地回环,注意区分容器内部和外部,以及是否改为了 php-fpm 所在的服务器 IP。
  2. Q: Nginx 错误日志中显示「FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream...」
    如果碰到这个问题,你可以开心一会了,这说明了你已经成功的连接上了 php-fpm 服务器。但是,php-fpm 的的配置可能出现问题,看一下 php-fpm 的配置文件 www.conf 设置的监听(listen)的 IP 和端口号是否正确。
  3. Q:如果你在 Nginx 的访问日志中发现了 404, 浏览器访问提示「File not found.」
    只是文件访问不到而已,不要慌,检查一下 Nginx 的 root 配置的路径,注意路径要 php-fpm 服务器上的文件路径。
posted @ 2021-12-07 18:34  Wenhsing  阅读(834)  评论(0编辑  收藏  举报