[IT-방법] 도커 컴포즈 실전 구축 가이드 – 1인 개발자를 위한 컨테이너 운영 핵심 절차

도커 컴포즈 기본 개념를 설명하는 실전 구축 가이드 대표 이미지

도커 컴포즈, 왜 명령어를 하나씩 치고 계신가요?

새로운 서버를 세팅할 때마다 docker run 명령어를 기억해내느라 진땀을 흘린 적이 있으신가요? 웹 서버를 띄우고, 데이터베이스를 연결하고, 캐시 서버인 레디스까지 올리려면 명령어만 대여섯 줄이 넘어가요. 이 명령어들을 메모장에 적어두었다가 나중에 다시 복사해서 붙여넣는 방식은 정말 위험해요. 실수로 옵션 하나를 빼먹으면 서비스가 제대로 작동하지 않거나, 데이터가 날아가는 끔찍한 상황이 생길 수 있거든요.

특히 1인 개발자라면 인프라 관리에 쏟을 시간이 부족해요. 서비스 로직을 짜는 시간도 모자란데, 컨테이너 하나하나의 네트워크 설정을 맞추고 볼륨을 연결하는 데 에너지를 다 써버리면 금방 지치고 말아요. 도커 컴포즈 실전 구축이 필요한 이유는 명확해요. 복잡한 명령어를 YAML 파일 하나로 문서화하여, 명령어 한 줄로 전체 환경을 똑같이 재현하기 위해서예요.

이 글을 끝까지 읽고 나면, 더 이상 수동으로 컨테이너를 하나씩 관리하지 않아도 돼요. 서버를 옮기거나 설정을 변경할 때도 파일 하나만 수정하면 끝나는 깔끔한 운영 환경을 갖추게 될 거예요. 단순히 이론만 설명하는 것이 아니라, 실제로 운영 서버에 바로 적용할 수 있는 실전 압축 가이드를 준비했어요.

이 글에서 함께 해볼 일들

  • 실무에서 바로 쓰는 프로젝트 디렉터리 구조 설계하기
  • 의존 관계와 네트워크를 고려한 서비스 정의법
  • 환경 변수와 볼륨을 활용한 안전한 데이터 관리
  • 실행 과정에서 발생하는 흔한 실수와 해결 방법

구축 전 반드시 체크해야 할 필수 준비물

도커 컴포즈를 본격적으로 다루기 전에, 여러분의 환경이 준비되어 있는지 확인해야 해요. 무턱대고 파일을 작성했다가는 문법 오류 때문에 시간을 허비할 수 있거든요. 우선 도커 엔진(Docker Engine)이 설치되어 있어야 하고, 최신 버전의 도커 컴포즈 플러그인이 포함되어 있는지 확인하세요. 요즘은 도커 설치 시 함께 포함되는 경우가 많지만, 구형 서버에서는 별도로 설치해야 할 수도 있어요.

또한, 서비스를 구성할 각 컨테이너의 이미지 이름을 미리 결정해두는 것이 좋아요. 예를 들어 웹 서버는 nginx:alpine처럼 가벼운 이미지를 쓸지, 아니면 특정 버전의 이미지를 쓸지 정해야 해요. 이렇게 미리 기준을 세워두면 나중에 파일을 수정할 일이 줄어들어요.

💡 알아두기
도커 컴포즈는 명령어를 실행하는 도구가 아니라, 실행할 환경을 정의하는 선언적 도구예요. ‘무엇을 해라’가 아니라 ‘어떤 상태로 만들어라’라고 명령하는 방식이라는 점을 기억하세요.

어떤 운영 방식을 선택할지 고민된다면 아래 비교 표를 참고해 보세요. 여러분의 현재 상황에 가장 적합한 방식을 고르는 데 도움이 될 거예요.

비교 항목 수동 docker run 방식 도커 컴포즈 방식
설정 관리 터미널 명령어 이력에 의존 YAML 파일로 영구 기록
멀티 컨테이너 각각 별도로 실행 및 연결 한 번에 전체 서비스 실행
환경 재현성 매우 낮음 (실수 가능성 높음) 매우 높음 (파일만 복사하면 끝)
네트워크 설정 수동으로 네트워크 생성/연결 자동으로 전용 네트워크 생성

