Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чи можна запускати кілька процесів в одному контейнері, наприклад PHP-FPM, Nginx і воркер черги?

Рекомендація Docker - один основний процес на контейнер, а різні відповідальності - окремі контейнери, що взаємодіють через мережу й томи:

services:
  web:      # Nginx
  app:      # PHP-FPM
  queue:    # php artisan queue:work
  scheduler: # php artisan schedule:work

Чому окремі контейнери кращі:

  • незалежне масштабування: воркерів черги може бути п'ять, а вебконтейнерів два;
  • окремі ресурси й ліміти: воркер, що обробляє відео, не з'їсть пам'ять вебзапитів;
  • ізольовані перезапуски й деплой: падіння воркера не вбиває веб;
  • логи й стан кожного процесу окремо, зрозумілий docker ps і healthcheck;
  • PID 1 - сам процес, тож сигнали зупинки доходять напряму.

Той самий образ - різні команди. Не потрібно чотири образи: один образ застосунку, а контейнери відрізняються command:

x-app: &app
  image: myapp:${TAG}
  env_file: .env

services:
  app:   { <<: *app }
  queue: { <<: *app, command: php artisan queue:work --max-jobs=1000 }
  scheduler: { <<: *app, command: php artisan schedule:work }

Коли кілька процесів в одному контейнері виправдані:

  • тісно пов'язані процеси, що мають жити й масштабуватися разом: Nginx + PHP-FPM у одному «вебконтейнері» - поширений і прийнятний компроміс;
  • середовища, що дають лише один контейнер (деякі PaaS);
  • сайдкар-процеси, без яких основний не працює.

Як робити це правильно:

  • менеджер процесів у PID 1 - supervisord, s6-overlay, tini + скрипт. Він запускає процеси, перезапускає впалі й передає сигнали зупинки всім;
  • вивід усіх процесів у stdout/stderr контейнера;
  • визначитися, що робити при падінні одного процесу: перезапустити лише його чи завершити весь контейнер (щоб оркестратор побачив проблему). Тихий перезапуск ховає помилки.

Сучасна альтернатива для Laravel: FrankenPHP поєднує веб-сервер і PHP в одному процесі - зв'язка Nginx + PHP-FPM стає непотрібною, і «вебконтейнер» знову має один процес.

Антипатерн: запускати в одному контейнері ще й базу чи Redis «для простоти» - дані, оновлення й масштабування бази стають залежними від деплою застосунку.

Докладніше в документації: Docker: кілька сервісів у контейнері

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання