30

Core: Dockerfile & docker compose.yml 작성법

Docker 배포 & 테스트

학습 목표

Dockerfile의 각 명령어를 이해한다 docker compose.yml의 구조를 이해한다 볼륨, 네트워크, 환경변수 설정을 할 수 있다

Dockerfile 구조 상세

기본 구조

# Stage 1: 기본 이미지 선택
FROM python:3.12-slim

# Stage 2: 메타데이터
LABEL maintainer="your-email@example.com"
LABEL description="제조 AI 어시스턴트 MVP"

# Stage 3: 시스템 패키지 설치
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Stage 4: 작업 디렉토리
WORKDIR /app

# Stage 5: 의존성 설치 (캐시 활용)
COPY pyproject.toml .
RUN pip install --no-cache-dir .

# Stage 6: 소스 코드 복사
COPY . .

# Stage 7: 포트 노출
EXPOSE 8501

# Stage 8: 헬스체크
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1

# Stage 9: 실행 명령
CMD ["streamlit", "run", "app/main.py", \
     "--server.port=8501", \
     "--server.address=0.0.0.0"]

빌드 최적화 포인트

[빌드 캐시 레이어 전략]

변경 빈도: 낮음 -> 높음 순으로 배치

  FROM python:3.12-slim        # 거의 안 바뀜 (캐시)
  RUN apt-get install ...      # 거의 안 바뀜 (캐시)
  COPY pyproject.toml .        # 의존성 변경 시만 재설치
  RUN pip install .            # 위가 바뀌면 재실행
  COPY . .                     # 코드 변경 시 여기만 재실행

결과: 코드만 수정했을 때 빌드 시간 대폭 감소
  (의존성 설치를 다시 하지 않으니까)

docker compose.yml 구조

services:
  # ---- Streamlit 앱 ----
  app:
    build: .
    ports:
      - "8501:8501"          # 호스트:컨테이너
    environment:
      - OPENAI_API_KEY       # 호스트 환경변수에서 가져옴
      - NEO4J_URI=bolt://neo4j:7687
      - NEO4J_USER=neo4j
      - NEO4J_PASSWORD=mfg-password-2024
    volumes:
      - ./data/documents:/app/data/documents  # 문서 영속화
      - chroma_data:/app/data/chroma_db       # 벡터 DB 영속화
    depends_on:
      neo4j:
        condition: service_healthy
    restart: unless-stopped

  # ---- Neo4j ----
  neo4j:
    image: neo4j:5-community
    ports:
      - "7474:7474"          # 브라우저
      - "7687:7687"          # Bolt
    environment:
      - NEO4J_AUTH=neo4j/mfg-password-2024
      - NEO4J_PLUGINS=["apoc"]
    volumes:
      - neo4j_data:/data
      - neo4j_logs:/logs
    healthcheck:
      test: ["CMD", "cypher-shell", "-u", "neo4j", "-p", "mfg-password-2024", "RETURN 1"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  chroma_data:       # ChromaDB 데이터 영속화
  neo4j_data:        # Neo4j 데이터 영속화
  neo4j_logs:        # Neo4j 로그

핵심 설정 설명

Volumes (데이터 영속화)

volumes:
  - ./data/documents:/app/data/documents  # 바인드 마운트
    # 호스트의 파일과 컨테이너의 파일이 동기화
    # 호스트에서 문서를 추가하면 컨테이너에서도 보임

  - chroma_data:/app/data/chroma_db       # 네임드 볼륨
    # Docker가 관리하는 별도 저장소
    # 컨테이너를 삭제해도 데이터 유지

depends_on + healthcheck

depends_on:
  neo4j:
    condition: service_healthy
    # Neo4j가 완전히 시작된 후에 앱 시작
    # healthcheck가 통과해야 "healthy" 상태

네트워크

# Docker Compose는 자동으로 네트워크를 생성
# 서비스 이름으로 통신 가능

app -> neo4j:7687    # 서비스 이름 = DNS 이름
                      # localhost가 아니라 "neo4j"!
AI로 학습하기 — 꿀팁
🤖제조 AI 앱 Dockerfile 생성AI 학습 팁

AI에게 제조 AI 어시스턴트 Streamlit 앱용 Dockerfile과 docker-compose.yml 완성본을 출력하게 요청하세요.

Streamlit 제조 AI 어시스턴트 앱(Python 3.11, requirements: streamlit langchain neo4j openai python-dotenv)을 위한 Dockerfile과 docker-compose.yml을 작성해줘. 요구사항: (1) .env 파일로 환경변수 주입, (2) 포트 8501 노출, (3) Neo4j 컨테이너도 같이 포함, (4) 각 지시어에 한국어 주석 추가.
이 팁이 도움이 됐나요?
핵심 포인트
  • Dockerfile: FROM -> 의존성 -> 코드 복사 -> CMD
  • 빌드 캐시: 변경 빈도 낮은 것을 위에 배치
  • docker compose.yml: 앱 + Neo4j를 함께 관리
  • volumes: 컨테이너 삭제 시에도 데이터 유지