튜토리얼

Docker Compose로 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드

강코의 코딩 일기 2026. 3. 19. 07:30

Docker Compose로 복잡한 다중 서비스 로컬 개발 환경을 쉽고 효율적으로 구축하는 방법을 단계별로 안내합니다. 컨테이너 간 연동부터 실제 예제까지, 개발 생산성을 높여보세요.

안녕하세요! 개발자라면 한 번쯤 겪어봤을 법한 고민이 있죠? "내 컴퓨터에서는 잘 되는데, 왜 다른 팀원 컴퓨터에서는 안 될까?", "새로운 프로젝트 시작할 때마다 환경 설정하느라 하루를 다 보내는 것 같아!" 이런 경험, 다들 있으실 거예요. 특히 여러 개의 서비스가 얽혀있는 복잡한 프로젝트를 진행할 때는 로컬 개발 환경을 구축하는 게 여간 까다로운 일이 아닌데요.

하지만 걱정 마세요! 오늘 이 글에서는 이런 복잡한 문제를 한 방에 해결해 줄 Docker Compose를 활용한 다중 서비스 연동 로컬 개발 환경 구축 방법을 아주 친근하고 자세하게 알려드릴 거거든요. 컨테이너 기술의 강력함과 Compose의 편리함을 제대로 느껴보실 준비되셨나요?

지금부터 저와 함께 Docker Compose의 세계로 떠나볼까요?


Docker Compose를 활용한 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드 - people, portrait, man, kathmandu, nepal, water, architecture, nature, face, old man, person

Image by 16692474 on Pixabay

왜 Docker Compose로 로컬 개발 환경을 구축해야 할까요?

우리가 겪는 로컬 개발 환경의 어려움은 대부분 의존성 문제에서 시작돼요. 예를 들어, 백엔드 서비스는 특정 버전의 Java와 PostgreSQL이 필요하고, 프론트엔드 서비스는 Node.js와 Redis 캐시가 필요하다고 해볼게요. 이 모든 것을 내 로컬 컴퓨터에 직접 설치하고 관리하려면 어떻게 될까요?

  • 버전 충돌: 여러 프로젝트를 동시에 진행할 때, 특정 라이브러리나 런타임의 버전이 충돌해서 어느 한쪽은 제대로 동작하지 않을 수 있어요.
  • 환경 불일치: 개발팀원마다 운영체제나 설치된 소프트웨어의 버전이 달라 "내 컴퓨터에서는 되는데..." 같은 비극적인 상황이 발생하죠.
  • 복잡한 설정: 새로운 팀원이 합류하거나 프로젝트를 새로 시작할 때마다 모든 환경을 처음부터 설정해야 하는 번거로움이 있어요.

이런 문제들을 Docker Compose가 어떻게 해결해 줄까요? 바로 컨테이너 기술의 장점을 십분 활용해서 말이죠.

  • 일관성 유지: 모든 서비스가 동일한 Docker 이미지를 기반으로 실행되므로, 개발 환경의 일관성을 완벽하게 유지할 수 있어요.
  • 격리된 환경: 각 서비스는 독립적인 컨테이너 안에서 실행되기 때문에, 서로 간의 의존성 충돌이나 로컬 환경과의 간섭 없이 깨끗하게 동작합니다.
  • 쉬운 설정 및 배포: YAML 파일 하나로 전체 서비스 구성과 연동 방법을 정의할 수 있어서, 단 한 줄의 명령어로 복잡한 다중 서비스 환경을 손쉽게 띄울 수 있어요.

결론적으로 Docker Compose개발 생산성을 극대화하고, 팀원 간의 협업을 원활하게 만들어주는 마법 같은 도구라고 할 수 있답니다.


Docker Compose, 넌 누구니?: 핵심 개념 이해하기

Docker Compose는 여러 개의 Docker 컨테이너를 하나의 애플리케이션으로 정의하고 실행하는 도구예요. 쉽게 말해, 개별 컨테이너를 하나하나 수동으로 관리하는 대신, 여러 컨테이너들을 묶어서 한 번에 관리할 수 있게 해주는 오케스트레이션 툴의 경량 버전이라고 생각하시면 돼요.

