Skip to content

Docker Compose

Compose는 다중 컨테이너 Docker 애플리케이션을 정의하고 실행하기위한 도구입니다. Compose에서는 YAML 파일을 사용하여 애플리케이션의 서비스를 구성합니다. 그런 다음 단일 명령으로 구성에서 모든 서비스를 만들고 시작합니다.

Categories

  • docker rollout - Docker Compose용 Zero Downtime Deployment 도구
  • Preevy - 프리뷰 환경을 빠르게 배포해주는 CLI 도구

Examples

실행 방법

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
  3. Run docker compose up and the Docker compose command starts and runs your entire app. You can alternatively run docker-compose up using the docker-compose binary.

A docker-compose.yml looks like this:

version: "3.9"  # optional since v1.27.0
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

For more information about the Compose file, see the Compose file reference.

Compose has commands for managing the whole lifecycle of your application:

  • Start, stop, and rebuild services
  • View the status of running services
  • Stream the log output of running services
  • Run a one-off command on a service

How to install

On Linux, you can download the Docker Compose binary from the Compose repository release page on GitHub. Follow the instructions from the link, which involve running the curl command in your terminal to download the binaries. These step-by-step instructions are also included below.

WARNING

For alpine, the following dependency packages are needed: py-pip, python-dev, libffi-dev, openssl-dev, gcc, libc-dev, and make.

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.26.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

Healthcheck

다음과 같이 하면 된다:

healthcheck:
  test: ["CMD-SHELL", "pg_isready -U postgres"]
  interval: 10s
  timeout: 5s
  retries: 5

종속성 확인은 다음과 같다.

depends_on:
  postgres-database:
    condition: service_healthy

curl Example:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080"]
  interval: 1m30s
  timeout: 10s
  retries: 3
  start_period: 40s

wget 사용 방법:

healthcheck:
   test: wget --no-verbose --tries=1 --spider http://localhost || exit 1
   interval: 5m
   timeout: 3s
   retries: 3
   start_period: 2m

Python의 urllib을 사용한 방법:

healthcheck:
   test: python -c "import urllib.request as r; exit(0 if r.urlopen('http://www.python.org/').status == 201 else 1)"
   interval: 5m
   timeout: 3s
   retries: 3
   start_period: 2m

스케일 방법

scale 명령을 사용하여 서비스의 복제본 수를 조정할 수 있습니다.

docker-compose up -d --scale service_name=N

와 같이 사용하여 특정 서비스의 복제본 수를 조정할 수 있습니다.

환경변수

.env파일이 있으면 된다.

환경변수 없을 때 오류 송출은 ${USER_VAR:?err} 와 같이 하면 된다.

Compose file 에서 빌드하는 방법

services:
  foo:
    build:
      context: ./dir
      dockerfile: backend.Dockerfile

다른 Compose file 참조하여 확장하는 방법

compose.yaml 파일이 다음과 같다면:

services:
  web:
    extends:
      file: common-services.yml
      service: webapp

위에서 참조하는 compose-services.yaml 파일은 다음과 같다:

services:
  webapp:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - "/data"

위의 경우 compose-services.yaml 파일의 webapp 안의 모든 내용을 compose.yaml 파일의 web 이 모든 설정을 받아온다.

더 나아가 compose.yaml 에서 로컬로 구성을 정의하거나 재정의할 수 있다:

services:
  web:
    extends:
      file: common-services.yml
      service: webapp
    environment:
      - DEBUG=1
    cpu_shares: 5

  important_web:
    extends: web
    cpu_shares: 10

사용자 지정 방법

  my-service:
    image: ubuntu:latest
    user: ${MY_UID}:${MY_GID}
    volumes:
      - /etc/passwd:/etc/passwd:ro
      - /etc/group:/etc/group:ro

실행시:

MY_UID="$(id -u)" MY_GID="$(id -g)" docker-compose up

재시작 방법

api-server:
    container_name: api-server
    build:
        context: api-server
        dockerfile: Dockerfile
    image: product-server:latest
    networks:
        - web-network
    restart: on-failure:5
  • no: 컨테이너가 자동으로 다시 시작되지 않음
  • on-failure[:max-retries]: 0이 아닌 종료 코드로 종료되는 경우 컨테이너를 다시 시작하고 Docker 데몬이 컨테이너를 다시 시작할 수 있는 최대 시도 횟수를 진행함
  • always: 컨테이너가 중지되면 항상 다시 시작
  • unless-stopped: 컨테이너가 임의로 또는 Docker 데몬에 의해 중지되지 않는 한 항상 컨테이너를 다시 시작

재시작 정책

version: "3.8"
services:
  redis:
    image: redis:alpine
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
  • delay: 재시작 시도 사이의 지속 시간
  • max_attempts: 다시 시작 기간 이외의 최대 시도 횟수
  • window: 재시작이 성공했는지 확인하는 기간

로그파일 드라이버

version: "3.8"
services:
  some-service:
    image: some-service
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"

Enabling GPU access with Compose

Run a sample CUDA container:

sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

위와 같은 명령을 docker-compose.yml 파일에 저장하고 싶다면:

capabilities
This value specifies as a list of strings (eg. capabilities: [gpu]). You must set this field in the Compose file. Otherwise, it returns an error on service deployment.
count
This value, specified as an integer or the value all, represents the number of GPU devices that should be reserved (providing the host holds that number of GPUs). If count is set to all or not specified, all GPUs available on the host are used by default.
device_ids
This value, specified as a list of strings, represents GPU device IDs from the host. You can find the device ID in the output of nvidia-smi on the host. If no device_ids are set, all GPUs available on the host are used by default.
driver
This value is specified as a string, for example driver: 'nvidia'
options
Key-value pairs representing driver specific options.

Example of a Compose file for running a service with access to 1 GPU device:

services:
  test:
    image: nvidia/cuda:12.3.1-base-ubuntu20.04
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

To enable access only to GPU-0 and GPU-3 devices:

services:
  test:
    image: tensorflow/tensorflow:latest-gpu
    command: python -c "import tensorflow as tf;tf.test.gpu_device_name()"
    deploy:
      resources:
        reservations:
          devices:
          - driver: nvidia
            device_ids: ['0', '3']
            capabilities: [gpu]

Legacy

참고로 runtime 속성을 사용하는 방법은 Compose v2.3 format 에서 사용하는 오래된 방법이다.

services:
  test:
    image: nvidia/cuda:10.2-base
    command: nvidia-smi
    runtime: nvidia

Troubleshooting

YAML invalid type

ERROR: The Compose file './docker-compose.yaml' is invalid because:
services.db.environment contains {"POSTGRES_USER": "user"}, which is an invalid type, it should be a string

주로 environment같은 변수를 수정할 때 실수할 수 있는데, 시퀀스키-벨류를 잘 구분해야 한다.

services:
  db:
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: 0000

위 내용은 키-벨류 이다.

services:
  db:
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=0000

위 내용은 시퀀스 이다. 같다(=) 문자를 사용했음에 주의하자.

depends_on status check

depends_on에서 종속성 확인은 해당 이미지의 활성상태를 확인하지 않는다. 별도의 스크립트로 통신 스크립트를 만들어야 한다.

See also

Favorite site

Documentation

Guide

Article