Как решить вашу проблему?
Дано - хост 1.2.3.4
К нему привязаны домены foo.com, bar.com, baz.org. За каждым доменом закреплен сайт, который состоит из PHP, Nginx, MySQL (далее по вкусу). Назовем каждый сайт приложением. С помощью docker-compose можно запустить примерно вот такой конфиг
version: "3.6"
networks:
app_network:
name: foo_net
services:
nginx:
ports:
- target: 80
published: ${APP_PORT}
protocol: tcp
mode: host
volumes:
- ./:/var/www/html
networks:
- app_network
php:
build:
...
volumes:
- ./:/var/www/html
networks:
- app_network
db_server:
ports:
- target: 3306
published: '${APP_DB_PORT}'
volumes:
- ../mysql:/var/lib/mysql
networks:
- app_network
node:
depends_on:
- php
volumes:
- ./:/var/www/html:rw
command: npm install && npm run dev
networks:
- app_network
Прикол в том, что все контейнеры одного приложения видят друг-друга в пределах одной виртуальной сети (app_network) даже без EXPOSE. EXPOSE связывает целевой порт контейнера с портом хоста (1.2.3.4) Без него nginx прекрасно видит PHP-FPM по порту 9000 (только имя контейнера должно быть правильным. В данном примере это будет php:9000)
....
location ~* \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass<b> php:9000;</b>
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
...
, PHP видит mysql по дефолтному порту 3306. Возникает вопрос, зачем же мы прокинули на хост какой-то ${APP_DB_PORT} от db_server. ответ прост - по этому порту можно подключиться напрямую к БД из своей любимой IDE, phpMyAdmin и.д. Соответственно, внешний порт БД для foo.com может быть 33061, для bar.com 33062 а для baz.org - 33063.
Такая же история и с NGINX, который выступает у нас фронтендом приложений. Мы слушаем на хосте ${APP_PORT} и прокидываем из него все в 80 порт соответствующего контейнера. Получается, что по порту 1080 нам ответит foo.com, 1180 - bar.com, а 1280 - baz.org. В итоге, у нас уже на одном хосте крутятся 3 приложения / сайта, которые не мешают друг-другу (и даже не подозревают о существовании друг-друга)
Остается самая малость - выпустить их в интернет. Тут все совсем просто: поднимаете nginx/haproxy/etc и говорите им, что для хостнейма foo.com используй апстрим
127.0.0.1:1080, для bar.com
127.0.0.1:1180 и угадайте сами, что для baz.org. Внимательно отнеситесь к слешам на конце апстрима. Документация вам расскажет, когда они нужны, а когда нет.
Откуда взялись переменные типа ${APP_PORT} ? Их можно задавать в .env файликах, которые будут лежать рядом с docker-compose.yml.
APP_PORT=1180
APP_DB_PORT=33062
В итоге, всех встречает шлюз, в соответствии с именем хоста раскидывает по апстримам, а внутри приложения контейнеры уже сами видят друг-друга.
Схема 100% рабочая, но не без изъянов. Для продакшена повнимательнее изучите нюансы. За подробностями приходите в личку и на мой курс про докер для PHP-разработчиков.