DockerDocker 기초 · 2기초

Dockerfile 작성 — 내 앱을 이미지로 만들기

DockerDockerfile이미지빌드멀티스테이지최적화

Dockerfile 기본 명령어

FROM node:20-slim          # 베이스 이미지
WORKDIR /app               # 작업 디렉토리
COPY package*.json ./      # 파일 복사
RUN npm install            # 명령 실행 (이미지 빌드 시)
COPY . .                   # 소스 코드 복사
EXPOSE 3000                # 포트 문서화 (실제 열지는 않음)
CMD ["node", "server.js"]  # 컨테이너 시작 시 실행

Node.js 앱 Dockerfile

# Dockerfile
FROM node:20-slim

WORKDIR /app

# 의존성 먼저 복사 (캐싱 최적화)
COPY package*.json ./
RUN npm ci --only=production

# 소스 복사
COPY . .

EXPOSE 3000

CMD ["node", "src/index.js"]
# 이미지 빌드
docker build -t my-node-app .
docker build -t my-node-app:1.0.0 .

# 실행
docker run -d -p 3000:3000 --name app my-node-app
curl http://localhost:3000

Python 앱 Dockerfile

FROM python:3.12-slim

WORKDIR /app

# 의존성 먼저
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

레이어 캐싱 원리

flowchart TB
    subgraph CACHE["레이어 캐싱"]
        L1["FROM node:20-slim\n(변경 없음 → 캐시 사용)"]
        L2["COPY package*.json\n(변경 없음 → 캐시 사용)"]
        L3["RUN npm install\n(변경 없음 → 캐시 사용)"]
        L4["COPY . .\n(소스 변경 → 재실행)"]
        L5["CMD ..."]
    end
    L1 --> L2 --> L3 --> L4 --> L5

자주 변경되는 것을 Dockerfile 아래쪽에 배치하면 빌드가 빨라집니다.

# ❌ 소스 먼저 복사하면 npm install 캐시가 매번 깨짐
COPY . .
RUN npm install

# ✅ package.json 먼저 → 소스 나중
COPY package*.json ./
RUN npm install
COPY . .

.dockerignore

불필요한 파일을 빌드 컨텍스트에서 제외합니다.

node_modules
.git
.env
*.log
dist
.next
__pycache__
*.pyc

멀티스테이지 빌드

빌드 도구는 최종 이미지에 포함하지 않아 크기를 줄입니다.

# Stage 1: 빌드
FROM node:20 AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build  # TypeScript 컴파일 등

# Stage 2: 프로덕션 (node_modules, 빌드 도구 없음)
FROM node:20-slim AS production

WORKDIR /app

# 빌드 결과만 복사
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./

EXPOSE 3000
CMD ["node", "dist/index.js"]
# 이미지 크기 비교
docker images
# REPOSITORY       SIZE
# my-app:single    800MB  ← 빌드 도구 포함
# my-app:multi     150MB  ← 멀티스테이지

환경 변수

# Dockerfile에서
ENV NODE_ENV=production
ENV PORT=3000

# 빌드 시 ARG (빌드 전용)
ARG APP_VERSION=1.0.0
RUN echo "Building version ${APP_VERSION}"
# 실행 시 -e 또는 --env-file
docker run -e DATABASE_URL=postgres://... my-app
docker run --env-file .env my-app

정리

명령역할
FROM베이스 이미지
WORKDIR작업 디렉토리
COPY파일 복사
RUN빌드 시 명령 실행
CMD컨테이너 시작 명령
EXPOSE포트 문서화
ENV환경 변수
ARG빌드 인자

다음 편에서는 Docker Compose — 여러 컨테이너를 함께 관리하는 방법을 배웁니다.

궁금한 점이 있으신가요?

협업·의뢰는 아래로, 가벼운 소통은 인스타그램 @bluefox._.hi도 환영이에요.