1) Запуск нескольких процессов в одном контейнере противоречит концепции докера. Докер сделан так, чтобы запускать один процесс (не считая дочерних процессов)
По хорошему вам нужно запускать fpm и nginx в отдельных контейнерах. При этом возникает несколько проблем:
- нужно чтобы контейнер nginx мог обратиться к контейнеру fpm по сети
- нужно чтобы nginx мог раздавать статику, которая обычно является частью приложения и находится в контейнере fpm
- нужно раздавать загружаемые файлы
Проще всего с загружаемыми файлами. Они в любом случае не должны храниться в контейнере и скорее всего это будет volume, который монтируется в оба контейнера.
Взаимодействие между контейнерами по сети тоже штука не сложная, но зависит от способа запуска контейнера.
Если контейнеры запущены через docker run в одной сети (поведение по умолчанию), то они видят друг друга по сети и могут использовать имя контейнера как dns имя.
Если два контейнера запущены в рамках одного docker-compose.yml файла (это ещё называется docker compose project), то они тоже друг друга видят, но уже не по имени контейнера, а по имени сервиса (ключ под которым контейнер указан в секции services).
Если приложение запускается в kubernetes, то там по умолчанию все контейнера pod'a имеют общий локалхост и могут обращаться к друг другу через 127.0.0.1.
Всё это - поведение по умолчанию, которое можно изменить явно указывая какую сеть использовать, какой hostname должен быть у контейнера и т.д.
Важно: nginx работает с dns в обход стандартных инструментов операционной системы. Если вы используете в директивах proxy_pass, fastcgi_pass доменное имя, а не ip адрес, вам нужно дополнительно указать в конфиге директиву
resolver <dns-ip>;
, где в качестве нужно указать ip адрес dns сервера.
Для докера это обычно 127.0.0.11, для кубера это адрес внутреннего dns сервера.
Раздавать статику можно по разному. Два концептуально разных способа:
- собрать образ nginx в котором есть статика, тут можно либо наследовать образ как сделали это вы, либо копировать статику в чистый образ nginx, что несколько чище и красивее
- убрать статику из образа вообще, выделив её в volume или cdn, но тут придётся при отгрузке сервиса актуализировать статику во внешнем хранилище
2) если очень хочется запустить несколько процессов в контейнере, то нужно запустить один процесс, который запустит остальные. Есть такие программы - менеджеры процессов. Это может быть supervosord, pm2, runit и т.п.
Это такая программа, основной задачей которой является запуск других программ. Обычно у неё есть свой файл конфигурации, в котором вы описываете какие программы запустить и как это сделать.
Ещё раз повторю - докер придуман не для этого. Не стоит делать этот приём основным при работе с докером.
Это костыль. Он иногда нужен, но очень редко.
3) То что nginx отдаёт код index.php, это проблема не настройки контейнеров, а конфигурации nginx. Если бы проблема была только в контейнерах, то вы бы получили не код скрипта, а 502.
Первое что бросается в глаза в вашем конфиге - это регулярка в локейшене для обработки php скриптов.
Попробуйте сделать
как здесь.