docker-compose.yml 파일의 중요성

Docker Compose의 핵심은 바로 docker-compose.yml이라는 YAML 파일이에요. 이 파일 안에는 우리가 만들고자 하는 다중 서비스 애플리케이션의 모든 구성 정보가 담겨 있답니다.

어떤 정보들이 들어갈까요?

  • services: 실행할 각 컨테이너(서비스)에 대한 정의 (예: 웹 서버, 데이터베이스, 캐시 서버 등)
  • networks: 컨테이너들이 서로 통신할 수 있도록 만들어주는 가상 네트워크 설정
  • volumes: 컨테이너 내의 데이터를 영구적으로 저장하거나 호스트와 공유하기 위한 설정

각 서비스는 사용할 Docker 이미지, 포트 매핑, 환경 변수, 의존성 등 상세한 정보를 가질 수 있어요. 이 파일 하나만 잘 작성해두면, 언제 어디서든 동일한 개발 환경을 즉시 구축할 수 있는 거죠. 정말 편리하지 않나요?


로컬 개발 환경 구축의 첫걸음: 기본 Docker Compose 파일 작성

그럼 이제 Docker Compose를 이용한 로컬 개발 환경 구축의 첫 단계를 밟아볼까요? 가장 기본적인 시나리오로, 간단한 웹 서비스(예: Node.js 애플리케이션)와 데이터베이스(예: PostgreSQL)를 연동하는 환경을 만들어볼게요.

먼저, 프로젝트 루트 디렉토리에 docker-compose.yml 파일을 생성합니다.


# docker-compose.yml
version: '3.8' # Docker Compose 파일 형식 버전

services:
  web: # 웹 서비스 정의
    build: . # 현재 디렉토리의 Dockerfile을 사용하여 이미지 빌드
    ports:
      - "3000:3000" # 호스트의 3000번 포트를 컨테이너의 3000번 포트에 연결
    environment: # 컨테이너 내에서 사용할 환경 변수 설정
      DATABASE_URL: postgres://user:password@db:5432/mydatabase
    depends_on: # 'web' 서비스가 'db' 서비스에 의존함을 명시
      - db

  db: # 데이터베이스 서비스 정의
    image: postgres:13 # PostgreSQL 13 버전 이미지 사용
    environment: # PostgreSQL 환경 변수 설정
      POSTGRES_DB: mydatabase
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes: # 데이터 지속성을 위한 볼륨 설정
      - db_data:/var/lib/postgresql/data

volumes: # 볼륨 정의
  db_data:

docker-compose.yml 파일은 다음과 같은 의미를 가집니다.

  • version: '3.8': Docker Compose 파일 형식의 버전을 명시해요. 최신 버전을 사용하는 것이 좋겠죠?
  • services: 우리가 실행할 서비스들을 정의하는 섹션이에요. 여기서는 webdb 두 가지 서비스를 정의했습니다.
  • web 서비스:
    • build: .: 현재 디렉토리에 있는 Dockerfile을 사용해서 Docker 이미지를 직접 빌드하라는 의미예요. (아래에 간단한 Dockerfile 예시를 보여드릴게요!)
    • ports: "3000:3000": 호스트 머신의 3000번 포트로 들어오는 요청을 web 컨테이너의 3000번 포트로 전달하도록 설정합니다.
    • environment: 컨테이너 내부에서 사용할 환경 변수를 설정하는데요, 여기서는 데이터베이스 접속 정보를 넣어줬어요.
    • depends_on: - db: web 서비스는 db 서비스가 시작된 후에 시작되어야 함을 알려줍니다. (이는 시작 순서만 보장하며, db 컨테이너 내부의 프로세스가 완전히 준비되었음을 보장하지는 않아요!)
  • db 서비스:
    • image: postgres:13: Docker Hub에서 공식 postgres:13 이미지를 다운로드하여 사용합니다.
    • environment: PostgreSQL 데이터베이스의 이름, 사용자, 비밀번호를 설정해요.
    • volumes: - db_data:/var/lib/postgresql/data: db_data라는 볼륨을 생성해서 컨테이너 내부의 PostgreSQL 데이터 디렉토리와 연결합니다. 이렇게 하면 컨테이너가 삭제되어도 데이터는 볼륨에 남아있게 되어 데이터의 지속성을 확보할 수 있어요.
  • volumes: 최하단에 db_data 볼륨을 명시적으로 정의해줬어요.

