当 运行 Nginx + PHP-FPM 在两个不同的容器中时,该配置是否可以在不共享代码卷的情况下工作?

When running Nginx + PHP-FPM in two different containers, can that configuration ever work without sharing a code volume?

我有以下用于本地开发的 docker-compose.yaml 文件,可以正常工作:

version: '3.9'

networks:
  backend:
    driver: bridge

services:
  site:
    container_name: nginx
    depends_on: [php]
    image: my-nginx:latest
    networks: [backend]
    ports: ['8080:80', '8081:443']
    restart: always
    volumes: [code:/var/www/html:nocopy]
    working_dir: /var/www/html

  php:
    container_name: php
    image: my-php-fpm:latest
    networks: [backend]
    ports: ['9000:9000']
    volumes: [code:/var/www/html:nocopy]
    working_dir: /var/www/html

volumes:
  code:
    external: true

我正在研究如何在我的生产基础设施中部署它,我喜欢 AWS ECS。我可以创建一个任务定义,它启动一个服务,同时定义两个容器(并且都共享我在构建过程中添加的代码卷)并且应用程序工作。

这个解决方案对我来说似乎很奇怪,因为现在我的应用程序可以横向扩展的唯一方法是每次给我一个 {php + nginx} 容器集。我的 PHP 需求比我的 nginx 需求扩展得更快,所以这让我觉得有点浪费。

我尝试过以下设置:

我的配置“有效”,因为负载平衡 Nginx 服务现在可以独立于负载平衡 PHP 服务进行扩展。他们能够互相交谈。但是 Nginx 没有我的代码意味着它只能 return 404 我希望我的 php 上游处理的任何事情。

server {
    listen 80;
    server_name localhost;

    root /var/www/html/public;
    index index.php index.html;

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

    location /health {
        access_log off;
        return 200 'PASS';
        add_header Content-Type text/plain;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app-upstream;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        proxy_http_version 1.1;
        proxy_set_header   "Connection" "";
    }
}

是否有任何我可以编写的 nginx 配置可以使此设置(没有 nginx 访问我的代码)工作?

感觉我唯一的选择是将相同的代码复制到两个容器中(感觉很奇怪),将它们组合到同一个容器中(这违反了 1 service/1 容器规则),或者接受我不能像我想的那样独立地扩展它们(这不是世界末日)。

不需要在这两个容器之间共享卷,只有 PHP 容器需要 PHP 脚本,对于 Nginx,它只需要对 PHP 容器,因此它可以代理请求。

为了运行你在AWS ECS上的应用,你需要把Nginx + PHP打包在同一个容器中,所以负载均衡器将请求代理到容器,Nginx接受连接并代理它到 PHP,然后是 return 响应。

使用一个容器让 Nginx 充当多个 PHP 容器的代理,使用 Fargate 是不可能的,它需要 运行 在同一网络上连接容器并以某种方式制作 Nginx 容器代理和平衡传入连接。除此之外,当一个新的 PHP 容器被部署时,它应该在 Nginx 上注册以开始接收连接。

在我将所有 PHP 应用程序移动到 NGINX Unit 之前,我经历了同样的挣扎很长一段时间。

https://unit.nginx.org/howto/cakephp/

这是一个示例,可以轻松设置单个容器来处理静态文件(html、css、js)以及所有 php 代码。要了解有关 Docker 中的单位的更多信息,请查看此内容。 https://unit.nginx.org/howto/docker/

如果您对教程有任何问题,请告诉我。

我从未见过 Nginx 和 PHP 运行 在独立扩展的单独 ECS 任务中的设置。我一直看到它们都在同一个 ECS 任务中 运行,有一个共享文件夹。

我不会太担心这是“浪费”。通过向每个任务添加 Nginx,您为每个 Fargate ECS 任务添加了少量 CPU 的使用量。我会更多地关注这样一个事实,即您通过 运行 它们在同一任务中保持尽可能低的延迟,因此 Nginx 可以将请求传递给 PHP 而不是 localhost.