Infra/Docker

[Docker] Compose 파일 작성법과 주요 옵션 총정리

minseoki 2026. 4. 26. 21:54

Docker compose

  • 도커(docker run)의 경우에는 단일 컨테이너를 실행한다.
  • 도커 컴포즈는 여러 종류의 컨테이너를 한번에 띄울 수 있다.
ex) 도커로 3tier를 구성한다면, docker run 을 3번 해서 web-was-db 컨테이너를 각각 구성해야 하고 —link도 구성해줘야 한다. 하지만 docker compose의 경우엔 3종류의 컨테이너를 컴포즈 파일 하나에서 동시에 구성이 가능하다.

image.png

컨테이너를 띄우는 목적은 뭘까?

서비스를 제공하고 싶기 때문이다. 컨테이너 안에 앱, 애플리케이션이 들어있다. 도커 컴포즈에서는 이런 한 종류의 컨테이너를 service라고 지칭한다.

mkdir /com

cd /com

vi docker-compose.yml

docker-compose.yml 이라는 파일명 = 디폴트값

한 개의 서비스로 구성된 도커 컴포즈 파일 편집

services:
#내가 띄울 다양한 종류의 컨테이너들

  webserver:
  #서비스의 이름. 내가 원하는대로 정하면 됨.
    image: nginx
    ports:
    - '8787:80'
    #publish 기능
    networks:
    - webnet
    # 아직 만들진 않았다. 밑에서 만들예정. 놓여질 네트워크

networks:
  webnet:
  # webnet이라는 이름의 네트워크 생성.

샘플 코드.

docker compose up

image.png

잘 동작한다.


docker compose down

도커 컴포즈 삭제

docker compose up -d

docker run 과 비슷하게 -d (detach) 백그라운드로 동작할 수 있다.



볼륨 구성

호스트의 현재 디렉토리에 vtest라는 디렉토리를 구성한 후 간단한 인덱스 파일을 생성하여 컨테이너에 볼륨 구성을 통해 웹루트디렉토리에 넣어주고 싶다.

mkdir ./vtest

경로 생성.

echo compose-volume-test > vtest/index.html

인덱스 파일 생성.

vi docker-compose.yml
services:
#내가 띄울 다양한 종류의 컨테이너들

  webserver:
  #서비스의 이름. 내가 원하는대로 정하면 됨.
    image: nginx
    ports:
    - '8787:80'
    #publish 기능
    networks:
    - webnet
    # 아직 만들진 않았다. 밑에서 만들예정. 놓여질 네트워크
    volumes:
    - ./vtest:/usr/share/nginx/html
    # 호스트의 ./vtest를 컨테이너의 /usr/share/nginx/html에 마운트
networks:
  webnet:
  # webnet이라는 이름의 네트워크 생성.
docker compose up -d

image.png

마운트가 잘 되었다.




docker-compose.yml 옵션들에 대해 알아보자.

networks:

네트워크 정의 및 선택

ports:

-p, publish 옵션

volumes:

-v, 호스트와 컨테이너 마운트

command:

CMD

environment:

-e, 환경변수

depends_on:

의존성 설정(컨테이너 띄울 순서)도 가능.

ex) node.js 앱(todo, weather, chat)의 경우 몽고디비가 연동이 안되면 앱 자체가 죽어버린다. node.js 서비스를 정의하면서 몽고디비를 depends_on 으로 걸어줘야 한다.





/com의 ubun 이라는 경로에서 위 명령어를 활용하여 ubuntu:latest를 동작시키는 compose 파일을 만들어 보자.

네트워크 : ubun_net

mkdir ubun

cd ubun/

vi docker-compose.yml
services:
  ubun:
    image: ubuntu:latest
    networks:
    - ubun_net
    command: "sleep infinity"

networks:
  ubun_net:

docker compose up -d

image.png


docker compose down


environment:
    - ENV_TEST=test

ubun 서비스에 환경변수 추가.

docker compose up -d

docker exec -it ubun-ubun-1 bash

image.png

환경변수가 잘 들어있다.

도커 컴포즈에서는 —link 를 굳이 명시하지 않아도 서비스의 이름으로 찾아갈 수 있다.


실습) wordpress 구성하기!

mysql:8, wordpress:latest를 베이스 이미지로 하여, Dockerfile은 쓰지않고, docker-compose.yml 파일을 구성해보자. publish 포트는 wordpress는 1234로 하고, mysql는 따로 publish 하지 않는다.

mkdir wp

cd wp

vi docker-compose.yml
services:
  wp:
    image: wordpress:latest
    ports:
    - '1234:80'
    environment:
    - WORDPRESS_DB_HOST=dbdb
    - WORDPRESS_DB_NAME=wpdb
    - WORDPRESS_DB_USER=wpuser
    - WORDPRESS_DB_PASSWORD=1234
    networks:
    - wpnet
    depends_on:
    - dbdb

  dbdb:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: '1234'
      MYSQL_USER: 'wpuser'
      MYSQL_PASSWORD: '1234'
      MYSQL_DATABASE: 'wpdb'
    networks:
    - wpnet