그리고 web 서비스를 위한 간단한 Dockerfile과 샘플 Node.js 애플리케이션이 필요하겠죠? server.jspackage.json이 있는 디렉토리에 Dockerfile을 만들어주세요.


# Dockerfile (web 서비스용)
FROM node:18-alpine # Node.js 18 버전 기반 이미지 사용
WORKDIR /app # 작업 디렉토리 설정
COPY package*.json ./ # package.json 및 package-lock.json 복사
RUN npm install # 의존성 설치
COPY . . # 나머지 파일 복사
EXPOSE 3000 # 3000번 포트 노출
CMD ["node", "server.js"] # 애플리케이션 실행 명령어

간단한 Node.js 웹 서비스 예시 (server.js):


// server.js
const express = require('express');
const { Pool } = require('pg');
const app = express();
const port = 3000;

// PostgreSQL 연결 풀 설정 (환경 변수 사용)
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
});

app.get('/', async (req, res) => {
  try {
    const client = await pool.connect();
    const result = await client.query('SELECT NOW()'); // 현재 시간 조회
    client.release();
    res.send(`Hello from web service! Current DB time: ${result.rows[0].now}`);
  } catch (err) {
    console.error('Error connecting to DB', err);
    res.status(500).send('Error connecting to database.');
  }
});

app.listen(port, () => {
  console.log(`Web service listening at http://localhost:${port}`);
});

그리고 package.json 파일:


// package.json
{
  "name": "web-service",
  "version": "1.0.0",
  "description": "A simple web service",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "pg": "^8.11.3"
  }
}

이제 이 모든 파일들을 같은 디렉토리에 두고 다음 명령어를 실행하면 됩니다.


docker compose up -d

-d 옵션은 컨테이너들을 백그라운드에서 실행하라는 의미예요. 명령어를 실행하면 Docker ComposeDockerfile을 빌드하고, PostgreSQL 이미지를 다운로드하여 두 개의 컨테이너를 생성하고 실행할 거예요. 웹 브라우저에서 http://localhost:3000으로 접속해보세요. 데이터베이스에서 현재 시간을 가져와서 보여주는 메시지를 확인할 수 있을 겁니다!

컨테이너가 잘 실행되고 있는지 확인하려면 다음 명령어를 사용합니다.


docker compose ps

모든 작업을 마치고 환경을 종료하고 싶을 때는:


docker compose down

이 명령어는 Docker Compose가 생성한 컨테이너네트워크를 모두 제거하지만, 볼륨은 기본적으로 제거하지 않아요. 볼륨까지 완전히 제거하려면 -v 옵션을 추가하면 됩니다.


docker compose down -v

Docker Compose를 활용한 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드 - architecture, building, skyscraper, exterior, modern architecture, facade, metal facade, media harbour, düsseldorf, nature, gehry, windows, reflections, clouds, sky, modern, germany, urban development

Image by cocoparisienne on Pixabay

다중 서비스 연동의 핵심: 서비스 간 통신 설정

앞서 예시에서 보셨듯이 Docker Compose 환경에서 여러 컨테이너가 서로 통신하는 것은 아주 자연스럽게 이루어져요. 어떻게 이런 마법이 가능할까요?

서비스 디스커버리와 네트워크

Docker Composedocker compose up 명령어를 실행할 때, 프로젝트별로 기본 브릿지 네트워크를 자동으로 생성해줘요. 그리고 이 네트워크에 모든 서비스 컨테이너들을 연결시켜 주거든요.

