Compose не масштабирует сервис с container_name: убираем фиксированное имя

Один worker работает, но docker compose up --scale worker=3 отказывается создавать копии. В конфигурации есть удобное container_name: worker. Оно фиксирует единственное имя контейнера, а несколько экземпляров не могут одновременно носить его на одном Docker Engine.

Compose уже умеет назначать уникальные имена по проекту, сервису и номеру экземпляра. Для связи сервисов внутри сети обычно достаточно имени сервиса. Жёсткое имя контейнера часто появляется из привычки выполнять docker exec, хотя docker compose exec позволяет обращаться к сервису напрямую.

Оставим идентичность сервису, а не экземпляру

Ниже worker просто ждёт и печатает своё hostname. Он не читает очередь и не меняет внешние данные. Важная часть конфигурации — отсутствие container_name и фиксированного опубликованного порта.

services:
  worker:
    image: python:3.12-slim
    command:
      - python
      - -u
      - -c
      - |
        import socket
        import time
        print(socket.gethostname(), flush=True)
        time.sleep(300)

Проверьте файл через docker compose config. Затем в собственном учебном проекте вызовите docker compose up -d --scale worker=3 и docker compose ps. Должны появиться три экземпляра. Логи docker compose logs worker покажут три hostname; конкретные значения генерирует Docker.

Для выполнения команды в определённом экземпляре используйте docker compose exec --index 2 worker python -V. Не сохраняйте автоматически назначенное имя контейнера в прикладной конфигурации: при пересоздании экземпляр может получить другое окружение и идентификатор.

Второй конфликт — порт хоста

Если каждому экземпляру назначить ports: ["8000:8000"], второй не сможет занять тот же порт на том же адресе хоста. Для фонового worker публикация порта вообще может не требоваться. Для нескольких HTTP-экземпляров обычно вводят общий прокси или задают подходящую схему динамической публикации, затем проверяют реальный адрес каждого.

Внутренний порт контейнера при этом одинаков у всех экземпляров и сам по себе конфликта не создаёт: у каждого собственное сетевое пространство. Ошибка касается общей точки входа на хосте. Это полезно различать до изменения порта самого приложения.

Размножить процесс — ещё не разделить работу

Рабочий обработчик должен безопасно конкурировать за задания. Если три процесса читают один локальный файл и каждый выполняет всё содержимое, масштабирование даст тройную обработку. Очередь, подтверждения и защита результата от повторов относятся к логике приложения и должны проверяться отдельно.

Также проверьте разделяемые каталоги: несколько процессов не должны писать разные результаты под одним именем без согласования. Начните с независимых учебных заданий и сравните, какие экземпляры их обработали. Только после этого масштабируйте реальный поток.

Если Compose всё ещё показывает старую конфигурацию, убедитесь, что вы смотрите тот же project name и полный набор файлов -f. Переменная проекта разделяет группы контейнеров, но не разрешает одинаковые фиксированные имена. Поэтому проще удалить ненужный container_name из самого контракта окружения.

На курсе Docker и Docker Compose вы соберёте несколько сервисов, разберёте сети, порты и независимые проекты, затем передадите окружение другому разработчику. Посмотрите программу и научитесь диагностировать конфигурацию до запуска копий приложения.

Продолжить на практике

  • Docker и Docker Compose: контейнеризация приложений ↗

    Упакуйте приложение в Docker и запустите его с PostgreSQL через Compose. Образы, сети, тома, диагностика поломок, обновление версий и восстановление данных — с практикой и итоговым проектом.