작성중
📂 목차
📚 본문
Docker Compose
Docker Compose는 여러 개의 컨테이너로 구성된 애플리케이션을 정의하고 실행하기 위한 도구이다.
핵심 특징
- YAML 파일 기반:
docker-compose.yml파일 하나로 전체 애플리케이션 스택을 정의 - 선언적 방식: “어떻게” 실행할지가 아닌 “무엇을” 실행할지 정의
- 단일 명령어:
docker-compose up하나로 모든 서비스 실행 - 환경 일관성: 개발/테스트/프로덕션 환경 간 일관된 구성 유지
웹 애플리케이션(프론트엔드 + 백엔드 + DB + Redis)을 배포한다고 가정해보자.
docker run 만 사용할 경우:
docker network create app-networkmysql 서버
docker run -d \
--name mysql \
--network app-network \
-e MYSQL_ROOT_PASSWORD=root123 \
-e MYSQL_DATABASE=myapp \
-v mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.0Redis 서버
docker run -d \
--name redis \
--network app-network \
-v redis-data:/data \
-p 6379:6379 \
redis:7-alpine백서버
docker run -d \
--name backend \
--network app-network \
-e DB_HOST=mysql \
-e DB_PASSWORD=root123 \
-e REDIS_HOST=redis \
-p 8080:8080 \
myapp-backend:latest프론트서버
docker run -d \
--name frontend \
--network app-network \
-e BACKEND_URL=http://backend:8080 \
-p 3000:3000 \
myapp-frontend:latest위와 같이 명령어가 길고 복잡하며, 다른 팀원들에게서는 다르게 실행될 수도 있어 재현성이 부족하다는 단점이 있고, 순서 관리가 힘들며, 환경 변수 관리에 혼란(여러 곳에 흩어짐)이 있게 된다. bash script 로 이를 커버 할 수 있지만 bash script 의 코드를 해석해야한다는 불편함과 코드 로직을 직접 전부 짜야하는 단점이 있다.
이를 해결하고자 Docker Compose 가 나왔다.
Docker Compose 기본 구조
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "8080:80"
database:
image: postgres:14
environment:
POSTGRES_PASSWORD: secret버전은 굳이 명시 안해도 알아서 자동으로 찾아온다.
services: 실행시킬 컨테이너들을 넣을 수 있는 실행 동작을 추상화한 블럭인 듯하며, 실행 단위라고 봐도 무방하다. 실행 단위마다 최소 하나의 이미지가 들어가야 한다.image: 이미지 명과 태그가 들어가는 자리이다. 해당 이미지로 컨테이너를 실행하게 된다.ports: 서비스가 어떤 포트로 포워딩이 될지를 정하는 곳이다.environment: 환경변수를 설정할 수 있는 블록이고,key: value로도 되고,- key:value로도 된다.
container_name도 있는데 이는 잘 쓰이지 않는다. scaling 할 때 불편함 때문
Docker Network 설정
서비스끼리의 네트워크를 설정해보자.
services:
web:
image: nginx
networks:
- frontend
- backend
api:
image: myapi
networks:
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge기본적으로 networks 라는 블록이 없으면 docker-compose 내부의 서비스들은 한 네트워크에 배치가 되어 서로 소통을 할 수 있게 된다. 만약 네트워크를 따로 설정해주고 싶다면 위처럼 networks 블록을 사용하여 network 를 생성할 수 있다.
Docker Volume 설정
데이터를 영구적으로 저장하기 위한 볼륨을 지정해보자.
services:
db:
image: postgres:14
volumes:
- db_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
web:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- static_content:/usr/share/nginx/html
volumes:
db_data:
driver: local
static_content:volumes 를 통해 Named Volume 을 지정하고 있음을 볼 수 있고, 이를 위 services 에서 쓰고 있음을 볼 수 있다. 또한 마지막 : 의 구분자로 read-only 를 주고 있는것도 볼 수 있을 것이다.
Docker Compose Build 블럭
서비스에 build 블럭을 쓸 수도 있다.
services:
web:
build:
context: ./app
dockerfile: Dockerfile.dev
args:
- NODE_VERSION=18
- APP_ENV=development
cache_from:
- myapp:latest
image: myapp:dev
ports:
- "3000:3000"Docker Compose 환경변수 연동
services:
db:
image: postgres:14
env_file:
- .env
- .env.local
environment:
POSTGRES_USER: ${DB_USER:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DBNAME:-myapp}위처럼 bash script 의 문법을 가져가면 된다. 민감한 정보는 env 파일로 다루고, .env 파일은 일반적인 설정이며 .gitignore 에 추가하도록 한다.