topic난이도 · 약 25

Docker — 컨테이너·이미지·Dockerfile

"내 컴퓨터에서는 됐는데"의 해독제 — 앱과 의존성을 하나로 포장.

#Docker#컨테이너#이미지#Dockerfile#멀티스테이지
왜 배우는가

Claude가 Dockerfile을 만들어도 멀티 스테이지·layer 캐시·슬림 베이스를 모르면 이미지가 거대해지고 빌드가 느려진다. 핵심 3개만 알면 최적화 지시 가능.

컨테이너는 '경량 가상머신'. 전체 OS 대신 커널은 호스트와 공유, 유저 공간만 격리. VM 대비 시작 속도 수십 배, 메모리는 1/10 수준. Docker가 대중화의 주역.

구분VM컨테이너
시작 시간수 분수 초
메모리GBMB
격리 수준하드웨어 가상화OS 네임스페이스+cgroup
이미지 크기수 GB수 MB~수백 MB
호스트 OS 공유✅ (Linux 커널)

핵심 3개념. 이미지(Image) = 앱 + 의존성 + 런타임을 묶은 읽기 전용 템플릿. 컨테이너(Container) = 이미지를 실행한 프로세스. Dockerfile = 이미지를 만드는 설명서.

dockerfile
# ❌ 나쁜 Dockerfile — 이미지 1GB+, 캐시 안 됨
FROM node:20
COPY . /app
WORKDIR /app
RUN npm install
CMD ["node", "server.js"]

# ✅ 좋은 Dockerfile — 멀티스테이지 + 캐시 + 슬림

# Stage 1: 빌드 (큰 이미지)
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci                    # 이 층은 package.json 변할 때만 재실행
COPY . .
RUN npm run build             # Next.js/Vite/TSC 빌드

# Stage 2: 실행 (슬림 이미지)
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
RUN npm ci --omit=dev         # 운영 의존성만
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public

EXPOSE 3000
USER node                     # root 금지(보안)
CMD ["node", "server.js"]

멀티 스테이지 = 빌드 도구(큰 이미지)와 런타임(슬림)을 분리. 최종 이미지에 `node_modules/@types`·`.next/cache` 같은 건 안 들어감.

Layer 캐시 최적화. Dockerfile의 각 줄은 층(layer)이 되고, 상위 층이 안 변하면 재빌드 생략. `package.json` 먼저 COPY → `npm ci` → 그다음 소스 COPY 순서가 핵심. 소스만 바뀔 때 `npm ci`를 다시 돌리지 않는다.

bash
# 자주 쓰는 명령
docker build -t myapp:1.0 .                  # 이미지 빌드
docker run -p 3000:3000 -e DATABASE_URL=... myapp:1.0  # 실행
docker ps                                    # 실행 중 컨테이너
docker logs -f <container>                   # 로그 스트림
docker exec -it <container> sh               # 접속 (디버깅)

# 이미지 크기 다이어트
docker images                                # 크기 확인
# node:20 = 1GB,  node:20-alpine = 170MB,  node:20-slim = 250MB
# 빌드된 Next.js 앱 기준 150MB 이하로 줄이는 것이 목표

# Docker Compose — 여러 컨테이너 함께
# docker-compose.yml (postgres + redis + 내 앱)
docker-compose up -d

Docker Compose 한 파일로 로컬에 Postgres + Redis + 앱을 동시에 띄움 → "Dev/Prod Parity"(12F #10) 실천.

보안 체크 3개. ① `USER` 지정(root 금지) ② 비밀번호·토큰은 Docker secrets(Compose)·런타임 env로, 이미지에 굽지 말 것 ③ 베이스 이미지는 정기 업데이트(`docker scan`·trivy). AI가 Dockerfile 만들 때 이 셋을 자주 빼먹는다.

실기 드릴 2문항
edit실기 드릴 · 단답형

Docker 이미지를 빌드용·런타임용으로 분리해 최종 크기를 줄이는 기법은?

check_circle실기 드릴 · OX

컨테이너는 가상머신과 달리 호스트 OS의 커널을 공유한다.