networks:
  wpnet:

image.png

성공!





기존에 존재하는 네트워크를 사용하고 싶을 때

docker network create mynet --driver=bridge

네트워크 생성.

image.png


vi docker-compose.yml

image.png

image.png

172.19.0.0 대역에 생성됐다.

빌드한 이미지로 서비스 구성

mkdir build

cd build/

vi Dockerfile
FROM httpd:latest

도커 파일 생성.


vi docker-compose.yml
services:
  myweb:
    build: .
    # docker-compose.yml 파일이 있는 경로(.)의 Dockerfile을 빌드

도커 컴포즈 파일 생성.


docker compose up -d
echo build-test > index.html

index.html 파일 생성.


vi Dockerfile

위에서 생성한 index.html 파일을 넣어보자.

FROM httpd:latest
WORKDIR /usr/local/apache2/htdocs
COPY index.html index.html
docker compose up -d
curl localhost:5959


image.png

기본 페이지가 뜨고 docker-compose up -d 를 했지만 이미지가 빌드되지 않았다.
이미 빌드를 한 적이 있어서 빌드된 이미지가 존재하면 다시 빌드하지 않는다.

docker compose down

컨테이너 종료.

docker compose up -d --build

—build 옵션을 명시해야 계속 빌드한다.


다시 curl을 찍어보면,


image.png

수정한 Dockerfile 대로 다시 빌드가 되었다.

docker compose down

컨테이너 종료.



이번엔 빌드를 하 되, 도커파일을 지정해줘보자.

vi docker-compose.yml
services:
  myweb:
    build: 
    # docker-compose.yml 파일이 있는 경로(.)의 Dockerfile을 빌드
      context: .
      # 디렉토리 지정
      dockerfile: Dockerfile
      # 도커파일의 이름 지정.
    image: myimg:1
    # 빌드해서 나온 이미지의 이름.
    # 단독으로 쓰일때와는 의미가 좀 다르다.

    ports:
    - '5959:80'

context: 도커가 빌드를 시작할 때 참고할 작업 폴더의 위치.

context: . 으로 되어있으면 도커는 현재 폴더에 있는 Dockerfile, 소스코드, package.json 등을 모두 빌드 컨텍스트 라는 임시 공간에 담는다.

위 코드 중 context, build 부분 해석

→ Dockerfile 란 이름의 도커파일로 빌드를 하는데, 지정한 디렉토리(현재 디렉토리)의 모든 내용을 빌드해라.




docker compose scaling

  • —scaling <서비스명>=<컨테이너개수> 로 서비스를 구성하는 컨테이너의 수를 변경할 수 있다.

image.png

image.png

docker-compose.yml 파일에 포트 범위를 명시해준다.


image.png

image.png



하나의 접속 지점을 통해 로드밸런싱이 됐으면 좋겠지만 docker compose 에서는 그게 불가능하다.

서비스를 구성하는 컨테이너마다 호스트의 포트를 1:1 로 맵핑시켜야 한다.

왜?

도커 컴포즈에서 --scale 옵션을 통해 컨테이너 개수를 늘리는 것은 동일한 서비스를 여러 개 복제하여 실행하는 기능에 불과하다. 이 방식은 단순히 물리적인 숫자를 늘려줄 뿐, 외부에서 들어오는 트래픽을 각 컨테이너의 상태나 부하 정도에 맞춰 지능적으로 분산해주는 전문적인 로드밸런싱 기능을 포함하지 않는다.


따라서 여러 개의 컨테이너를 띄우더라도 특정 컨테이너에만 요청이 몰리거나, 장애가 발생한 컨테이너로 접속이 시도되는 등의 한계가 존재한다. 이를 해결하기 위해서는 Nginx나 HAProxy와 같은 별도의 로드밸런서 서비스를 도커 컴포즈 설정에 추가하여 앞단에 배치해야 한다.


전문 로드밸런서는 들어오는 모든 요청을 단일 지점에서 받아 각 컨테이너로 골고루 전달하고, 컨테이너의 생존 여부를 실시간으로 확인하여 정상적인 곳으로만 트래픽을 보내는 가이드 역할을 수행한다. 결과적으로 효율적인 트래픽 분산과 안정적인 서비스 유지를 위해서는 단순한 개수 확장보다는 로드밸런서를 통한 체계적인 관리가 필수적이다.

'Infra > Docker' 카테고리의 다른 글

Docker Swarm 에 대해서...  (1) 2026.05.05
[Docker] 기본 명령어와 주요 옵션 정리  (0) 2026.04.28