요약
Docker Compose로 백엔드 개발 환경 구축 2026
2026년 최신 Docker Compose 가이드로 DB, Redis 등 여러 서비스를 한 번에 설정하고 관리하는 방법을 상세히 분석합니다.
핵심 키워드: Docker Compose, 백엔드 개발, 환경 구축, DB Redis 연동
이 글의 순서
1 배경: 왜 Docker Compose가 필수일까요?
2 Docker Compose 핵심 개념과 기본 구조
3 실전 예제: DB, Redis, 백엔드 앱 연동
4 Docker Compose 명령어와 관리 팁
5 흔히 겪는 문제와 해결 방안
6 FAQ: 자주 묻는 질문
배경
왜 Docker Compose가 필수일까요?
백엔드 개발자라면 누구나 한 번쯤 개발 환경 설정 때문에 골머리를 앓아본 경험이 있을 겁니다. 데이터베이스, 캐시 서버, 메시지 큐 등 다양한 서비스들을 로컬 머신에 일일이 설치하고 버전을 관리하며, 서로 충돌하지 않도록 설정하는 것은 여간 번거로운 일이 아닐 수 없습니다. 특히 팀 프로젝트의 경우, 개발자마다 다른 OS나 환경 설정으로 인해 ‘내 컴퓨터에서는 되는데…’라는 비극적인 상황이 발생하기도 합니다.
이러한 문제들을 해결하기 위해 등장한 것이 바로 컨테이너 기술, 그리고 그 중에서도 Docker입니다. Docker는 애플리케이션과 그 종속성들을 컨테이너라는 독립적인 환경에 패키징하여, 어떤 환경에서든 동일하게 실행될 수 있도록 돕습니다. 하지만 여러 개의 컨테이너를 함께 관리해야 할 때는 또 다른 복잡성이 생겨나죠. 예를 들어, 백엔드 애플리케이션, MySQL 데이터베이스, Redis 캐시 서버를 각각 별도의 Docker 컨테이너로 실행하고, 이들 간의 네트워크를 연결하며, 데이터 영속성을 관리하는 것은 수동으로 하기에는 많은 명령과 설정이 필요합니다.
“Docker Compose는 여러 컨테이너를 하나로 묶어 관리하는 오케스트레이션 도구로, 개발 환경 구축의 복잡성을 혁신적으로 줄여줍니다.”
— 권퓨터의 개발 철학
여기서 Docker Compose가 진정한 구원투수로 등장합니다. Docker Compose는 여러 Docker 컨테이너를 하나의 서비스로 정의하고, 이들을 단일 명령으로 실행하고 관리할 수 있도록 해주는 도구입니다. YAML 파일을 통해 서비스 간의 종속성, 네트워크 설정, 볼륨(데이터 저장 공간) 등을 선언적으로 정의할 수 있어, 개발 환경을 코드로 관리(Infrastructure as Code)하는 것이 가능해집니다.
2026년 현재, 클라우드 네이티브 환경이 대세가 되면서 Docker Compose는 개발 환경뿐만 아니라 소규모 프로덕션 환경에서도 유용하게 활용되고 있습니다. 이 글에서는 Docker Compose를 활용하여 백엔드 개발 환경을 쉽고 효율적으로 구축하는 방법을 단계별로 알아보겠습니다. 특히 MySQL(또는 PostgreSQL), Redis, 그리고 여러분의 백엔드 애플리케이션을 한 번에 띄우는 실전 예제를 통해 바로 적용할 수 있는 가이드를 제공할 예정입니다.


