Skip to main content

Command Palette

Search for a command to run...

Docker Compose

Updated
4 min read
Docker Compose

Docker Compose

Docker Compose란?

이전에 도커 이미지를 빌드하고 컨테이너를 빌드할 때 다양한 옵션이 달린 상당히 복잡한 명령어들을 입력해서 굴리고는 했다.

그런데 아무래도 복잡한 명령어로 여러 개의 컨테이너로 구성된 시스템을 실행하는 것은 조금 불편할 수 있다.

이를 위해 사용될 수 있는 것이 Docker Compose인데, 시스템 구축과 관련된 명령어를 하나의 텍스트 파일(Compose 파일)에 적어 복잡한 명령어 대신 한 번의 명령어로 시스템 전체를 실행하고 관리할 수 있게 하는 것이다.

도커가 사용되는 프로그램들을 보면 항상 있는 yaml파일들이 바로 이것이다.

여기서도 전에 옵션으로 붙여주었던 포트, 환경변수, 볼륨, 네트워크에 대한 처리도 물론 가능하다.

Compose 파일 만들기

Compose 파일은 docker-compose.yaml 파일을 만들어주는 것으로 시작한다.

아래는 compose파일의 일부로

version: "3.8"
services:
  mongodb:
    image: "mongo"
    volumes:
      - data:/data/db
    #environment:
      #MONGO_INITDB_ROOOT_USERNAME: max
      #MONGO_INITDB_ROOOT_PASSWORD: secret
    env_file:
      - ./env/mongo.env
  backend:
  frontend:

파이썬처럼 들여쓰기와 콜론으로 작성된다.

가장 첫 줄의 compose의 버전을 적어주는 것으로 시작해서 서비스에는 기존에 구성해놨던 디비, 백엔드, 프론트엔드를 각각 넣어준다.

보이는 것처럼 이미지와 볼륨을 위와 같이 추가해줄 수 있다. 환경변수를 하드코딩할 수도 있지만 env_file: 를 통해 .env파일을 불러올 수도 있다.

보면 볼륨과 env_file의 아래 요소에만 -가 붙어있는데, 콜론과 공백이 없는 단일 값의 경우 -를 붙여주어야한다.

Compose 파일 없이 작업할 때 네트워크를 설정해주었었는데, Compose파일에도

network:
    - goals-network

네트워크를 추가할 수는 있으나 대부분의 경우 이 작업을 할 필요가 없다고 한다.

컴포즈 파일을 이용할 경우 도커가 이 컴포즈 파일에 특정된 모든 서비스에 대해 새 환경을 자동으로 생성하고 모든 서비스를 네트워크에 추가하기 때문에, 따로 설정해주지 않아도 하나의 네트워크 아래에서 작동한다는 것이다.

그나저나 볼륨은 따로 최상위에

version: "3.8"
services:
  mongodb:
    image: "mongo"
    volumes:
      - data:/data/db
    #environment:
    #MONGO_INITDB_ROOOT_USERNAME: max
    #MONGO_INITDB_ROOOT_PASSWORD: secret
    env_file:
      - ./env/mongo.env
  # backend:
  #frontend:

volumes:
  data:

와 같이 적어줘야한다. 볼륨에 대한 정보가 있는데 이렇게 쓰는 것이 이상해보일 수 있지만 이는 명명된 볼륨을 인식하기 위해 필요한 구문이다.

+) 리눅스에 Docker Compose 설치하기

맥과 윈도우에는 기본적으로 도커와 함께 설정되나 리눅스의 경우 따로 설치해줘야한다.

그런데 이제 docker compose는 도커의 cli 플러그인으로 동작하기 때문에 플러그인으로 다운받아주고

DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}                                                                                                  ─╯
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.34.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 71.4M  100 71.4M    0     0  9696k      0  0:00:07  0:00:07 --:--:-- 11.2M

  ~ ──────────────────────────────── ✘ 255  max-env at  23:11:24 ─╮
❯ chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose                 ─╯


  ~ ──────────────────────────────────────  max-env at  23:12:19 ─╮
❯ docker compose version                                             ─╯

Docker Compose version v2.34.0

하면 위와 같이 나온다.

Docker Compose Up Down

현재 플러그인으로 설치되어있으므로

docker compose up

으로 실행해주면 된다.

이를 실행하면 뭔가 많이 쏟아져 나오는데 위로 올려보면

❯ docker compose up                                                                                                                              ─╯
WARN[0000] /home/max/devops/study_docker/section6/docker-compose.yaml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] Running 3/3
 ✔ Network section6_default      Created                                                                                                       0.3s
 ✔ Volume "section6_data"        Created                                                                                                       0.0s
 ✔ Container section6-mongodb-1  Created                                                                                                       0.0s
Attaching to mongodb-1

네트워크를 컴포즈 파일에서 지정하지 않았음에도 생성된 것을 확인 가능하다. 디폴트로는 이걸 attached모드로 실행한다.

detached모드로 실행하고 싶다면

 docker compose up -d                                                                                                                           ─╯
WARN[0000] /home/max/devops/study_docker/section6/docker-compose.yaml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] Running 1/1
 ✔ Container section6-mongodb-1  Started

로 옵션을 붙여준다.

반대로

docker compose down

