![[도커 #8] 컴포즈](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog-custom%3Ftitle%3D%255B%25EB%258F%2584%25EC%25BB%25A4%2B%25238%255D%2B%25EC%25BB%25B4%25ED%258F%25AC%25EC%25A6%2588%26tag%3DTemplate%2B1%26description%3D%26template%3D3%26backgroundImage%3Dhttps%253A%252F%252Fsource.inblog.dev%252Fog_image%252Fdefault.png%26bgStartColor%3D%2523a8e8ec%26bgEndColor%3D%2523a8e8ec%26textColor%3D%2523000000%26tagColor%3D%2523000000%26descriptionColor%3D%2523000000%26logoUrl%3D%26blogTitle%3DGyeongwon%2527s%2Bblog&w=2048&q=75)
1. 도커 컴포즈(Docker Compose)란 ?
여러 개의 Docker 컨테이너를 하나의docker-compose.yml
파일로 정의하고 실행 할 수 있게 도와주는 도구이다. 마치 지휘자처럼 여러 서비스를 한 번에 관리한다.
예시) Spring 서버, MySQL, Redis, Nginx 등을 하나의 명령으로
up
, down
함로컬 개발 환경에서 멀티 컨테이너 구성을 빠르게 테스트할 때 사용하고, 배포용으로는 적합하지 않다.
배포는 더 강력한 오케스트레이터(Kubernetes, AWS ECS 등)을 사용
2. Compose 실행 구조
docker-compose up
명령어는 내부적으로 다음 두 단계를 자동 실행한다.docker build
(→Dockerfile
기반으로 이미지 빌드)
docker run
(→ 실제 컨테이너 실행)
이미지 빌드시, 내부적으로 빌드 전용 임시 컨테이너가 만들어져서 이미지 생성 후 삭제된다. 그 후 실제 서비스용 컨테이너가 뜨는 것이다. 그래서 "하나 실행되고, 리얼 컨테이너가 실행된다"는 표현이 나온 것이다.
docker-compose
는 컨테이너를 실행할 때 환경변수 주입한다. 따라서 .env
파일 또는 environment:
키워드를 활용해야 확실하다.이 시점에서 환경변수는 OS 레벨이 아니라, 컨테이너 내부 프로세스에 전달된다. 즉, 환경변수 설정 이후에 실행되는 명령어만 영향을 받는다.

Dockerfile에 서비스명을
ENV RDS_HOSTNAME=my_db
처럼 하면 이미지를 빌드하는 시점에는 my_db
컨테이너가 아직 존재하지 않는다. 따라서 DNS에 등록도 안되어 있음 무효한 설정이 들어가게 됨 즉 시점 차이를 잘 이해해야한다. 따라서 명심하자 환경변수는 docker-compose.yml에서 설정해야한다.3. Dockerfile 중심의 구성
docker-compose.yml
에image: ~
쓰지말고, 대신build:
속성으로 Dockerfile 기반 빌드를 유도하면 이미지 관리가 깔끔해지고, 버전 충돌 방지에 유리하다.

4. Docker의 DNS와 서비스 디스커버리
DNS (Domain Name System)
: 사람이 읽을 수 있는 도메인 이름(예:
google.com
)을 컴퓨터가 이해할 수 있는 IP 주소(예: 142.250.72.206
)로 변환해주는 시스템이다. 즉, “이름 → IP 주소” 매핑을 자동으로 해준다. Docker에서의 DNS는 ?
: 도커는 자체 DNS 서버를 가지고 있다. 같은 네트워크 안에 있는 컨테이너들끼리 이름으로 통신 할 수 있게 도와준다.
- 두 컨테이너는 같은 커스텀 네트워크에 속해야 한다.
- 각 컨테이너의 이름이 자동으로 도커 DNS에 등록됨
- IP 주소를 직접 몰라도 됨 (동적 IP 문제 해결)
서비스 디스커버리는 ?
: 서비스 이름만으로 다른 서비스(컨테이너)에 접근할 수 있도록 하는 기능이다. 도커의 DNS가 제공하는 핵심 기능 중 하나이고, 컨테이너 간 통신을 자동화하고 IP 관리를 없애주는 메커니즘이다.
5. 명령어 정리
명령어 | 설명 |
docker-compose up -d | 빌드 + 런까지 자동, 백그라운드 실행 |
docker-compose down | 전체 종료 및 네트워크 정리 |
docker-compose build | Dockerfile 기반 이미지 빌드만 |
docker-compose logs | 로그 확인 |
docker-compose exec <서비스명> bash | 실행 중인 컨테이너에 터미널 접속 |
6. [실습] Docker Compose 기반 멀티 컨테이너 구성 실습 - Spring 서버 + MySQL 연동
이 실습을 통하여 서비스 디스커버리, 환경변수 관리, 네트워크 구성까지 한번 잡아보았다.
디렉토리 구조

ex07/
├── db/
│ ├── Dockerfile # DB(MySQL) 이미지를 커스터마이징하기 위한 설정
│ └── init.sql # DB 초기화용 SQL 스크립트 (예: 테이블 생성, 데이터 삽입 등)
├── server/
│ ├── Dockerfile # 서버(Spring, Node 등) 이미지를 커스터마이징하는 설정
│ └── entrypoint.sh # 컨테이너 시작 시 실행되는 스크립트 (ex. 마이그레이션, 실행)
├── docker-compose.yml # 전체 컨테이너 조합을 정의한 구성 파일
정석적인 도커 멀티 컨테이너 프로젝트 구조다.
docker-compose.yml 코드 분석

./server/Dockerfile
을 기반으로 서버 애플리케이션 컨테이너 생성

- 외부에서
localhost:8080
으로 접근하면 컨테이너 내부의80
포트와 연결됨 (예: Spring 웹 서버)
- 서버가 죽어도 재시작됨
- my_db가 먼저 실행된 후, my_server가 실행됨, 데이터베이스가 준비되기 전에 서버가 먼저 실행되는 것을 방지

my_server
에 환경변수 전달
- 코드 내부에서 DB 접속할 때 사용됨
String url = "jdbc:mysql://" + RDS_HOSTNAME + ":" + RDS_PORT + "/" + RDS_DB_NAME;

- backend_network 라는 네트워크에 속해 있음
- 같은 네트워크에 속해있는 서비스와 통신 가능

backend_network
→my_db
,my_server
가 내부 통신을 위해 사용하는 네트워크
frontend_network
→ 현재는 아무 서비스에도 안 붙어있음. 추후 프론트엔드 서비스 붙일 때 사용할 수 있음.
전체 실습 코드
version: '3.8'
services:
my_db:
build:
context: ./db
ports:
- "3306:3306"
restart: always
networks:
- backend_network
my_server:
build:
context: ./server
ports:
- "8080:80"
restart: always
depends_on:
- my_db
environment:
- RDS_HOSTNAME=my_db
- RDS_PORT=3306
- RDS_USERNAME=ssar
- RDS_PASSWORD=ssar1234
- RDS_DB_NAME=blogdb
networks:
- backend_network
networks:
backend_network:
driver: bridge
frontend_network:
driver: bridge
항목 | 설명 |
my_db | 커스텀 MySQL 컨테이너 (3306 노출) |
my_server | Spring 또는 웹 서버 컨테이너 (8080 노출) |
depends_on | DB가 먼저 실행되어야 서버가 실행됨 |
RDS_HOSTNAME=my_db | 도커 DNS를 통해 이름 기반 DB 접속 가능 |
networks | 같은 네트워크 안에 있어야 이름 기반 통신(DNS) 가능 |
entrypoint.sh | 서버 시작 전에 초기 실행할 작업들을 정의 (예: 마이그레이션) |
init.sql | DB 최초 실행 시 초기 데이터 삽입 또는 스키마 구성 |

Share article