개념
Docker Compose 핵심 개념과 기본 구조
Docker Compose를 효과적으로 사용하기 위해서는 몇 가지 핵심 개념을 이해하는 것이 중요합니다. 이 섹션에서는 docker-compose.yml 파일의 기본 구조와 주요 요소들을 자세히 살펴보겠습니다.
1. docker-compose.yml 파일: 환경의 설계도
Docker Compose는 모든 설정을 하나의 YAML 파일에 정의합니다. 이 파일은 프로젝트의 모든 서비스, 네트워크, 볼륨 등을 선언적으로 기술하는 역할을 합니다. 일반적으로 프로젝트의 루트 디렉토리에 docker-compose.yml이라는 이름으로 생성합니다.
2. services: 컨테이너 정의
services는 Docker Compose 파일의 핵심입니다. 각 서비스는 하나의 컨테이너를 나타내며, 해당 컨테이너를 어떻게 빌드하고 실행할지에 대한 모든 설정을 포함합니다.
다음은 일반적인 서비스 정의에서 사용되는 주요 속성들입니다.
version: '3.8'
services:
my-app: # 서비스 이름
image: my-backend-image:latest # 사용할 Docker 이미지 (Docker Hub 또는 로컬)
build: # Dockerfile을 사용하여 이미지를 빌드할 경우
context: . # Dockerfile이 있는 경로
dockerfile: Dockerfile # Dockerfile 이름
ports: # 호스트와 컨테이너 포트 매핑
- "8080:8080"
environment: # 컨테이너 내부 환경 변수 설정
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydb
SPRING_DATASOURCE_USERNAME: user
SPRING_DATASOURCE_PASSWORD: password
volumes: # 호스트와 컨테이너 볼륨 매핑 (데이터 영속성)
- ./app_data:/app/data
depends_on: # 서비스 간 종속성 (db가 먼저 시작되어야 함)
- db
networks: # 사용할 네트워크 지정
- my-network
3. networks: 서비스 간 통신
Docker Compose는 기본적으로 모든 서비스를 단일 브리지 네트워크에 연결하여 서비스 이름으로 서로 통신할 수 있게 합니다. 하지만 필요에 따라 사용자 정의 네트워크를 생성하여 네트워크를 분리하거나 더 세밀하게 제어할 수 있습니다.
같은 네트워크에 속한 컨테이너들은 서로의 서비스 이름으로 통신할 수 있습니다. 예를 들어, 백엔드 앱은 데이터베이스를 db라는 호스트 이름으로 접근할 수 있습니다.
4. volumes: 데이터 영속성
컨테이너는 기본적으로 상태를 저장하지 않는 휘발성(stateless) 환경입니다. 컨테이너가 삭제되면 그 안에 있던 데이터도 사라지죠. 데이터베이스처럼 영구적인 데이터를 저장해야 할 경우 볼륨(Volume)을 사용합니다. 볼륨은 호스트 머신의 특정 디렉토리를 컨테이너 내부에 마운트하여 데이터를 컨테이너 외부에서 관리할 수 있게 합니다.
이러한 개념들을 바탕으로 docker-compose.yml 파일을 작성하면, 복잡한 개발 환경도 몇 줄의 코드로 명확하게 정의하고 관리할 수 있게 됩니다. 이제 실제 예제를 통해 이 개념들을 어떻게 적용하는지 살펴보겠습니다.