을 써주면 모든 컨테이너가 내려가고 생성된 디폴트 네트워크와 모든 것이 종료된다. 그러나 -v 플래그를 써주지 않으면 볼륨은 날아가지 않는다. 볼륨까지 날려버리려면

docker compose down -v

면 된다.

다중 컨테이너 작업하기

이제 남은 백엔드와 프론트엔드를 처리할 차례다.

가장 먼저 도커 이미지 빌드에 대한 정보를 제공할 수 있는데,

 backend:
    #build: ./backend
    build: 
      context: ./backend
      dockerfile: Dockerfile

사실 도커파일이 상대경로상 백엔드 디렉토리에 있기에 주석처리된 저 부분으로도 현재 상황에선 충분하다.

볼륨과 환경변수 정보, 포트와 depends on을 적어주면 된다.

backend:
    build: ./backend
    #build:
    # context: ./backend
    # dockerfile: Dockerfile
    ports:
      - "80:80"
    volumes:
      - logs:/app/logs
      - ./backend:/app
      - /app.node_modules
    env_file:
      - ./env/backend.env
    depends_on:
      - mongodb

와 같이 적어주면 되는데, 다른 것은 특별할 게 없고 depends on은 도커 컴포즈에만 있는 옵션인데, 도커 컴포즈는 동시에 여러 컨테이너를 만들게 되는데 이 중 어떤 컨테이너는 이미 실행중인 특정 컨테이너에 의존할 수 있기 떄문에(여기서는 백엔드가 MongoDB에 의존하는) 적어주는 부분이다. 그러면 컨테이너 생성 순서에서 몽고DB를 우선으로, 이후에 백엔드 컨테이너를 만들어주게 된다.

8 views

More from this blog

락프리 데이터 구조와 알고리즘

여기서는 락프리 데이터 구조를 설명한다. 락프리(lock-free) 란 배타락을 이용하지 않고 처리를 수행하는 데이터 구조 및 그에 대한 조작 알고리즘을 총칭한다. 왜 락프리인가? 전통적인 동시성 제어 방법인 뮤텍스나 세마포어는 여러 문제점을 가지고 있다: 성능 저하: 락 경합(lock contention)으로 인한 대기 시간 데드락: 여러 스레드가 서로의 락을 기다리는 상황 우선순위 역전: 낮은 우선순위 스레드가 높은 우선순위 스레드를 ...

Jul 27, 20257 min read126

소프트웨어 트랜잭셔널 메모리

소프트웨어 트랜잭셔널 메모리 동시성 프로그래밍에서 공유 자원에 대한 안전한 접근은 항상 중요한 과제다. 전통적으로 뮤텍스 락과 같은 비관적 락(Negative Lock) 방식을 사용해왔다. 이 방식은 크리티컬 섹션에 진입하기 전에 반드시 락을 획득해야 하며, 락을 얻지 못하면 코드 실행 자체가 블록된다. 하지만 이와는 다른 접근 방식이 있다. 바로 낙관적 락(Optimistic Lock) 방식인데, 이는 "일단 실행하고 나중에 검증하자"는 철학...

Jul 20, 202517 min read263

공평한 배타 제어

공평한 배타 제어 여기서는 공평한 배타 제어에 대해 설명한다. 먼저 컨텐션(contention) 이라는 개념을 이해할 필요가 있다. 컨텐션이란 여러 스레드가 동시에 같은 락을 획득하려고 경쟁하는 상황을 말한다. 컨텐션이 높을수록 스레드들이 락을 기다리는 시간이 길어지고 성능이 저하된다. 이러한 컨텐션 상황은 시스템 아키텍처에 따라 더욱 복잡해질 수 있다. 특히 비균일 메모리 접근(Non-Uniform Memory Access, NUMA) 와 같...

Jul 13, 20259 min read21

KernelSnitch[논문 리뷰]

Paper 1. Intro 이 글은 NDSS 2025에서 발표된 KernelSnitch 논문을 소개이다. 이 연구는 커널의 평범한 데이터 구조체들이 가진 본질적인 특성이 어떻게 심각한 보안 취약점이 되는지를 보여준다. 핵심은 이러하다: "데이터 구조체의 크기에 따른 접근 시간 차이를 이용해 커널의 비밀 정보를 유출할 수 있다" 여기서는 커널 힙 포인터 유출에 집중해서 설명한다. 이 공격이 성공하면 KASLR을 우회하고 더 심각한 커널 익스플로...

Jul 11, 20257 min read131

멀티태스크와 액터 모델

멀티태스크 협조적/비협조적 멀티태스크 선점: 프로세스와의 협조 없이 수행하는 컨택스트 스위칭이라고는 하나, 결국 뺏어오는 게 가능하냐의 문제다. 협조적 멀티태스크(비선점형, cooperative): 각각의 프로세스가 자발적으로 컨택스트 스위칭을 수행하는 멀티태스크 방식. 장점: 멀티태스크 매커니즘을 구현하기 쉽다. 단점: 프로세스가 자발적으로 컨텍스트 스위칭을 해야하는데, 만약 버그가 발생하여 프로세스가 무한 루프에 빠지거나 정지하게 되면 그 ...

Jul 6, 20252 min read25
M

MaxLog

35 posts