가장 중요한 점은, 이 네트워크 안에서는 각 서비스 이름이 곧 호스트 이름이 된다는 거예요! 예를 들어, web 서비스는 db라는 이름으로 db 서비스에 접근할 수 있습니다. 그래서 앞선 예시에서 DATABASE_URLdb:5432라고 설정했던 거랍니다. IP 주소를 몰라도, 포트만 알면 쉽게 접근할 수 있죠.

때로는 기본 네트워크만으로는 부족할 때도 있어요. 특정 서비스들만 접근할 수 있는 격리된 네트워크를 만들거나, 이미 존재하는 외부 네트워크에 연결해야 할 수도 있거든요. 이럴 때는 networks 섹션을 사용해서 네트워크를 명시적으로 정의할 수 있습니다.


# docker-compose.yml (네트워크 명시적 정의 예시)
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://user:password@db:5432/mydatabase
    depends_on:
      - db
    networks: # 'web' 서비스를 'app_network'에 연결
      - app_network

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: mydatabase
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - db_data:/var/lib/postgresql/data
    networks: # 'db' 서비스를 'app_network'에 연결
      - app_network

networks: # 'app_network'라는 사용자 정의 네트워크 정의
  app_network:
    driver: bridge # 기본 브릿지 드라이버 사용
    # external: true # 이미 존재하는 외부 네트워크에 연결할 경우

이렇게 networks를 명시적으로 정의하면, 컨테이너 간의 통신 구조를 더 명확하게 제어할 수 있어요. 예를 들어, admin_tool이라는 서비스는 데이터베이스에만 접근하고 웹 서비스에는 접근하지 못하게 할 수도 있겠죠.


실전 예제: 웹 서비스, DB, 캐시 연동 환경 구축

이제 조금 더 복잡하고 현실적인 시나리오를 살펴볼까요? 프론트엔드(React 개발 서버와 Nginx), 백엔드(Node.js API), 데이터베이스(PostgreSQL), 그리고 캐시(Redis)가 연동된 다중 서비스 환경을 Docker Compose로 구축해보겠습니다.

프로젝트 구조 설계

각 서비스는 독립적인 디렉토리를 가지고, 해당 디렉토리 안에 Dockerfile과 소스 코드를 두는 것이 일반적이에요. 전체 프로젝트 구조는 대략 다음과 같을 수 있습니다.


my-fullstack-app/
├── docker-compose.yml
├── .env
├── backend/
│   ├── Dockerfile
│   ├── package.json
│   └── server.js
├── frontend/
│   ├── Dockerfile (Nginx용)
│   ├── package.json (React 앱)
│   ├── public/
│   └── src/
└── nginx/
    └── nginx.conf

여기서는 프론트엔드를 빌드해서 Nginx로 서빙하는 방식으로 구성해볼게요.

`docker-compose.yml` 작성 및 실행

각 서비스에 대한 상세한 Dockerfile과 코드는 생략하고, 핵심인 docker-compose.yml 파일을 먼저 살펴보겠습니다.


# docker-compose.yml
version: '3.8'

services:
  nginx: # 리버스 프록시 및 정적 파일 서빙
    image: nginx:stable-alpine
    ports:
      - "80:80" # 호스트 80포트를 Nginx 80포트에 연결
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro # Nginx 설정 파일 마운트
      - ./frontend/build:/usr/share/nginx/html:ro # 빌드된 프론트엔드 파일 서빙
    depends_on:
      - backend # 백엔드 서비스에 의존
    networks:
      - app_network

  frontend_build: # 프론트엔드 빌드 서비스 (일회성)
    build:
      context: ./frontend
      dockerfile: Dockerfile.build # frontend 디렉토리 내 Dockerfile.build 사용
    volumes:
      - ./frontend/build:/app/build # 빌드 결과물을 호스트에 마운트
    command: ["npm", "run", "build"] # 빌드 명령어 실행
    networks:
      - app_network # 네트워크에 연결 (빌드 과정에서 필요할 수 있음)
    # entrypoint: ["/bin/sh", "-c", "npm install && npm run build"] # 빌드 후 종료되도록

  backend: # 백엔드 API 서비스
    build: ./backend # backend 디렉토리의 Dockerfile 사용
    ports:
      - "5000:5000" # 개발용: 백엔드 직접 접속 (선택 사항)
    environment:
      DATABASE_URL: postgres://user:password@db:5432/mydatabase
      REDIS_HOST: redis
      REDIS_PORT: 6379
    depends_on:
      - db
      - redis
    networks:
      - app_network

  db: # PostgreSQL 데이터베이스
    image: postgres:13
    environment:
      POSTGRES_DB: mydatabase
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - app_network

  redis: # Redis 캐시 서버
    image: redis:6-alpine
    volumes:
      - redis_data:/data # Redis 데이터 지속성을 위한 볼륨
    networks:
      - app_network