만약 서비스 규모가 커져서 수십 개의 컨테이너를 관리해야 한다면 도커 컴포즈를 넘어 쿠버네티스(Kubernetes)를 고민해야 할 수도 있어요. 하지만 1인 개발자나 소규모 팀이 운영하는 서비스라면, 도커 컴포즈만으로도 충분히 강력하고 안정적인 운영이 가능해요. 오히려 설정이 너무 복잡한 시스템은 관리 비용만 높일 수 있으니, 지금은 컴포즈에 집중하는 것을 추천해요.

도커 컴포즈 실전 구축 5단계 프로세스

이제 실제로 서비스를 구축해 볼 차례예요. 단순히 코드를 따라 쓰는 것이 아니라, 왜 이런 구조가 필요한지 이해하면서 진행하는 것이 중요해요. 우리는 간단하지만 실무에서 가장 많이 쓰이는 웹 서버(Nginx) – 애플리케이션(Node.js) – 데이터베이스(MySQL) 조합을 예시로 들어볼게요.

STEP 1. 프로젝트 디렉터리 구조 설계하기

파일을 만들기 전에 먼저 폴더 구조를 깔끔하게 잡아야 해요. 모든 설정 파일을 한곳에 몰아넣으면 나중에 관리하기가 정말 힘들거든요. 추천하는 구조는 다음과 같아요.

  • my-project/ (루트 디렉터리)
    docker-compose.yml (컴포즈 설정 파일)
    .env (환경 변수 파일)
    ./nginx/ (웹 서버 설정 폴더)
    ./app/ (애플리케이션 소스 코드)
    ./data/ (데이터베이스 데이터 저장용 볼륨)

이렇게 분리해 두면, 각 서비스가 사용하는 설정값과 데이터가 어디에 있는지 한눈에 알 수 있어요. 특히 데이터베이스 데이터는 반드시 호스트 OS의 특정 폴더와 연결(볼륨 마운트)해 두어야 해요. 그렇지 않으면 컨테이너를 삭제하는 순간 소중한 데이터가 모두 사라지게 되니까요.

STEP 2. docker-compose.yml 파일 작성하기

이제 핵심인 docker-compose.yml 파일을 작성할 거예요. 이 파일은 각 서비스가 어떤 이미지를 사용할지, 어떤 포트를 열어둘지, 어떤 볼륨을 연결할지를 정의하는 설계도예요. 아래는 우리가 만들 서비스의 기본 뼈대예요.

version: '3.8'

services:
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_DATABASE: myapp_db
    volumes:
      - ./data/mysql:/var/lib/mysql

  app:
    build: ./app
    restart: always
    depends_on:
      - db
    environment:
      DB_HOST: db
      DB_USER: root
      DB_PASS: ${DB_PASSWORD}
    ports:
      - "3000:3000"

  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app

여기서 depends_on이라는 속성에 주목하세요. 이것은 서비스 간의 실행 순서를 정해줘요. 애플리케이션이 데이터베이스 없이 실행되면 에러가 나며 종료될 수 있기 때문에, 데이터베이스가 먼저 올라온 뒤에 애플리케이션이 실행되도록 순서를 잡아주는 것이죠.

STEP 3. 환경 변수(.env)로 보안 강화하기

위 코드에서 ${DB_PASSWORD}라고 적힌 부분을 보셨나요? 데이터베이스 비밀번호를 파일에 직접 적는 것은 매우 위험한 행동이에요. 만약 이 파일을 깃허브(GitHub) 같은 곳에 올리면 전 세계에 내 비밀번호가 공개되는 셈이니까요.

이럴 때 사용하는 것이 바로 .env 파일이에요. 프로젝트 루트에 .env 파일을 만들고 다음과 같이 작성하세요.

DB_PASSWORD=mysecretpassword123!
DEBUG=true