실전 예제
실전 예제: DB, Redis, 백엔드 앱 연동
이제 실제 백엔드 개발 환경을 Docker Compose로 구축하는 예제를 살펴보겠습니다. 여기서는 MySQL 8.0 데이터베이스, Redis 7.0 캐시 서버, 그리고 간단한 가상의 백엔드 애플리케이션을 연동하는 시나리오를 가정합니다.
1. 프로젝트 구조 준비
먼저 프로젝트의 기본 디렉토리 구조를 설정합니다. 백엔드 애플리케이션 코드는 backend 디렉토리에, Docker Compose 파일은 루트 디렉토리에 위치시킬 것입니다.
다음과 같이 프로젝트 디렉토리를 구성합니다.
.
├── backend/
│ ├── Dockerfile
│ └── src/ # 백엔드 애플리케이션 소스 코드
└── docker-compose.yml
2. 백엔드 애플리케이션 Dockerfile 작성 (예시)
백엔드 애플리케이션을 Docker 컨테이너로 만들기 위한 Dockerfile을 backend/ 디렉토리에 작성합니다. 여기서는 Spring Boot 애플리케이션을 예시로 들겠습니다. Node.js나 Python 앱의 경우 해당 언어의 베이스 이미지와 빌드 명령을 사용하면 됩니다.
Spring Boot 애플리케이션을 빌드하고 실행하는 Dockerfile 예시입니다. JAR 파일을 컨테이너에 복사하여 실행합니다.
# backend/Dockerfile
FROM openjdk:17-jdk-slim
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
EXPOSE 8080
3. docker-compose.yml 파일 작성
이제 가장 중요한 docker-compose.yml 파일을 작성합니다. 이 파일은 MySQL, Redis, 그리고 백엔드 앱 세 가지 서비스를 정의합니다.
MySQL, Redis, 백엔드 애플리케이션을 포함하는 완전한 Docker Compose 파일입니다. 각 서비스의 설정과 네트워크, 볼륨 정의를 확인하세요.
# docker-compose.yml
version: '3.8'
services:
db:
image: mysql:8.0 # MySQL 8.0 이미지 사용
ports:
- "3306:3306" # 호스트 3306 포트를 컨테이너 3306 포트에 매핑
environment: # MySQL 환경 변수 설정
MYSQL_ROOT_PASSWORD: root_password # 루트 비밀번호
MYSQL_DATABASE: mydatabase # 데이터베이스 이름
MYSQL_USER: user # 사용자 이름
MYSQL_PASSWORD: password # 사용자 비밀번호
volumes:
- db_data:/var/lib/mysql # 데이터 영속성을 위한 이름 있는 볼륨
- ./mysql-init:/docker-entrypoint-initdb.d # 초기 스키마 및 데이터 주입 (선택 사항)
networks:
- backend-network
healthcheck: # DB 준비 상태 확인
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot_password"]
timeout: 20s
retries: 10
redis:
image: redis:7.0-alpine # Redis 7.0 경량 이미지 사용
ports:
- "6379:6379" # 호스트 6379 포트를 컨테이너 6379 포트에 매핑
command: redis-server --appendonly yes # 데이터 영속성을 위한 AOF 활성화
volumes:
- redis_data:/data # 데이터 영속성을 위한 이름 있는 볼륨
networks:
- backend-network
backend-app:
build: # Dockerfile을 사용하여 이미지를 빌드
context: ./backend # backend/ 디렉토리에서 Dockerfile 찾기
dockerfile: Dockerfile
ports:
- "8080:8080" # 호스트 8080 포트를 컨테이너 8080 포트에 매핑
environment: # 백엔드 앱 환경 변수 설정
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydatabase # DB 서비스 이름(db)으로 접근
SPRING_DATASOURCE_USERNAME: user
SPRING_DATASOURCE_PASSWORD: password
SPRING_REDIS_HOST: redis # Redis 서비스 이름(redis)으로 접근
SPRING_REDIS_PORT: 6379
depends_on: # db와 redis가 먼저 시작되어야 함
db:
condition: service_healthy # db 서비스의 healthcheck가 통과될 때까지 대기
redis:
condition: service_started # redis 서비스가 시작될 때까지 대기
networks:
- backend-network
networks:
backend-network: # 사용자 정의 네트워크 정의
driver: bridge
volumes:
db_data: # MySQL 데이터를 위한 이름 있는 볼륨
redis_data: # Redis 데이터를 위한 이름 있는 볼륨
주요 설정 설명:
db서비스:mysql:8.0이미지를 사용합니다.MYSQL_ROOT_PASSWORD,MYSQL_DATABASE,MYSQL_USER,MYSQL_PASSWORD환경 변수를 설정하여 데이터베이스를 초기화합니다.db_data볼륨을 통해 데이터 영속성을 확보하며,healthcheck를 정의하여 DB가 완전히 준비될 때까지 기다리도록 설정했습니다.mysql-init볼륨은 컨테이너 시작 시 SQL 스크립트를 실행하여 초기 스키마를 구성하는 데 사용될 수 있습니다.redis서비스:redis:7.0-alpine이미지를 사용합니다.command: redis-server --appendonly yes를 통해 Redis의 AOF(Append Only File) 기능을 활성화하여 데이터 영속성을 강화합니다.redis_data볼륨을 사용합니다.backend-app서비스:build섹션을 통해backend/Dockerfile을 사용하여 이미지를 직접 빌드합니다.environment변수를 통해 DB와 Redis에 연결할 정보를 전달하는데, 이때 호스트 이름으로 각 서비스의 이름(db,redis)을 사용합니다.depends_on을 사용하여db와redis서비스가 먼저 시작되고 준비될 때까지 기다리도록 설정했습니다. 특히service_healthy조건을 사용하여 DB의 실제 준비 상태를 확인하는 것이 중요합니다.networks:backend-network라는 사용자 정의 브리지 네트워크를 생성하여 세 서비스가 이 네트워크를 통해 통신하도록 합니다. 이렇게 하면 서비스 간 통신이 격리되고 명확해집니다.volumes:db_data와redis_data라는 이름 있는 볼륨을 정의하여 각 서비스의 데이터가 컨테이너 외부의 Docker 관리 영역에 영구적으로 저장되도록 합니다.
핵심 포인트: depends_on은 서비스 시작 순서를 보장하지만, 서비스가 완전히 준비(Ready)될 때까지 기다리는 것은 아닙니다. DB의 경우 healthcheck와 condition: service_healthy를 함께 사용하여 실제 DB가 연결 가능한 상태가 될 때까지 기다리게 하는 것이 중요합니다.

