콘텐츠로 이동

Docker — 어디서나 똑같이 실행하기

"내 컴퓨터에서는 되는데요?"

개발하면서 자주 겪는 상황입니다.

개발자 A 컴퓨터:  Python 3.11, bcrypt 4.0  → 잘 됨
개발자 B 컴퓨터:  Python 3.9, bcrypt 3.2   → 오류
배포 서버:        Python 3.10, 패키지 없음  → 실행 안 됨

Docker는 이 문제를 해결합니다.

Docker 컨테이너:  OS, Python 버전, 패키지 전부 포함
→ 어느 컴퓨터에서든 완전히 동일한 환경으로 실행

Docker 핵심 개념

이미지 (Image)

실행 환경을 담은 읽기 전용 설계도입니다.

이미지:  python:3.11-slim + fastapi + uvicorn + 소스코드

컨테이너 (Container)

이미지를 실제로 실행한 인스턴스입니다.

이미지        컨테이너
설계도   →   건물
클래스   →   객체 (인스턴스)

같은 이미지로 여러 컨테이너를 실행할 수 있습니다.

Dockerfile

이미지를 만드는 명령 목록입니다.

Dockerfile 작성

# Dockerfile
# 1. 베이스 이미지 선택 (Python 3.11, 용량 작은 slim 버전)
FROM python:3.11-slim

# 2. 작업 디렉토리 설정
WORKDIR /app

# 3. 의존성 먼저 복사 (캐시 활용)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 4. 소스코드 복사
COPY . .

# 5. 포트 노출 (문서 목적)
EXPOSE 8000

# 6. 실행 명령
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

requirements.txt를 먼저 복사하는 이유:
소스코드만 바뀔 때 패키지 설치 단계를 캐시에서 재사용할 수 있습니다.

이미지 빌드 및 실행

# 이미지 빌드
docker build -t myapp .
# -t: 이미지 이름 지정
# .: Dockerfile이 있는 디렉토리

# 컨테이너 실행
docker run -p 8000:8000 myapp
# -p 호스트포트:컨테이너포트

# 백그라운드 실행
docker run -d -p 8000:8000 --name myapp-container myapp

# 실행 중인 컨테이너 목록
docker ps

# 컨테이너 중지
docker stop myapp-container

# 로그 확인
docker logs myapp-container
docker logs -f myapp-container  # 실시간 스트리밍

환경 변수 전달

# 실행 시 환경 변수 전달
docker run -p 8000:8000 \
  -e SECRET_KEY=mysecretkey \
  -e DATABASE_URL=sqlite:///app.db \
  myapp

# .env 파일로 전달
docker run -p 8000:8000 --env-file .env myapp

Docker Compose — 여러 컨테이너 관리

백엔드 서버 + 데이터베이스를 함께 실행할 때 유용합니다.

# docker-compose.yml
version: "3.9"

services:
  api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - SECRET_KEY=${SECRET_KEY}
      - DATABASE_URL=postgresql://postgres:password@db:5432/appdb
    depends_on:
      - db
    volumes:
      - .:/app  # 개발 시 코드 변경 즉시 반영

  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=appdb
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data  # 데이터 영속성

volumes:
  postgres_data:
# 모든 서비스 시작
docker compose up

# 백그라운드 실행
docker compose up -d

# 중지
docker compose down

# 로그 확인
docker compose logs api

.dockerignore

불필요한 파일이 이미지에 포함되지 않도록 합니다.

# .dockerignore
.env
*.db
__pycache__/
.git/
*.pyc
node_modules/

이미지 크기 최적화

# 좋은 예: slim 베이스 이미지 + 불필요한 파일 제외
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY main.py database.py auth.py ./

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
# 이미지 크기 확인
docker images myapp

Docker Hub — 이미지 공유

# Docker Hub에 로그인
docker login

# 이미지 태그 지정
docker tag myapp username/myapp:latest

# 업로드
docker push username/myapp:latest

# 다른 곳에서 받기
docker pull username/myapp:latest

클라우드 서비스(Railway, Render 등)에 이미지를 직접 배포할 때 사용합니다.

개발 환경에서 Docker 활용

# docker-compose.dev.yml — 개발 전용
services:
  api:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app          # 코드 변경이 컨테이너에 즉시 반영
    command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
    env_file:
      - .env

  db:
    image: postgres:15
    ports:
      - "5432:5432"     # 로컬에서 DB 직접 접근 가능
    environment:
      - POSTGRES_DB=appdb
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
docker compose -f docker-compose.dev.yml up

실습 미션

미션 1: Dockerfile 작성

기존 FastAPI 프로젝트에 Dockerfile을 만들고:
1. docker build -t myapp . 로 이미지를 빌드하세요.
2. docker run -p 8000:8000 myapp 으로 실행하세요.
3. http://localhost:8000/docs 에 접속해 확인하세요.

미션 2: 환경 변수 전달

1. SECRET_KEY를 Dockerfile에 하드코딩하지 않고,
   실행 시 -e 옵션으로 전달하세요.
2. SECRET_KEY 없이 실행하면 서버가 오류를 내는지 확인하세요.

미션 3: Docker Compose

docker-compose.yml을 작성해:
1. api 서비스와 postgres 서비스를 함께 실행하세요.
2. docker compose up 하나로 전체 환경이 시작되는지 확인하세요.
3. docker compose down 후 재시작해도 DB 데이터가 유지되는지 확인하세요.

미션 4 (심화): 멀티 스테이지 빌드

Dockerfile을 멀티 스테이지로 개선하세요:
- 빌드 단계: 의존성 설치
- 실행 단계: 최소한의 파일만 포함
이미지 크기가 줄어드는지 확인하세요.

핵심 요약

개념 설명
이미지 실행 환경을 담은 읽기 전용 설계도
컨테이너 이미지를 실행한 인스턴스
Dockerfile 이미지를 만드는 명령 목록
-p 8000:8000 호스트:컨테이너 포트 매핑
Docker Compose 여러 컨테이너를 함께 정의하고 실행
volumes 컨테이너와 호스트 간 파일 공유/영속화
.dockerignore 이미지에서 제외할 파일 목록

Docker는 "실행 환경 자체를 코드로 관리"하는 도구입니다.
팀 전원이 동일한 환경에서 개발하고 배포할 수 있습니다.