본문 바로가기
Docker

도커 컴포즈와 간단한 컴포즈 문법

by 진꿈청 2024. 3. 3.

docker-compose를 사용하는 이유는?

도커 명령어를 파일로 관리하기에 복잡한 도커 컨테이너 및 도커 네트워크를 구성하기에 용이하여 사용한다.

첫 번째로 도커보다 간결하다.

기존의 도커는 간단한 html을 만들고 nginx로 연결하려면 아래와 같은 도커 명령어를 입력해야 한다.
아래 도커 명령어는 도커 컴포즈로 좀 더 단순하게 표현이 가능하다.(뒤에서 알아봄)

docker run -it -p 8080:80 --rm -v $(pwd):/usr/share/nginx/html/ nginx

 

--rm 옵션은 종료시 컨테이너를 삭제하기 위해 준 것이다.

 

두 번째로 컨테이너 간 연결이 쉬워진다.

 

아래는 postgresql과 django-sample이란 컨테이너를 연결하는 예이다.


--link 옵션을 주어 django-sample 컨테이너에게 db라는 이름으로 postgresql 컨테이너의 존재를 알린 것이다.

{연결할 컨테이너 이름}:{해당 컨테이너에서 참고할 이름}

 

docker run --rm -d --name postgres \
  -e POSTGRES_DB=djangosample \
  -e POSTGRES_USER=sampleuser \
  -e POSTGRES_PASSWORD=samplesecret \
  postgres

docker run -d --rm \
  -p 8000:8000 \
  -e DJANGO_DB_HOST=db \
  --link postgres:db \
  django-sample


이또한, 도커 컴포즈를 활용하면 좀 더 단순화 가능하다.

 

 

세 번째로 특정 컨테이너끼리만 통신할 수 있는 가상 네트워크 환경을 관리하는데 명령어가 길어진다.

 

--network 옵션을 통해서 특정 네트워크 내에만 존재하는 컨테이너끼리만 통신할 수 있도록 했다.
django2의 경우 해당 네트워크 내에 존재하지 않기 때문에 --link로 연결해도 통신할 수 없다.

# 네트워크 생성
docker network create --driver bridge web-service

# 해당 network를 활용하여 컨테이너 실행
docker run --rm -d --name postgres \
  --network web-service \
  -e POSTGRES_DB=djangosample \
  -e POSTGRES_USER=sampleuser \
  -e POSTGRES_PASSWORD=samplesecret \
  postgres

docker run -d --rm --name django1 \
  --network web-service \
  -p 8000:8000 \
  -e DJANGO_DB_HOST=db \
  --link postgres:db \
  django-sample

docker run -d --rm --name django2 \
  -p 8001:8000 \
  -e DJANGO_DB_HOST=db \
  --link postgres:db \
  django-sample

이는 너무 verbose하다.

도커 네트워크 참고 블로그
https://captcha.tistory.com/70

 

06. 도커 네트워크 (Docker Network)

도커 네트워크 구조 - 도커는 컨테이너에 내부 IP를 순차적으로 할당 - 내부 IP는 컨테이너를 재시작할 때마다 변경될 수 있음 - 내부 IP는 도커가 설치된 호스트, 즉 내부망에서만 쓸 수 있는 IP이

captcha.tistory.com

 

그렇다면 docker-compose에서는?

docker-compose를 구성하기 위한 yml 파일 생성.

 

앞서 구성한 도커 구성을 아래와 같이 파일 형태로 작성하여 사용가능.

version: '3'

volumes:
  postgres_data: {}

services:
  db:
    image: postgres
    volumes:
      - postgres_data:/var/lib/postgres/data
    environment:
      - POSTGRES_DB=djangosample
      - POSTGRES_USER=sampleuser
      - POSTGRES_PASSWORD=samplesecret

  django:
    build:
      context: .
      dockerfile: ./compose/django/Dockerfile-dev
    volumes:
      - ./:/app/
    command: ["./manage.py", "runserver", "0:8000"]
    environment:
     - DJANGO_DB_HOST=db
    depends_on:
      - db
    restart: always
    ports:
      - 8000:8000

훨씬 더 간단하다.

실행 방법

작성한 docker-compose.yml이 있는 곳에 가서 docker-compose up 명령어 입력.
백그라운드에서 실행하기 위해 -d 옵션도 지정.

docker-compose up -d

 

실행 중인 컨테이너를 내리고 싶다면 down 명령어를 사용하면 된다.

docker-compose down

 

그렇다면 docker-compose 명령어에는 이것 이외에 어떤 것들이 있을까?

 

docker-compose 명령어

docker-compose up -d // 도커 백그라운드 실행
docker-compose up --force-recreate // 도커 컨테이너 새로 만들기
docker-compose up --build // 도커 이미지 빌드 후 compose up

docker-compose up에서 --build 플래그 여부의 차이는,
--build가 붙으면 캐싱된 이미지를 체크하지 않고 무조건 빌드를 하고 시작하라는 의미이다.


붙이지 않고 써도 이미지에 없으면 빌드부터 하긴 하지만, 소스 수정이 이루어졌을 때는 다시 이미지를 빌드해야 한다.
따라서, 가급적 --build를 붙여서 compose-up을 하는게 좋다.

 

-d (detached) 모드를 붙이면 백그라운드에서 실행되므로 당연히 앱 내의 로그 및 출력이 터미널에 나오지 않는다.

 

 