도커 컴포즈는 실행될 때 자동으로 같은 폴더에 있는 .env 파일을 읽어서 변수를 채워줘요. 이렇게 하면 설정 파일(YAML)은 공용으로 관리하되, 민감한 정보는 개인별로 혹은 서버별로 따로 관리할 수 있어 매우 안전하고 유연해져요.

STEP 4. 네트워크와 볼륨 최적화하기

서비스가 늘어나면 컨테이너끼리 어떻게 통신할지도 중요해져요. 도커 컴포즈는 기본적으로 모든 서비스가 하나의 가상 네트워크에 소속되게 만들어요. 덕분에 애플리케이션 코드에서 데이터베이스에 접속할 때 복잡한 IP 주소를 알 필요 없이, 서비스 이름인 db만 입력하면 바로 연결이 가능해요. 이것이 도커 컴포즈가 제공하는 가장 큰 마법 중 하나예요.

또한, 볼륨 설정 시 읽기 전용(read-only) 옵션을 적절히 활용하면 보안을 더 높일 수 있어요. 예를 들어 Nginx가 웹 소스 코드만 읽으면 된다면, :ro 옵션을 붙여서 웹 서버가 코드를 실수로 수정하거나 삭제하지 못하도록 막을 수 있어요.

STEP 5. 서비스 실행 및 상태 점검

모든 준비가 끝났다면 이제 명령어를 입력할 차례예요. 터미널에서 프로젝트 폴더로 이동한 뒤 아래 명령어를 입력하세요.

docker compose up -d

이 명령어는 모든 서비스를 백그라운드(detached mode)에서 실행하라는 뜻이에요. 서비스가 잘 올라왔는지 확인하려면 docker compose ps를 입력해 보세요. 각 컨테이너가 Up (healthy) 상태인지 확인하는 것이 핵심이에요. 만약 특정 서비스가 계속 꺼진다면 docker compose logs [서비스명]을 통해 어떤 에러가 발생했는지 꼼꼼히 살펴봐야 해요.

⚠️ 주의
포트 충돌을 조심하세요! 만약 내 컴퓨터의 80번 포트를 이미 다른 프로그램이 쓰고 있다면, 80:80 설정 시 에러가 발생하며 실행되지 않아요. 이럴 때는 8080:80처럼 호스트 포트를 바꿔서 지정해 주세요.

자주 하는 실수와 해결법 + FAQ

실전 구축 과정에서는 누구나 실수를 해요. 당황해서 서버를 끄기 전에, 아래 리스트를 보고 내가 무엇을 놓쳤는지 먼저 확인해 보세요.

자주 하는 실수와 해결법

  • 실수: 컨테이너를 재시작했는데 데이터가 초기화돼요.
    왜 발생할까요? 데이터베이스 데이터를 컨테이너 내부 저장소에만 저장했기 때문이에요. 컨테이너는 삭제되면 내부 데이터도 같이 사라져요.
    해결법: 반드시 volumes 설정을 통해 호스트 OS의 디렉터리와 연결해 주세요.
  • 실수: 애플리케이션이 DB를 찾지 못하고 종료돼요.
    왜 발생할까요? DB 컨테이너가 완전히 부팅되어 접속을 받아들일 준비가 되기도 전에 앱이 먼저 접속을 시도했기 때문이에요.
    해결법: depends_on만으로는 부족할 수 있어요. 앱의 로직에 ‘DB 접속 재시도(Retry)’ 코드를 넣거나, Healthcheck 기능을 활용하세요.
  • 실수: 외부에서 접속이 안 돼요.
    왜 발생할까요? 포트 포워딩 설정을 빠뜨렸거나, 방화벽에서 해당 포트를 막아두었을 가능성이 커요.
    해결법: YAML 파일의 ports: "80:80" 설정을 확인하고, 클라우드(AWS, GCP 등)를 사용 중이라면 보안 그룹 설정을 체크하세요.
  • 실수: .env 파일의 값이 적용되지 않아요.
    왜 발생할까요? 파일 이름이 정확하지 않거나, 변수 이름에 오타가 있을 때 발생해요.
    해결법: 파일명이 정확히 .env인지 확인하고, 변수명에 공백이 들어가지 않았는지 검토하세요.
  • 실수: 수정된 코드가 반영되지 않아요.
    왜 발생할까요? 이미 빌드된 이미지를 계속 사용하고 있기 때문이에요.
    해결법: docker compose up --build 명령어를 사용하여 이미지를 다시 빌드하며 실행하세요.