활용 가이드
Docker Compose 명령어와 관리 팁
docker-compose.yml 파일을 작성했다면, 이제 몇 가지 간단한 명령어로 전체 개발 환경을 쉽게 관리할 수 있습니다. 2026년 현재 docker compose CLI(command-line interface)는 docker-compose 스탠드얼론 명령어를 대체하여 Docker 엔진에 통합되었습니다. 따라서 docker compose 명령어를 사용하는 것이 권장됩니다.
1. 서비스 실행 및 중지
코드 설명: docker-compose.yml 파일이 있는 디렉토리에서 다음 명령어를 실행하여 모든 서비스를 백그라운드에서 시작합니다.
docker compose up -d
-d(detach) 옵션은 컨테이너를 백그라운드에서 실행하여 터미널을 점유하지 않도록 합니다.- 최초 실행 시 Docker 이미지를 다운로드하고 백엔드 앱 이미지를 빌드하는 데 시간이 걸릴 수 있습니다.
실행 중인 모든 서비스를 중지하고 컨테이너를 제거합니다.
docker compose down
docker compose down은 컨테이너와 네트워크를 제거하지만,volumes에 정의된 데이터 볼륨은 기본적으로 유지됩니다.- 데이터 볼륨까지 완전히 제거하려면
-v옵션을 추가합니다:docker compose down -v. 이 명령어는 데이터베이스의 데이터를 완전히 삭제하므로 주의해서 사용해야 합니다.
2. 서비스 상태 확인
현재 실행 중인 서비스들의 상태를 확인합니다.
docker compose ps
- 이 명령은 각 서비스의 이름, 상태, 포트 매핑 등을 보여줍니다.
3. 로그 확인
모든 서비스의 실시간 로그를 확인합니다.
docker compose logs -f
-f(follow) 옵션은 실시간으로 새로운 로그를 계속 출력합니다.- 특정 서비스의 로그만 보려면 서비스 이름을 지정합니다:
docker compose logs -f backend-app
“Docker Compose의 강력함은 단일 YAML 파일로 복잡한 환경을 선언하고, 몇 가지 명령어로 모든 것을 제어할 수 있다는 점에 있습니다.”
— 효율적인 개발의 시작
4. 특정 서비스만 재시작 / 빌드
백엔드 애플리케이션 코드 변경 후, 해당 서비스만 다시 빌드하고 재시작합니다.
docker compose up -d --no-deps --build backend-app
--no-deps: 종속성 서비스(db, redis)를 다시 시작하지 않습니다.--build:backend-app서비스의 이미지를 다시 빌드합니다. (Dockerfile 변경 또는 소스 코드 변경 시 필요)
핵심 포인트
개발 중에는 docker compose up -d --no-deps --build [서비스 이름] 명령을 활용하여 변경된 백엔드 애플리케이션만 빠르게 재배포하고 테스트할 수 있습니다. 이는 개발 생산성을 크게 향상시킵니다.
문제 해결
흔히 겪는 문제와 해결 방안
Docker Compose는 개발 환경 구축을 매우 편리하게 해주지만, 때로는 예상치 못한 문제에 직면할 수 있습니다. 여기서는 Docker Compose 사용 중 흔히 겪는 문제들과 그 해결 방안을 제시합니다.
문제 01
Port 겹침 오류 (Address already in use)
Docker Compose가 컨테이너를 실행하려고 할 때, 컨테이너에 매핑하려는 호스트 포트가 이미 다른 프로세스에 의해 사용 중인 경우 발생합니다. 예를 들어, MySQL 컨테이너의 3306 포트가 이미 로컬 MySQL 서버에 의해 사용 중일 수 있습니다.
해결 — 포트 번호 변경 또는 기존 프로세스 종료
1. docker-compose.yml 파일에서 해당 서비스의 ports 설정을 변경하여 사용 중이지 않은 다른 호스트 포트 번호로 매핑합니다. 예를 들어, MySQL의 호스트 포트를 33060으로 변경할 수 있습니다: - "33060:3306".
2. 이미 해당 포트를 사용 중인 로컬 프로세스를 종료합니다. Windows/Linux에서는 netstat -ano | findstr :[포트번호] (Windows), sudo lsof -i :[포트번호] (Linux) 명령어로 프로세스를 찾고 종료할 수 있습니다.
문제 02
컨테이너 간 네트워크 연결 실패
백엔드 애플리케이션이 데이터베이스나 Redis에 연결하지 못하는 경우입니다. 주로 잘못된 호스트 이름, 포트, 또는 네트워크 설정 때문에 발생합니다.
해결 — 서비스 이름 확인 및 네트워크 설정 점검
1. 백엔드 앱의 환경 변수에서 DB나 Redis의 호스트 이름이 docker-compose.yml에 정의된 서비스 이름(db, redis)과 일치하는지 확인합니다. SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydatabase 처럼 서비스 이름을 사용해야 합니다.
2. 모든 서비스가 동일한 networks에 속해 있는지 확인합니다. 만약 네트워크를 정의하지 않았다면, 기본 bridge 네트워크를 사용하게 됩니다.
3. docker compose logs [서비스 이름] 명령으로 각 서비스의 로그를 확인하여 연결 시도 및 실패 메시지를 분석합니다.
4. depends_on 조건이 service_healthy 또는 service_started로 올바르게 설정되어 있는지 확인하여, 종속 서비스가 완전히 준비될 때까지 기다리도록 합니다.
문제 03
볼륨 권한 문제 (Permission denied)
컨테이너가 볼륨에 데이터를 쓰거나 읽으려고 할 때 호스트 머신의 파일 시스템 권한 문제로 인해 접근이 거부될 수 있습니다. 특히 리눅스 환경에서 많이 발생합니다.
해결 — 볼륨 권한 조정
1. 이름 있는 볼륨을 사용하는 경우 Docker가 알아서 권한을 관리하므로 비교적 안전합니다. 가능하면 이름 있는 볼륨을 사용하는 것이 좋습니다.
2. 바인드 마운트를 사용하는 경우 (예: ./mysql-init:/docker-entrypoint-initdb.d), 호스트 머신에서 마운트하려는 디렉토리(mysql-init)에 Docker 컨테이너의 사용자(보통 root 또는 특정 사용자)가 접근할 수 있는 권한을 부여해야 합니다. sudo chmod -R 777 ./mysql-init와 같이 권한을 일시적으로 변경하여 테스트해볼 수 있지만, 보안상 777은 권장되지 않으므로 특정 사용자/그룹에게만 권한을 부여하는 것이 좋습니다.
핵심 포인트: 문제 발생 시 가장 먼저 docker compose ps로 서비스 상태를 확인하고, docker compose logs -f [서비스 이름]으로 상세 로그를 확인하는 것이 중요합니다. 대부분의 문제는 로그에 힌트가 있습니다.
자주 묻는 질문 (FAQ)
Q. Docker Compose를 사용하면 어떤 장점이 있나요?
Docker Compose는 여러 컨테이너로 구성된 애플리케이션을 단일 YAML 파일로 정의하고, 한 번의 명령으로 모든 서비스를 시작, 중지, 관리할 수 있게 해줍니다. 이를 통해 개발 환경 구축의 복잡성을 줄이고, 팀원 간 환경 일관성을 유지하며, 빠른 개발 환경 공유가 가능해집니다.
Q. docker-compose와 docker compose 명령어의 차이는 무엇인가요?
원래 docker-compose는 별도로 설치해야 하는 파이썬 기반의 도구였습니다. 하지만 2026년 현재는 Docker 엔진에 통합되어 docker compose (하이픈 없이) 명령어로 사용됩니다. 기능적으로는 거의 동일하지만, docker compose가 더 최신 표준이며 통합된 워크플로우를 제공합니다.
Q. 데이터베이스 데이터를 영구적으로 저장하려면 어떻게 해야 하나요?
docker-compose.yml 파일의 volumes 섹션을 사용하여 이름 있는 볼륨(Named Volume)을 정의해야 합니다. 예를 들어, MySQL 서비스에 db_data:/var/lib/mysql과 같이 볼륨을 지정하면, 컨테이너가 삭제되어도 데이터는 호스트 머신의 Docker 관리 볼륨에 남아있어 다음 실행 시에도 유지됩니다.
Q. 백엔드 앱에서 DB나 Redis에 연결할 때 어떤 호스트를 사용해야 하나요?
Docker Compose 네트워크 내에서는 각 서비스의 이름이 곧 호스트 이름이 됩니다. 따라서 백엔드 앱에서는 db라는 이름으로 데이터베이스에, redis라는 이름으로 Redis에 연결하면 됩니다. 예를 들어, DB 연결 URL은 jdbc:mysql://db:3306/mydatabase와 같이 설정합니다.
마무리
효율적인 개발 환경, 이제는 선택이 아닌 필수!
지금까지 Docker Compose를 활용하여 백엔드 개발 환경을 쉽고 효율적으로 구축하는 방법을 자세히 살펴보았습니다. 2026년 개발 트렌드에서 Docker Compose는 더 이상 선택 사항이 아니라, 안정적이고 일관된 개발 환경을 위한 필수 도구로 자리매김하고 있습니다. DB, Redis와 같은 다양한 미들웨어를 로컬에 직접 설치하고 관리하는 번거로움 없이, 단 하나의 docker-compose.yml 파일로 모든 것을 제어할 수 있다는 것은 개발 생산성을 비약적으로 향상시킬 수 있는 강력한 장점입니다.
“표준화된 개발 환경은 팀 전체의 효율성을 높이고, 개발자는 오직 코드와 비즈니스 로직에만 집중할 수 있게 합니다.”
— 권퓨터의 결론
이 가이드를 통해 여러분도 복잡한 백엔드 개발 환경 구축에 대한 부담을 덜고, 더 즐겁고 생산적인 개발 경험을 하시길 바랍니다. Docker Compose는 여러분의 개발 워크플로우를 한 단계 업그레이드할 수 있는 최고의 파트너가 될 것입니다. 앞으로도 Docker Compose의 더욱 다양한 기능과 고급 활용법을 탐구하며, 여러분의 개발 여정을 응원하겠습니다!
긴 글을 읽어주셔서 감사합니다!
Docker Compose로 개발 환경을 구축하며 궁금한 점이나 팁이 있다면 언제든지 댓글로 남겨주세요.
권퓨터는 항상 여러분의 개발 여정을 응원합니다!