Есть несколько проблем с тем, что вы пытаетесь сделать. Если ваша цель состоит в том, чтобы оставить позади балансировщик нагрузки, я думаю, что вместо того, чтобы пытаться запускать несколько экземпляров вашего проекта, лучшим решением будет использование функций масштабирования, доступных для docker-compose. В частности, если ваша цель состоит в том, чтобы поставить некоторые службы за балансировщиком нагрузки, вы, вероятно, не хотите использовать несколько экземпляров таких вещей, как ваша база данных.
Если вы объедините это с динамическим интерфейсным прокси-сервером, таким как Traefik , вы можете сделать настройку в значительной степени автоматической.
Рассмотрим очень простой пример, состоящий из внутреннего контейнера, на котором работает простой веб-сервер, и внешнего интерфейса traefik:
---
version: "3"
services:
webserver:
build:
context: web
labels:
traefik.enable: true
traefik.port: 80
traefik.frontend.rule: "PathPrefix:/"
frontend:
image: traefik
command:
- --api
- --docker
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
ports:
- "80:80"
- "127.0.0.1:8080:8080"
Если я начну так, я получу один бэкэнд и один фронтенд:
docker-compose up
Но я также могу попросить docker-compose
масштабировать бэкэнд:
docker-compose up --scale webserver=3
В этом случае я получаю один интерфейс и три бэкэнд-сервера. Traefik автоматически обнаружит бэкэнды и проведет циклическое соединение между ними Вы можете скачать этот пример и попробовать его.
Предостережения
Есть несколько аспектов вашей конфигурации, которые необходимо изменить, чтобы эта работа работала (и на самом деле вам нужно будет изменить их, даже если вы создадите несколько экземпляров своего проекта, как вы предложили в своем вопрос).
Конфликтующие пути
Возьмем, к примеру, конфигурацию вашего webserver
контейнера:
volumes:
- ./logs:/var/log/nginx:delegated
Если вы запустите два экземпляра этой службы, оба контейнера будут монтировать ./logs
на /var/log/nginx
. Если они оба попытаются записать в /var/log/nginx/access.log
, у вас будут проблемы.
Самое простое решение здесь - избежать монтирования привязки для таких вещей, как каталоги журналов (и любые другие каталоги, в которые вы будете писать), и вместо этого использовать именованные тома докера.
Жесткое кодирование имен контейнеров
В некоторых местах вы жестко задаете имя контейнера, например:
mysql:
image: mysql:5.7.21
container_name: dl-mysql
Это вызовет проблемы, если вы попытаетесь запустить несколько экземпляров этого проекта или несколько экземпляров контейнера mysql. Не устанавливайте статически имя контейнера.
Устаревший синтаксис ссылок
В вашей конфигурации используется устаревший синтаксис links
:
links:
- mysql
Не делай этого. В современном докере контейнеры в одной сети могут просто ссылаться друг на друга по имени. Другими словами, если ваша составная конфигурация имеет:
mysql:
image: mysql:5.7.21
restart: unless-stopped
working_dir: /application
environment:
- MYSQL_DATABASE=dldl
- MYSQL_USER=docker
- MYSQL_PASSWORD=docker
- MYSQL_ROOT_PASSWORD=docker
volumes:
- ./../:/application
ports:
- "8007:3306"
Другие контейнеры в вашем стеке компоновки могут просто использовать имя хоста mysql
для ссылки на эту службу.