networks:
  app_network:
    driver: bridge

volumes:
  db_data:
  redis_data:

이 구성은 다음과 같은 특징을 가집니다.

  • nginx: Nginx 컨테이너는 호스트의 80번 포트로 들어오는 요청을 받아요. nginx.conf 파일을 통해 정적 파일(프론트엔드 빌드 결과물)을 서빙하고, 특정 경로(예: /api)로 들어오는 요청은 backend 서비스로 리버스 프록시합니다.
  • frontend_build: 프론트엔드 애플리케이션(React)을 빌드하는 컨테이너예요. command를 사용해 빌드 명령어를 실행하고, 빌드된 결과물(./frontend/build)은 볼륨 마운트를 통해 호스트로 가져와서 nginx 서비스가 서빙할 수 있도록 합니다. 이 서비스는 한 번 빌드하고 나면 종료될 거예요.
  • backend: Node.js 기반의 백엔드 API 서버입니다. 데이터베이스와 Redis에 의존하며, 환경 변수를 통해 연결 정보를 전달받아요.
  • db: PostgreSQL 데이터베이스 컨테이너입니다. 볼륨을 통해 데이터의 지속성을 확보합니다.
  • redis: Redis 캐시 서버 컨테이너입니다. 이 역시 볼륨을 사용해서 데이터를 영구적으로 저장할 수 있게 합니다.
  • app_network: 모든 서비스가 이 사용자 정의 네트워크에 연결되어 서로 서비스 이름으로 통신할 수 있어요.

Nginx 설정 파일 (nginx/nginx.conf) 예시:


# nginx/nginx.conf
events {
    worker_connections 1024;
}

