У меня есть следующий файл 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, так что это кажется мне немного расточительным.
Я пробовал экспериментировать со следующей настройкой:
volumesFrom
в контейнер nginx, который дал бы ему доступ к моему коду (который я упаковал в контейнер PHP). во время моего процесса сборки). Нет ссылки на док-контейнер PHP, который я могу сделать, чтобы это произошло.Моя конфигурация «работает» в том смысле, что служба Nginx с балансировкой нагрузки теперь может масштабироваться независимо от службы PHP с балансировкой нагрузки. Они оба могут разговаривать друг с другом. Но Nginx, не имеющий моего кода, означает, что он не может не возвращать 404 на все, что я хочу, чтобы мой php upstream обрабатывал.
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 служба/1 контейнер), либо признать, что я не могу масштабировать их как самостоятельно, как хотелось бы (что не конец света).
Разделять объем между этими двумя контейнерами не требуется, PHP-скрипты требуются только для PHP-контейнера, для Nginx требуется только сетевой доступ к PHP-контейнеру, чтобы он мог проксировать запросы.
Чтобы запустить ваше приложение на AWS ECS, вам нужно упаковать Nginx + PHP в один контейнер, чтобы балансировщик нагрузки проксировал запрос к контейнеру, Nginx принимал подключение и проксировал его в PHP, а затем возвращал ответ.
Использование одного контейнера для Nginx в качестве прокси-сервера для нескольких контейнеров PHP невозможно с помощью Fargate, для этого потребуется запустить контейнеры в одной сети и каким-то образом создать прокси-сервер контейнера Nginx и сбалансировать входящие соединения. Кроме того, при развертывании нового PHP-контейнера его необходимо зарегистрировать на Nginx, чтобы он начал принимать подключения.
Интересный подход с использованием NLB, поздравляю с вашими усилиями. Я предложил упаковать их все в один контейнер из-за простоты, так как вам не нравится иметь более 1 службы в контейнере, даже это способ решения, и это не так уж плохо, если ваше приложение простое/небольшое. С другой стороны, вы можете рассмотреть EKS, использующий nginx в качестве Ingress.
У меня была такая же проблема в течение долгого времени, пока я не переместил все свои PHP-приложения в модуль NGINX.
https://unit.nginx.org/howto/cakephp/
Это пример того, как легко настроить один контейнер для обработки статических файлов (html, css, js), а также всего php-кода. Чтобы узнать больше о Unit в Docker, ознакомьтесь с этим. https://unit.nginx.org/howto/docker/
Дайте мне знать, если у вас возникнут проблемы с учебниками.
Интересно, обязательно посмотрю.
Я никогда не видел установки, в которой Nginx и PHP работали в отдельных задачах ECS, которые масштабировались независимо. Я всегда видел, как они оба работают в одной и той же задаче ECS с общей папкой.
Я бы не слишком беспокоился о том, что это «расточительно». Вы добавляете небольшое количество ресурсов ЦП к каждой задаче Fargate ECS, добавляя Nginx к каждой задаче. Я бы больше сосредоточился на том факте, что вы максимально снижаете задержку, запуская их оба в одной задаче, чтобы Nginx мог передавать запросы PHP поверх localhost
.
Я определенно согласен с тем, что оказалось более хлопотным, чем что-либо еще, держать эти два раздельно. Элегантность, которую я получаю от возможности управлять каждой службой по отдельности, приносит мне другие головные боли с nginx, которых я могу избежать, если все они находятся в одном окне. С другой стороны, я много узнал о nginx, и я вижу доказательства того, что моя предполагаемая идея может работать. Собираюсь считать этот ответ правильным и сейчас соберу эти два вместе и, возможно, вернусь к этому позже для науки.
Удалив мои вызовы
try_files
в конфиге, я, по крайней мере, смог увидеть, как эта концепция работает в действии, что подтверждает вашу точку зрения о том, что nginx не нужен доступ к этому коду. Я не согласен с тем, чтобы nginx + php должен были упакованы в один и тот же контейнер: я запускаю оба в одних и тех же подсетях VPC, апстрим nginx идет на NLB, целевая группа которого регистрирует все мои задачи php ECS. Нет необходимости в чем-либо другом, указывающем службе PHP ECS на NLB и позволяя ему выполнять всю работу по регистрации целей. Я соглашусь, что держать их отдельно было больше хлопот, чем пользы.