자주 묻는 질문

Q. 도커 컴포즈 파일을 수정하면 어떻게 적용해야 하나요?

수정된 설정을 반영하려면 단순히 docker compose up -d를 다시 입력하면 돼요. 도커 컴포즈가 변경 사항을 감지하고, 바뀐 부분만 알아서 재시작해 줍니다. 아주 똑똑하죠?

Q. 여러 개의 컴포즈 파일을 따로 관리할 수 있나요?

네, 가능해요. 개발 환경용과 운영 환경용 파일을 따로 만들어 두고, 실행할 때 -f 옵션으로 지정하면 돼요. 예를 들어 docker compose -f docker-compose.prod.yml up -d처럼 사용합니다.

Q. 컨테이너 내부로 직접 들어가서 명령어를 치고 싶을 때는 어떻게 하나요?

docker compose exec [서비스명] sh 명령어를 사용하세요. 쉘(Shell) 환경으로 접속하여 내부 파일 구조를 확인하거나 디버깅을 할 수 있어요.

Q. 사용하지 않는 이미지나 컨테이너가 용량을 너무 많이 차지해요.

정기적으로 docker system prune 명령어를 실행해 주세요. 사용하지 않는 컨테이너, 네트워크, 이미지를 한꺼번에 정리해서 디스크 공간을 확보해 줍니다.

Q. DB 비밀번호를 바꾸고 싶을 땐 어떻게 해야 하나요?

.env 파일을 수정한 뒤, 데이터베이스 컨테이너를 삭제하고 다시 생성해야 해요. 다만, 단순히 컨테이너만 삭제하는 게 아니라 기존에 생성된 볼륨 데이터와 충돌이 날 수 있으니 주의가 필요해요.

성공적인 운영을 위한 마지막 체크리스트

도커 컴포즈 구축을 마쳤다면 이제 운영의 영역으로 들어온 거예요. 처음에는 완벽하게 구축하기 어렵지만, 반복하면서 자신만의 패턴을 만들어가는 과정이 중요해요. 지금까지 배운 내용을 바탕으로, 실무에서 놓치지 말아야 할 핵심 사항들을 정리해 드릴게요.

✅ 핵심 요약

  • 데이터베이스 데이터는 반드시 외부 볼륨으로 연결할 것
  • 민감한 정보는 반드시 .env 파일을 통해 관리할 것
  • 서비스 간 의존성은 depends_on으로 명시할 것
  • 환경 변수 변경 시에는 –build 옵션을 활용할 것
  • 정기적인 docker system prune으로 디스크를 관리할 것
  • 로그 확인을 생활화하여 에러에 즉각 대응할 것

오늘의 구축을 마쳤다면, 이제 다음 단계로 나아가 보세요. 단순히 띄워 놓는 것을 넘어, 시스템을 더 단단하게 만드는 과정이 필요해요.

지금 바로 실행해야 할 단계별 과제

  • 오늘 할 일: 현재 운영 중인 서비스를 도커 컴포즈 파일로 정리해 보기
  • 이번 주 할 일: 환경 변수(.env)를 적용하여 보안 설정 강화하기
  • 실행 직전 할 일: 서버 이전 시나리오를 가정하고 데이터 볼륨 백업 테스트하기

구축 절차를 문서로 남겨 두면 다음 서버 이전이나 팀원과의 협업이 훨씬 쉬워집니다. 지금 바로 여러분의 프로젝트 디렉터리에 docker-compose.yml 파일을 만들어 보세요!

더 깊이 있는 도커 활용법이 궁금하다면, 도커 컴포즈 기본 개념 완벽 정리 — 개념부터 실무 활용까지 한눈에 보는 가이드를 함께 읽어보시는 것을 추천해요.

댓글 남기기