如何正确链接php-fpm和Nginx Docker容器?

2022-08-30 07:10:39

我正在尝试链接 2 个单独的容器:

问题是php脚本不起作用。也许 php-fpm 配置不正确。这是源代码,在我的存储库中。这是文件:docker-compose.yml

nginx:
    build: .
    ports:
        - "80:80"
        - "443:443"
    volumes:
        - ./:/var/www/test/
    links:
        - fpm
fpm:
    image: php:fpm
    ports:
        - "9000:9000"

我用它来构建基于nginx的自定义映像:Dockerfile

FROM nginx

# Change Nginx config here...
RUN rm /etc/nginx/conf.d/default.conf
ADD ./default.conf /etc/nginx/conf.d/

最后,这是我的自定义Nginx虚拟主机配置:

server {
    listen  80;

    server_name localhost;
    root /var/www/test;

    error_log /var/log/nginx/localhost.error.log;
    access_log /var/log/nginx/localhost.access.log;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/.+\.php(/|$) {
        fastcgi_pass 192.168.59.103:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}

任何人都可以帮我正确配置这些容器以执行php脚本吗?

附言我通过 docker-composer 运行容器,如下所示:

docker-compose up

从项目根目录。


答案 1

我知道这是一个老帖子,但我遇到了同样的问题,无法理解为什么你的代码不起作用。经过大量的测试,我发现了原因。

看起来fpm从nginx接收完整路径并尝试在fpm容器中查找文件,因此它必须与nginx配置中完全相同,即使它不存在于nginx容器中。server.root

演示:

docker-compose.yml

nginx:
    build: .
    ports:
        - "80:80"
    links:
        - fpm
fpm:
    image: php:fpm
    ports:
        - ":9000"

    # seems like fpm receives the full path from nginx
    # and tries to find the files in this dock, so it must
    # be the same as nginx.root
    volumes:
        - ./:/complex/path/to/files/

/etc/nginx/conf.d/default.conf

server {
    listen  80;

    # this path MUST be exactly as docker-compose.fpm.volumes,
    # even if it doesn't exist in this dock.
    root /complex/path/to/files;

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

    location ~ ^/.+\.php(/|$) {
        fastcgi_pass fpm:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Dockerfile

FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/

答案 2

不要在nginx配置中对容器的ip进行硬编码,docker link会将链接计算机的主机名添加到容器的hosts文件中,您应该能够通过主机名ping。

编辑:Docker 1.9网络不再需要您链接容器,当多个容器连接到同一网络时,它们的主机文件将被更新,以便它们可以通过主机名相互访问。

每次 Docker 容器从映像启动(甚至停止/启动现有容器)时,容器都会获得 docker 主机分配的新 IP。这些 IP 与实际计算机不在同一子网中。

请参阅 Docker 链接文档(这是 compose 在后台使用的内容)

但是在链接和公开的docker-compose文档中更清楚地解释了

链接

links:
 - db
 - db:database
 - redis

具有别名名称的条目将在此服务的容器内的 /etc/hosts 中创建,例如:

172.17.2.186  db
172.17.2.186  database
172.17.2.187  redis

暴露

公开端口而不将其发布到主机 - 只有链接服务才能访问它们。只能指定内部端口。

如果您将项目设置为通过环境变量获取端口 +其他凭据,则链接会自动设置一堆系统变量

要查看哪些环境变量可用于服务,请运行 。docker-compose run SERVICE env

name_PORT

完整网址,例如.DB_PORT=tcp://172.17.0.5:5432

name_PORT_num_protocol

完整的网址,例如DB_PORT_5432_TCP=tcp://172.17.0.5:5432

name_PORT_num_protocol_ADDR

容器的 IP 地址,例如DB_PORT_5432_TCP_ADDR=172.17.0.5

name_PORT_num_protocol_PORT

公开的端口号,例如DB_PORT_5432_TCP_PORT=5432

name_PORT_num_protocol_PROTO

协议(tcp 或 udp),例如DB_PORT_5432_TCP_PROTO=tcp

name_NAME

完全限定的容器名称,例如DB_1_NAME=/myapp_web_1/myapp_db_1


推荐