Cloud Wave

[Cloud Wave] docker-compose

ankisile 2023. 7. 16. 17:41

목차

 

docker-compose

docker-compose란?

• 다중 컨테이너 Docker 응용 프로그램을 정의하고 실행하기 위한 도구(multi container)
• Compose(합성)를 사용하면 YAML 파일을 사용하여 응용프로그램의 서비스 설정가능
• 명령 하나로 configuration으로 부터 모든 서비스를 생성하고 시작할 수 있음
• 프로덕션, 스테이징, 개발, 테스트, CI 워크플로우 등 모든 환경에서 작업 작성

 

docker-compose 설치

docker-compose 는 rpm 패키지 형태로 제공하지 않으므로 직접 다운로드해서 사용해야 한다.

# curl -L \
"https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# ls /usr/local/bin/
# chmod +x /usr/local/bin/docker-compose 
# cp /usr/local/bin/docker-compose /usr/bin/
# docker-compose version

    cf) podman의 경우 패키지로 설치가능함

     

    docker-compose 문법

     

    예시와 함께 문법을 알아가보자

    version: '3'
    services:
     db:
      image: postgres
     volumes:
     - ./docker/data:/var/lib/postgresql/data
     environment:
     - POSTGRES_DB=sampledb
     - POSTGRES_USER=sampleuser
     - POSTGRES_PASSWORD=samplesecret
     - POSTGRES_INITDB_ARGS=--encoding=UTF-8
     django:
      build:
       context: .
       dockerfile: ./Dockerfile
      environment:
      - DJANGO_DEBUG=True
      - DJANGO_DB_HOST=db
      - DJANGO_DB_PORT=5432
      - DJANGO_DB_NAME=sampledb
      - DJANGO_DB_USERNAME=sampleuser
      - DJANGO_DB_PASSWORD=samplesecret
      - DJANGO_SECRET_KEY=dev_secret_key
      ports:
      - "8000:8000"
      command: 
      - python manage.py runserver 0:8000
      volumes:
      - ./:/app/

    version

    version: '3'

    docker-compose.yml 파일의 첫 줄은 파일 규격 버전을 정의한다. 파일의 규격에 따라 지원하는 옵션이 달라지는데, “3”이라 적으면 3 으로 시작하는 최신 버전을 사용한다는 의미이다.

    services

    services:

    이 항목 밑에 실행하려는 컨테이너들을 정의한다. Compose 에서는 컨테이너 대신 서비스라는 개념을 사용한다.

    db

    services:
     db:

    postgres 서비스의 이름을 db 로 정의한다.

    image

    services:
     db:
      image: postgres

    db 서비스에서 사용할 도커 이미지를 정의한다. 여기서는 dockerhub 의 공식 postgres 이미지를 사용한다.

    volumes

    services:
     db:
      volumes:
      - ./docker/data:/var/lib/postgresql/data

    docker run 으로 db 컨테이너를 실행할 때 --volume 옵션을 사용하여 데이터베이스의 데이터를 로컬 컴퓨터에 저장했던 부분과 동일하다. 다만 docker-compose.yml 의 volumes 에는 상대 경로를 지정할 수 있어서 편리하다. 위에선 docker run 으로 db 컨테이너 실행할 때와 마찬가지로, 프로젝트 루트 아래의 docker/data 디렉터리에 데이터를 저장한다.

    environment

    services:
     db:
      environment:
      - POSTGRES_DB=sampledb
      - POSTGRES_USER=sampleuser
      - POSTGRES_PASSWORD=samplesecret
      - POSTGRES_INITDB_ARGS=--encoding=UTF-8

    docker run 명령어의 -e 옵션에 적었던 변수들이다. 마지막의 POSTGRES_INITDB_ARGS 부분이 추가되었는데, 데이터베이스 서버의 인코딩을 UTF-8 로 설정하기 위해서이다.

    django

    services:
     django:

    앱 서비스의 이름은 django 로 정의한다.

    build

    services:
     django:
      build:
       context: .
       dockerfile: ./Dockerfile

    db 서비스와 달리 앱 서비스는 특정 이미지 대신 build 옵션을 추가한다. context 는 docker build 명령을 실행할 디렉터리 경로가 아니다. dockerfile 에는 ‘개발용’ 도커 이미지를 빌드하는 데 사용할 Dockerfile 을 지정하면 된다. Dockerfile 파일에서는 (운영용 Dockerfile 과는 달리) 소스코드를 컨테이너에 넣지 않는다.

    environment

    services:
     django:
      environment:
       - DJANGO_DEBUG=True
       - DJANGO_DB_HOST=db
       - DJANGO_DB_PORT=5432
       - DJANGO_DB_NAME=sampledb
       - DJANGO_DB_USERNAME=sampleuser
       - DJANGO_DB_PASSWORD=samplesecret

    환경 변수는 docker run 을 할 때보다 좀 더 자세하게 기록한다. 각 값은 앱 서비스의 환경 변수로 설정되며, Django 설정 파일(djangosample/settings.py)에서 불러와 사용한다. (데이터베이스 관련 정보들은 db 서비스에서 설정한 값들과 일치해야 한다.

    ports

    services:
     django:
      ports:
       - "8000:8000"

     

    docker run 명령어의 -p 옵션에 해당하는 부분이다.

    command

    services:
     django:
      command:
       - python manage.py runserver 0:8000

     

    docker run 으로 애플리케이션 컨테이너를 실행할 때 가장 마지막에 실행될 명령어 부분이다.

    volumes

    services:
     django:
      volumes:
       - ./:/app/

    docker run 으로 애플리케이션 컨테이너를 실행할 때 -v 옵션을 사용하여 프로젝트 루트 디렉터리를 컨테이너 내부의 /app 디렉터리와 연결했던 부분과 동일하다.

     

    docker-compose commands

     

    예제: Docker-compose 사용해서 Jenkins 컨테이너 생성하기

    Jenkins

    # mkdir jenkins ; cd jenkins
    # mkdir /jenkinsdata/
    # vim docker-compose.yml

    • volumes 부분의 /var/run/docker.sock:/var/run/docker.sock
      • Jenkins 이미지를 불러온 후 컨테이너 내부에서 Jenkins 의 command 에 포함될 docker 명령을 위해서 docker 를 설치한다
      • => 즉, docker 명령어를 Jenkins 안에서 사용해야 된다
      • => 따라서, 소켓을 바인딩 해서 포테이너 때 처럼 젠킨스 내에서 docker 명령어를 사용할 수 있음. docker daemon은 socket에 있기 때문에