기타 명령어

docker-compose start // 정지한 컨테이너를 재개
docker-compose start mysql // mysql 컨테이너만 재개

docker-compose restart // 이미 실행 중인 컨테이너 다시 시작
docker-compose restart redis // 이미 실행중인 redis 재시작

docker-compose stop // gracefully stop함.
docker-compose stop wordpress

docker-compose down // stop 뿐만 아니라 컨테이너 삭제까지

docker-compose logs
docker-compose logs -f // 로그 watching

docker-compose ps // 컨테이너 목록

docker-compose exec [컨테이너] [명령어]
docker-compose exec wordpress bash // wordpress에서 bash 명령어 실행

docker-compose build // build 부분에 정의된 대로 빌드
docker-compose build wordpress // wordpess 컨테이너만 빌드

docker-compose run [service] [command] // 이미 docker-compose 가동 중인 것과 별개로 하나 더 올릴 때
docker-compose run nginx bash

docker-compose.yml 문법

-version

docker-compose.yml 파일의 명세 버전.
버전에 따라 도커 엔진 버전도 다르다.

아래 참고
https://docs.docker.com/compose/compose-file/

-services

컨테이너에 사용할 이미지 이름과 태그(버전) 태그 생략시 최신 버전 설치.
이미지가 없다면 자동으로 pull.

또한, ports는 일반 도커를 구성할 때와 마찬가지로 호스트 포트로 접근해야 내용을 볼 수 있다.

services:
  django:
    image: ...
    ports:
      - "8000:80" // 호스트 포트:컨테이너 포트
  postgres:
      image: ....

 

restart

재시작 정책으로 도커 컨테이너가 실행되는 순간 접근하여 접근 시간에 따른 실패를 방지한다.
또한, 자동으로 재시작하게끔 해주기도 한다. 이래저래 유용하다고 한다.

services:
  django:
    image: ...
    restart: always // "no", always, on-failure, unless-stopped
  postgres:
      image: ....

 

build
이미지 자체를 빌드 후 사용할 경우 build를 사용한다. 이미지 빌드를 위한 도커파일이 필요하고 지정해주어야 한다.
자체 빌드기 때문에 image 속성 대신 사용한다.

docker-compose build를 통해서 빌드한 후 docker-compose up 해주면 된다.

services:
  django:
    build:
      context: .
      dockerfile: ./compose/django/Dockerfile-dev 
  postgres:
      image: ....

 

environment

사용하고자 하는 이미지의 환경 변수를 지정할 때 사용한다.

도커 파일과 도커 컴포즈의 환경 변수 우선순위는 다음과 같다.

  1. docker-compose run/exec -e key:value
  2. docker-compose.yml의 environment
  3. Dockerfile의 ENV
services:
  db:
    image: mysql:5.7 // 사용할 이미지
    volumes:
      - ./mysql:/var/lib/mysql // 볼륨(컨테이너가 죽어도 데이터를 유지)
    restart: always // 컨테이너가 죽지 않고 계속
    environment: // 환경변수
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

 

volumes

services:
  nginx:
    image: nginx
    ports:
      - 8080:80
    volumes:
      - ./:/usr/share/nginx/html
    link:
      - mysql:db

 

depends_on

의존성을 명시한다. 예를 들어 아래와 같은 yml에서는 nginx는 mysql에 의존하고 있으므로 mysql 이미지가 실행된 후 nginx 이미지가 실행된다.

services:
  mysql:
    image: mysql
    ...
  nginx:
    image: nginx
    ports:
      - 8080:80
    depends_on:
      - mysql

다양한 docker-compose.yml 작성 예시들

1. 간단히 Nginx 올리기

version: '3'

services:
  nginx:
    image: nginx
    ports:
      - 8080:80
    volumes:
      - ./:/usr/share/nginx/html

2. 워드프레스

db를 먼저 실행하기 위해 depends_on을 wordpress에 세팅

version: '3'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpwd
      MYSQL_DATABASE: databasename
      MYSQL_USER: user
      MYSQL_PASSWORD: userpwd

  wordpress:
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wp
      WORDPRESS_DB_PASSWORD: wp
      WORDPRESS_DB_NAME: wp
    depends_on:
      - db

volumes:
  db_data: {}

3. SpringBoot + redis

version: '3'

services:
  redis:
    image: redis
    ports:
      - 6379:6379
    restart: always

  springboot:
    image: whateveryouwant
    ports:
      - 8080:8080
    depends_on:
      - redis
    restart: always

 

확실하게 도커 명령어를 사용하는 것보다 도커 컴포즈 사용시 간략하고 이해하기도 쉽다는 것을 확인할 수 있다.

좋은 도커 이미지를 만들 때 설명했던 화이트 박스처럼 도커 컴포즈를 활용하면,

어떤 도커 컨테이너가 필요하며 어떻게 구성되어있는지 그리고 수정까지 가능하다.

'Docker' 카테고리의 다른 글

Dockerfile은 무엇일까?  (0) 2024.03.02
도커 명령어 모음  (0) 2024.03.02
도커 엔진을 구성하는 도커 이미지와 도커 컨테이너  (0) 2024.03.02
도커가 배포할 때 필요한 이유  (0) 2024.03.01
Docker란?  (0) 2024.01.27