← 아티클 목록

docker compose scale로 서비스 복제·스케일 하기

2028-02-21#docker#compose#스케일링

부하 테스트를 위해 워커 컨테이너를 3개 띄우고 싶은데, 같은 서비스를 docker run으로 세 번 실행하긴 번거롭습니다. compose에는 한 서비스를 여러 인스턴스로 복제하는 기능이 있습니다. 다만 "포트를 고정하면 두 번째 컨테이너부터 충돌"하는 함정이 있어서, 스케일은 포트 설계와 함께 봐야 합니다.

--scale로 즉석 복제

가장 빠른 방법은 up 시점에 개수를 지정하는 것입니다.

Docker
docker compose up -d --scale worker=3

이러면 worker 서비스가 myapp-worker-1, myapp-worker-2, myapp-worker-3으로 뜹니다. 확인은 ps로 합니다.

Docker
docker compose ps
OUTPUT
NAME             IMAGE        STATUS         PORTS
myapp-worker-1   myapp:dev    Up 4 seconds
myapp-worker-2   myapp:dev    Up 4 seconds
myapp-worker-3   myapp:dev    Up 4 seconds

포트 충돌 함정

여기서 서비스에 고정 포트 매핑이 있으면 두 번째 컨테이너부터 실패합니다.

YAML
services:
  web:
    image: myapp:dev
    ports:
      - "8080:80"     # 호스트 8080 고정 → 복제 불가

--scale web=3을 걸면 Bind for 0.0.0.0:8080 failed: port is already allocated 에러가 납니다. 해결은 호스트 포트를 비우거나 범위로 주는 것입니다.

YAML
services:
  web:
    image: myapp:dev
    ports:
      - "80"          # 호스트 포트는 도커가 랜덤 할당

이러면 각 인스턴스가 서로 다른 호스트 포트를 받아 충돌하지 않습니다. 실제로 어떤 포트가 붙었는지는 docker compose port web 80로 확인합니다.

선언적으로 — deploy.replicas

매번 플래그를 주기 싫다면 compose 파일에 개수를 박아둘 수 있습니다.

YAML
services:
  worker:
    image: myapp:dev
    deploy:
      replicas: 3
방식적합한 상황
--scale svc=N임시 실험, 부하 테스트
deploy.replicas: N항상 N개로 띄우는 기본 구성

deploy.replicas는 Swarm용 필드였지만 최근 compose는 일반 up에서도 존중합니다. 둘을 같이 쓰면 --scale 값이 우선합니다.

로드밸런싱은 어떻게

같은 네트워크의 다른 서비스가 worker라는 이름으로 접근하면, 도커 내장 DNS가 여러 인스턴스로 라운드로빈 분배합니다. 즉 호스트 포트를 노출하지 않고 서비스 이름으로만 통신하면 별도 LB 없이 분산이 됩니다.

체크리스트

Docker
# 1. 고정 호스트 포트가 있으면 스케일 전에 제거/범위화
docker compose config | grep -A2 ports

# 2. 복제 실행
docker compose up -d --scale worker=3

# 3. 인스턴스와 할당 포트 확인
docker compose ps
docker compose port web 80

스케일이 안 늘어나는 대부분의 원인은 고정 포트 매핑입니다. 포트부터 비우면 나머지는 매끄럽게 동작합니다.


compose로 서비스를 여러 개 복제하고 포트 충돌을 직접 일으켜보며 해결하는 실습은 도커 트랙에서 회원가입 없이 무료로 해볼 수 있습니다.