본문 바로가기
컴퓨터 활용(한글, 오피스 등)/기타

Dockerfile 동작 원리

by 3604 2026. 8. 12.
728x90

 

Dockerfile은 Docker 이미지를 빌드하기 위한 명령어 스크립트입니다. 마치 요리 레시피처럼, 어떤 기반 이미지를 사용할지, 어떤 파일을 복사할지, 어떤 명령을 실행할지 등을 정의합니다.

1. Dockerfile 기본 구조

dockerfile
# 1. 베이스 이미지 지정 (FROM)
FROM ubuntu:22.04

# 2. 메타데이터 설정 (LABEL)
LABEL maintainer="your@email.com"

# 3. 환경 변수 설정 (ENV)
ENV DEBIAN_FRONTEND=noninteractive

# 4. 시스템 패키지 설치 (RUN)
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip

# 5. 작업 디렉토리 설정 (WORKDIR)
WORKDIR /app

# 6. 로컬 파일 복사 (COPY)
COPY requirements.txt .
COPY src/ ./src/

# 7. 의존성 설치 (RUN)
RUN pip3 install -r requirements.txt

# 8. 포트 노출 (EXPOSE)
EXPOSE 8080

# 9. 컨테이너 시작 명령어 (CMD / ENTRYPOINT)
CMD ["python3", "src/app.py"]

2. 레이어(Layer) 기반 아키텍처

Dockerfile의 각 명령어는 이미지 레이어를 생성합니다.

text
이미지 구조 (예시)
┌─────────────────────┐
│  CMD ["python3"]    │  <- 레이어 5
├─────────────────────┤
│  RUN pip install    │  <- 레이어 4
├─────────────────────┤
│  COPY src/          │  <- 레이어 3
├─────────────────────┤
│  RUN apt-get install│  <- 레이어 2
├─────────────────────┤
│  FROM ubuntu:22.04  │  <- 레이어 1 (베이스)
└─────────────────────┘

레이어의 특징

  1. 캐싱: 변경되지 않은 레이어는 재사용됨 → 빌드 속도 향상
  2. 재사용: 여러 이미지가 동일한 레이어를 공유 가능
  3. 불변성: 한 번 생성된 레이어는 수정 불가

3. 주요 명령어 상세

🔹 FROM

dockerfile
FROM node:18-alpine    # 베이스 이미지 지정
FROM python:3.11-slim  # 여러 FROM 가능 (멀티스테이지 빌드)

🔹 RUN

dockerfile
# shell form (기본)
RUN apt-get update && apt-get install -y curl

# exec form (권장)
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "curl"]

🔹 COPY vs ADD

dockerfile
# COPY: 로컬 파일/디렉토리 복사
COPY package.json /app/
COPY . /app/

# ADD: COPY + URL 다운로드 + 압축 해제
ADD https://example.com/file.tar.gz /tmp/
ADD archive.tar.gz /app/    # 자동 압축 해제

🔹 WORKDIR

dockerfile
WORKDIR /app                # 이후 명령어의 작업 디렉토리 설정
RUN pwd                    # /app 출력
WORKDIR src
RUN pwd                    # /app/src 출력

🔹 ENV

dockerfile
ENV NODE_ENV=production
ENV PORT=3000
ENV DATABASE_URL=postgres://user:pass@db:5432/db

🔹 EXPOSE

dockerfile
EXPOSE 8080               # 문서화 목적 (실제 포트 매핑은 docker run -p)
EXPOSE 80/tcp 443/udp    # 프로토콜 지정 가능

🔹 CMD vs ENTRYPOINT

 
구분CMDENTRYPOINT
용도 기본 실행 명령 고정 실행 명령
오버라이드 docker run 시 쉽게 변경 가능 --entrypoint로만 변경 가능
함께 사용 ENTRYPOINT의 인자로 전달 CMD를 인자로 받음
dockerfile
# 예제 1: CMD만 사용
CMD ["python3", "app.py"]
# docker run 이미지 python3 app.py
# docker run 이미지 python3 server.py  (오버라이드)

# 예제 2: ENTRYPOINT + CMD
ENTRYPOINT ["python3"]
CMD ["app.py"]
# docker run 이미지 app.py
# docker run 이미지 server.py  (CMD 오버라이드)

4. 빌드 과정

빌드 명령어

bash
# 기본 빌드
docker build -t my-app:latest .

# 컨텍스트 지정
docker build -f Dockerfile.prod -t my-app:prod ./path

# 빌드 인자 전달
docker build --build-arg VERSION=1.0 -t my-app .

빌드 흐름

text
1. Docker 클라이언트가 Dockerfile 읽기
2. 베이스 이미지 다운로드 (FROM)
3. 각 명령어 실행 → 레이어 생성
4. 레이어 캐시 확인 (변경된 부분부터 다시 빌드)
5. 최종 이미지 생성

5. 멀티스테이지 빌드 (Multi-stage Build)

하나의 Dockerfile에서 여러 FROM을 사용하여 빌드 환경과 실행 환경을 분리합니다.

dockerfile
# Stage 1: 빌드 스테이지
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp main.go

# Stage 2: 실행 스테이지 (더 작은 이미지)
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]

장점

  • 최종 이미지 크기 감소 (빌드 도구 제외)
  • 보안 강화 (불필요한 패키지 제거)
  • 빌드 캐시 최적화

6. Dockerfile 최적화 팁

✅ 캐시 활용하기

dockerfile
# BAD: 자주 변경되는 코드가 먼저 오면 캐시 무효화
COPY . .
RUN pip install -r requirements.txt

# GOOD: 변경이 적은 파일 먼저 복사
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

✅ 레이어 수 줄이기

dockerfile
# BAD: 여러 RUN 명령어 → 레이어 증가
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean

# GOOD: 하나의 RUN으로 합치기
RUN apt-get update && \
    apt-get install -y curl && \
    apt-get clean

✅ .dockerignore 사용

dockerfile
# .dockerignore
node_modules/
.git/
*.log
.env
Dockerfile
.dockerignore

✅ 불필요한 패키지 제거

dockerfile
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

7. 당신의 RAG 앱 Dockerfile 예상 구조

dockerfile
# 멀티스테이지 빌드 예시
FROM rust:1.75 AS builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
RUN cargo fetch
COPY src/ ./src/
RUN cargo build --release --features ssr

FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /app/target/release/my-rag-app .
EXPOSE 3000
CMD ["./my-rag-app"]

8. 실행 과정 요약

 
 
  1. Dockerfile 작성
  2. docker build → 이미지 생성 (레이어 캐싱 활용)
  3. docker run → 컨테이너 실행 (이미지의 레이어를 합쳐서 실행 환경 구성)
  4. 컨테이너에서 애플리케이션 실행

9. 문제 해결: 이미지 빌드 실패 시

bash
# 1. 빌드 로그 확인
docker build --progress=plain -t my-app .

# 2. 캐시 무시하고 재빌드
docker build --no-cache -t my-app .

# 3. 특정 단계까지 빌드
docker build --target builder -t my-app-builder .

# 4. 빌드 인자 확인
docker build --build-arg DEBUG=true -t my-app .

Dockerfile은 이렇게 코드 인프라(IaC)의 핵심 도구로, 애플리케이션을 어디서나 동일하게 실행할 수 있게 해줍니다.

728x90