1. Docker Compose란?

Docker Compose is a tool for defining and running multi-container applications. It is the key to unlocking a streamlined and efficient development and deployment experience.
Docker Compose는 '다중 컨테이너 애플리케이션'을 정의하고 실행하는 도구입니다. 간소화되고 효율적인 개발 및 배포 환경의 핵심적입니다.
YAML 파일을 작성하여 서비스, 네트워크 및 볼륨을 쉽게 설정하고 관리할 수 있습니다. production, staging, development, test, CI workflow 등 모든 환경에 대한 작업을 수행합니다. 또한, 애플리케이션의 라이프사이클을 관리하기 위한 명령어도 포함되어 있습니다.
과거에는 Docker Compose가 독립적인 CLI 도구였지만, 현재는 Docker의 공식 플러그인 형태로 통합된 것으로 알고 있습니다. 명령어에서도 차이가 있는데, docker-compose가 예전 버전, docker compose는 현재 공식 플러그인 버전입니다.
- 서비스 시작, 중지, rebuild
- 실행 중인 서비스 상태 확인
- 실행 중인 서비스의 로그 출력 스트리밍
- 일회성 명령 실행
(1) Compose의 주요 이점
- 간편한 제어
- 하나의 YAML 파일을 통해 다중 컨테이너 정의 및 관리
- 다양한 서비스를 조정하는 작업 간소화
- 효율적인 협업
- 구성 파일을 공유하기 쉽다! → 협업 용이
- 빠른 개발
- 컨테이너 생성에 대한 캐시를 관리
- 변경되지 않은 서비스 재시작 시 기존 컨테이너 재사용
- 이식성
- Compose 파일(.yaml)에서 변수 사용 가능
- 변수 사용을 통해 다양한 환경/사용자에 맞게 커스터마이징 가능
- 광범위한 커뮤니티
- 활발한 커뮤니티! 풍부한 리소스! 튜토리얼!
- 지속적인 개선!
(2) Compose의 일반적인 사용 사례
ⓐ 개발 환경
- 애플리케이션이 개발되고 실행될 격리된 환경 구성에 적합
- 애플리케이션의 모든 서비스(데이터베이스, 캐시, 웹 서비스 API 등) 간 종속성 문서화 효과까지! (.yaml 파일)
ⓑ 자동화 된 테스트 환경
- 격리된 테스트 환경 구성에 적합
- CD/CI
- 자동화 된 end-to-end 테스트에 적합한 환경이 필요한데..
- Compose를 이용하면 이런 환경을 생성하고 파괴하기에도 편하다!!
2. Docker Compose 설치
저는 AWS EC2의 Ubuntu 인스턴스에서 진행하였습니다!
docker가 이미 설치된 상황에서, 해당 docker 버전에 맞는 docker compose를 설치하기 위해 다음 과정을 진행했습니다
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.35.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
# curl -SL https://github.com/docker/compose/releases/download/{버전}/docker-compose-linux-{아키텍처} -o $DOCKER_CONFIG/cli-plugins/docker-compose
$HOME 디렉터리에 사용자를 위한 Docker Compose의 최신 릴리즈를 다운로드하게 됩니다.
(저 할 때만 해도 v2.35.1이 최신 릴리즈였는데, 그 새 버전이 올랐더군요)
시스템 내 모든 사용자가 사용할 수 있도록 설치하고 싶다면, 설치 위치를 ~/.docker/cli-plugins 대신 /usr/local/lib/docker/cli-plugins으로 설정하면 됩니다.
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
다운로드 한 파일에 실행 권한이 없을 수도 있습니다.
chmod로 실행 권한을 수정해줍니다.
(또는, docker compose 설치 시 '모든 사용자를 위해' 설치했다면, 이 과정이 필요하지 않을 수 있습니다.)
docker compose version
버전이 정상적으로 출력되면 설치에 성공한 것입니다.
3. 사용 방법, 명령어
기본적으로, docker-compose.yml 파일을 먼저 작성해야 합니다. (작성 요령은 다음 section에서 다룰게요)
이 구성 파일에 서비스 정의 내용을 작성하고, 이 내용을 토대로 한 번의 명령어로 전체 애플리케이션을 실행하는 것입니다.
명령어 | 설명 |
docker compose up | 컨테이너 생성 및 실행 |
docker compose up -d | -d: 백그라운드에서 실행 (detached mode) |
docker compose down | 모든 컨테이너, 네트워크, 볼륨 정리 |
그리고 저는 수많은 시행착오를 거치면서.. build를 너무 많이 했더니, 쓸데없이 용량을 차지하는 것들이 많이 생겼더군요. ㅠㅠ
그래서 새로 빌드를 할 때마다, 아래 명령어로 사용하지 않는 Docker 리소스를 모두 정리한 뒤, 다시 빌드하고.. 용량을 관리하면서 진행했습니다.
docker system prune -a
(사용하지 않는 이미지, 컨테이너, 네트워크, 캐시 모두 정리)
4. 주요 문법
version: '3.8' # YAML 파일 버전
services:
서비스이름:
image: 이미지명[:태그] 또는 build: 디렉토리
container_name: 컨테이너명
ports:
- "호스트포트:컨테이너포트"
volumes:
- "호스트경로:컨테이너경로"
environment:
- 변수명=값
depends_on:
- 다른서비스명
networks:
- 네트워크이름
문법 | 설명 | 예시 |
version | YAML 파일 버전 지정 | |
services | 실행할 컨테이너들 (여러 개 가능) | |
image | 사용할 이미지 있을 시 작성 | nginx, python:3.11-slim |
build | 빌드할 Dockerfile 위치(디렉토리) | . (현재 디렉토리에 Dockerfile이 있다) |
ports | 포트 포워딩 | "80:80" |
volumes | 볼륨 마운트 | ./nginx/default.conf:/etc/nginx/conf.d/default.conf |
environment | 환경 변수 | |
depends_on | 의존성 | |
networks | 사용자 정의 네트워크 |
5. 사용 예시
다음은 제가 프로젝트에 적용하기 위해 작성한 내용입니다.
뭐든 경험을 기반으로 공부해야 나중에도 잘 기억할 수 있는 것 같습니다!!
상황 설명:
Django 프로젝트를 배포할건데, nginx 프록시 서버와 gunicorn을 이용해 배포하고 싶어요.
- 두 개의 컨테이너(Django web, nginx)가 하나의 볼륨을 공유
- nginx가 웹 서버를 프록시
(1) 프로젝트 디렉토리 구조
프로젝트 디렉토리 구조
(Djangro 프로젝트 입니다.)
(예시에 등장하는 파일/디렉토리 외에는 모자이크)
(2) docker-compose.yml
docker-compose.yml
version: '3.8' services: web: build: . container_name: liquest-back-web volumes: - static_volume:/app/static expose: - "8000" nginx: image: nginx:stable container_name: nginx-proxy ports: - "80:80" volumes: - static_volume:/app/static - ./nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - web volumes: static_volume:
- (web, nginx) volumes: 이름이 static_volume인 Docker 볼륨 정의
- (nginx) volumes: 커스텀 nginx 설정 파일(./nginx/default.conf)를 컨테이너의 nginx 설정 경로에 덮어씌움
- (nginx) expose: 내부 포트 8000을 다른 컨테이너에 노출 (즉, docker compose의 내부 서비스 간 통신)
- (nginx) ports: 호스트의 80번 포트를 컨테이너의 80번 포트에 매핑 (즉, 외부 접속자는 localhost:80으로 접근 가능)
- (nginx) depends_on: web 서비스가 먼저 시작되도록 의존성 지정
(3) Dockerfile
Dockerfile
FROM python:3.11-slim WORKDIR /app COPY . /app RUN apt-get update && \ apt-get install -y git python3-dev python3-venv \ gcc libgomp1 libgl1-mesa-glx libglib2.0-0 pkg-config libcairo2-dev libgirepository1.0-dev default-jdk nginx vim && \ rm -rf /var/lib/apt/lists/* RUN pip install --upgrade pip && \ pip install -r requirements.txt && \ pip install gunicorn && \ pip install torch --index-url https://download.pytorch.org/whl/cpu CMD ["gunicorn", "mysite.wsgi:application", "--bind", "0.0.0.0:8000"]
- CMD ["gunicorn", "mysite.wsgi:application", "--bind", "0.0.0.0:8000"]
- 제 프로젝트의 경우 wsgi.py가 /mysite에 위치
- (python manage.py runserver는 개발용이고, 저는 운영용으로 배포하고 싶은 것이므로 gunicorn을 사용했습니다.)
(4) nginx/default.conf
nginx/default.conf
server { listen 80; location /static/ { alias /app/static/; } location / { proxy_pass http://web:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
- listen 80: Nginx가 80번 포트에서 요청 수신
- (docker-compose.yml에서 이 포트를 매핑시켰었죠?)
- /static/: '/static/'으로 시작하는 요청을 '/app/static/' 경로에 있는 정적 파일로 매핑
- (docker-compose.yml에서 설정한 static_volume과 연관되어 있어요)
- (ex: 브라우저 요청 /static/blabla.js → /app/static/blabla.js 파일로 반환)
- location /
- proxy_pass: '/static/'을 제외한 모든 요청은 web 서비스의 8000번 포트로 전달
- (web은 docker-compose.yml에서 설정한 Compose service 이름!!)
- proxy_set_header: 원래 요청의 호스트명을 유지하고(Host $host;), 웹 앱이 요청자의 IP 등 정확한 정보를 받을 수 있게 설정(X-Real-IP $remote_addr; X-Forwarded-For $proxy_add_x_forwarded_for;)
- proxy_pass: '/static/'을 제외한 모든 요청은 web 서비스의 8000번 포트로 전달
사실 nginx 파일 설정 내용은 아직 모르는 게 참 많습니다.. 계속계속 공부할 내용이 나옵니다..
일단은, docker로 관리하던 Django 프로젝트에
nginx와 gunicorn을 이용한 배포에도 Docker로 관리를 하고 싶어서 시도한 내용이었는데, 성공적이었습니다!!
📖 레퍼런스
1. Docker Compose https://docs.docker.com/compose/
2. Why Use Compose? https://docs.docker.com/compose/intro/features-uses/
3. Install using the repository https://docs.docker.com/compose/install/linux/#install-using-the-repository
4. YAML Lint (YAML 문법 오류 점검 사이트) https://www.yamllint.com/
'개발 > Back-End' 카테고리의 다른 글
[Express.js] 기초 이해하기 (4) | 2025.01.25 |
---|