http {
    upstream backend_server {
        server backend:5000; # Docker Compose 서비스 이름으로 백엔드 접근
    }

    server {
        listen 80;
        server_name localhost;

        location / {
            root /usr/share/nginx/html; # 프론트엔드 빌드 파일 경로
            index index.html index.htm;
            try_files $uri $uri/ /index.html; # SPA 라우팅 지원
        }

        location /api/ {
            proxy_pass http://backend_server; # /api 요청은 백엔드로 프록시
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

프론트엔드 빌드를 위한 Dockerfile.build (frontend/Dockerfile.build):


# frontend/Dockerfile.build
FROM node:18-alpine as builder
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build # React 앱 빌드

이제 모든 설정이 완료되었다면, 프로젝트 루트 디렉토리에서 다음 명령어를 실행합니다.


docker compose up -d --build

--build 옵션은 Dockerfile이 있는 서비스들을 다시 빌드하라는 의미예요. frontend_build 서비스가 먼저 실행되어 프론트엔드를 빌드하고, 그 결과물이 호스트에 저장되면 Nginx가 이를 서빙하게 됩니다. 모든 서비스가 성공적으로 실행되면, 웹 브라우저에서 http://localhost로 접속하여 프론트엔드 애플리케이션을 확인할 수 있고, 백엔드 API 호출도 Nginx를 통해 정상적으로 이루어질 거예요.

정말 멋지지 않나요? 복잡한 다중 서비스 아키텍처Docker Compose 하나로 손쉽게 관리할 수 있답니다!


Docker Compose를 활용한 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드 - statue, sculpture, iron, steel, docker, finland, hamina, docker, docker, docker, docker, docker, finland

Image by Olga_Fil on Pixabay

더욱 강력하게 활용하기: 볼륨, 네트워크, 환경 변수

Docker Compose는 단순히 여러 컨테이너를 띄우는 것 이상의 강력한 기능을 제공해요. 볼륨, 네트워크, 환경 변수를 잘 활용하면 개발 환경을 더욱 유연하고 효율적으로 만들 수 있답니다.

볼륨 (Volumes)

앞서 데이터베이스 예시에서 보셨듯이, 볼륨컨테이너가 삭제되어도 데이터를 보존할 수 있게 해주는 핵심 기능이에요. Docker Compose에서는 두 가지 주요 볼륨 유형을 사용할 수 있습니다.

  • Named Volumes (이름 있는 볼륨): Docker가 관리하는 볼륨으로, 주로 데이터베이스처럼 지속성 데이터가 필요한 경우에 사용합니다. db_data, redis_data처럼 이름을 붙여 관리하죠.
  • Bind Mounts (바인드 마운트): 호스트 머신의 특정 경로를 컨테이너 내부 경로에 직접 연결하는 방식이에요. 개발 중인 소스 코드를 컨테이너와 공유할 때 유용합니다. 호스트에서 코드를 수정하면 컨테이너에도 즉시 반영되어 개발 생산성을 높일 수 있어요.

예를 들어, 백엔드 서비스의 코드를 바인드 마운트로 연결하고 싶다면 다음과 같이 volumes 설정을 추가할 수 있어요.


services:
  backend:
    build: ./backend
    # ... (생략)
    volumes:
      - ./backend:/app # 호스트의 ./backend 디렉토리를 컨테이너의 /app 디렉토리에 마운트

이렇게 하면 backend 컨테이너/app 디렉토리가 호스트의 ./backend 디렉토리와 동기화되어, 호스트에서 코드를 수정하면 컨테이너 내부에서도 즉시 변경된 코드를 사용할 수 있게 됩니다 (물론 애플리케이션 재시작은 필요할 수 있겠죠!).

네트워크 (Networks)

사용자 정의 네트워크를 통해 서비스 간의 통신을 더욱 세밀하게 제어할 수 있다고 말씀드렸는데요. 예를 들어, 특정 백엔드 서비스만 접근할 수 있는 데이터베이스 네트워크를 만들거나, 외부에서 접근 가능한 공개 네트워크와 내부 전용 프라이빗 네트워크를 분리할 수도 있습니다.

또한, 이미 호스트에 존재하는 Docker 네트워크Docker Compose 서비스를 연결하고 싶다면 external: true 옵션을 사용할 수 있어요.


networks:
  existing_network:
    external: true # 이미 존재하는 'existing_network'에 연결

이렇게 하면 Docker Compose로 띄운 서비스들이 기존 Docker 환경의 다른 컨테이너들과도 손쉽게 통신할 수 있게 됩니다.

환경 변수 (Environment Variables)

데이터베이스 비밀번호나 API 키 같은 민감한 정보는 docker-compose.yml 파일에 직접 노출하는 것보다 환경 변수로 관리하는 것이 보안상 훨씬 안전해요. Docker Compose.env 파일을 통해 환경 변수를 쉽게 관리할 수 있도록 지원합니다.

프로젝트 루트 디렉토리에 .env 파일을 생성하고 다음과 같이 내용을 작성합니다.


# .env
POSTGRES_DB=mydatabase
POSTGRES_USER=user
POSTGRES_PASSWORD=password
REDIS_HOST=redis
REDIS_PORT=6379

그리고 docker-compose.yml 파일에서 environment 섹션을 수정하여 .env 파일의 변수를 참조하도록 할 수 있어요.


services:
  backend:
    # ...
    environment:
      DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
      REDIS_HOST: ${REDIS_HOST}
      REDIS_PORT: ${REDIS_PORT}
    env_file: # .env 파일을 사용하여 환경 변수 로드
      - ./.env

  db:
    # ...
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    env_file:
      - ./.env

  redis:
    # ...
    env_file:
      - ./.env

이렇게 하면 .env 파일만 수정하면 모든 서비스의 환경 변수를 일괄적으로 변경할 수 있어서 매우 편리하고, 민감한 정보가 docker-compose.yml 파일에 직접 노출되지 않아 보안에도 유리하죠.

마지막으로, Docker CLIDocker Compose CLI다중 서비스 환경을 관리할 때 어떻게 다른지 간단한 표로 비교해볼게요.

기능 Docker CLI (단일 컨테이너) Docker Compose CLI (다중 서비스)
컨테이너 생성 및 시작 docker run [OPTIONS] IMAGE [COMMAND] (개별 컨테이너마다 실행) docker compose up [-d] [--build] (docker-compose.yml에 정의된 모든 서비스 한 번에 시작)
실행 중인 컨테이너 확인 docker ps docker compose ps (프로젝트 단위로 서비스 확인)
컨테이너 로그 확인 docker logs [CONTAINER_ID_OR_NAME] docker compose logs [SERVICE_NAME] (특정 서비스 또는 전체 서비스 로그 확인)
컨테이너 중지 docker stop [CONTAINER_ID_OR_NAME] docker compose stop [SERVICE_NAME] (특정 서비스 또는 전체 서비스 중지)
컨테이너 삭제 docker rm [CONTAINER_ID_OR_NAME] docker compose rm [SERVICE_NAME] (컨테이너만 삭제)
환경 전체 제거 docker rm -f $(docker ps -a -q) (모든 컨테이너 수동 제거) docker compose down [-v] [--rmi all] (docker-compose.yml에 정의된 모든 리소스 제거)

보시는 것처럼 Docker Compose CLI를 사용하면 다중 서비스 환경을 훨씬 직관적이고 효율적으로 관리할 수 있어요. 각 컨테이너를 일일이 신경 쓸 필요 없이, 프로젝트 단위로 명령어를 실행할 수 있다는 점이 가장 큰 장점이랍니다.


마무리: Docker Compose로 개발 생산성을 극대화하세요!

지금까지 Docker Compose를 활용하여 로컬 개발 환경을 구축하고 다중 서비스를 연동하는 방법에 대해 자세히 알아봤어요. Docker Compose는 단순히 개발 환경을 설정하는 도구를 넘어, 팀원 간의 개발 환경 일관성을 보장하고, 새로운 프로젝트 시작 시 환경 설정 시간을 획기적으로 줄여주는 강력한 솔루션이라는 것을 느끼셨으면 좋겠습니다.

의존성 문제로 골머리를 앓거나, "내 컴퓨터에서만 되는" 마법 같은 상황을 더 이상 겪고 싶지 않다면, 오늘부터 Docker Compose를 적극적으로 활용해보세요! 처음에는 YAML 파일 작성이 어렵게 느껴질 수도 있지만, 몇 번 연습하다 보면 금세 익숙해질 거예요.

여러분의 개발 생산성 향상에 이 글이 큰 도움이 되었기를 바랍니다. 혹시 Docker Compose를 사용하면서 겪었던 재미있는 경험이나 팁이 있다면, 주저하지 말고 댓글로 공유해주세요! 함께 배우고 성장하는 개발 문화, 정말 멋지잖아요?

다음에는 더 유익한 정보로 찾아올게요. 행복한 코딩하세요!

📌 함께 읽으면 좋은 글

  • [튜토리얼] Playwright E2E 테스트 환경 구축: 웹 자동화 실전 가이드
  • [개발 책 리뷰] 클린 코드, 유지보수성 높은 코드 작성 핵심 원리 실전 가이드북 심층 리뷰
  • [보안] 클라우드 시크릿 관리 전략: HashiCorp Vault와 AWS Secrets Manager 완벽 활용

이 글이 도움이 되셨다면 공감(♥)댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.