🔧 DevOps

Dockerfile

도커파일

Docker 이미지를 빌드하는 스크립트. FROM, RUN, COPY 등 명령어로 구성.

상세 설명

Dockerfile은 Docker 이미지를 빌드하기 위한 텍스트 기반 스크립트입니다. 베이스 이미지 선택부터 의존성 설치, 애플리케이션 복사, 실행 명령어까지 컨테이너 환경을 코드로 정의합니다. "Infrastructure as Code"의 가장 기본적인 형태라 할 수 있습니다.

Dockerfile의 각 명령어(FROM, RUN, COPY 등)는 이미지의 새로운 레이어를 생성합니다. 레이어는 캐시되므로, 자주 변경되는 명령어를 아래쪽에 배치하면 빌드 시간을 크게 줄일 수 있습니다. 예를 들어, package.json만 먼저 복사해서 npm install 하면 코드 변경 시 의존성 캐시를 재사용합니다.

멀티스테이지 빌드는 최적화된 프로덕션 이미지를 만드는 핵심 기법입니다. 빌드 스테이지에서는 컴파일러와 개발 도구를 사용하고, 최종 스테이지에서는 실행 바이너리만 복사하여 이미지 크기를 수십 MB로 줄일 수 있습니다.

보안을 위해 non-root 사용자로 실행하고, .dockerignore로 불필요한 파일을 제외하며, 특정 버전의 베이스 이미지를 사용하는 것이 좋습니다. latest 태그는 재현성을 떨어뜨리므로 프로덕션에서는 지양합니다.

코드 예제

# 멀티스테이지 빌드 - Node.js 애플리케이션
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app

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

# 소스 코드 복사 및 빌드
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:20-alpine AS production
WORKDIR /app

# 보안: non-root 사용자 생성
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001

# 빌드 결과물만 복사
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./

# non-root 사용자로 실행
USER nextjs

# 헬스체크
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

EXPOSE 3000
CMD ["node", "dist/main.js"]

실무에서 이렇게 말해요

시니어: "이미지 크기가 1.2GB인데 너무 커. 멀티스테이지 빌드로 줄여보자."

주니어: "alpine 베이스 이미지 쓰고, devDependencies 빼면 될까요?"

시니어: "그것도 좋고, distroless 이미지 써보는 것도 고려해봐. 보안에도 좋아."

면접관: "Dockerfile 빌드 속도를 최적화하는 방법을 설명해주세요."

지원자: "레이어 캐시를 활용합니다. 자주 변경되지 않는 의존성 설치를 먼저 하고, 소스 코드 복사를 나중에 합니다. 또한 .dockerignore로 불필요한 파일을 제외하고, BuildKit의 병렬 빌드 기능을 활용합니다."

리뷰어: "FROM node:latest 대신 특정 버전 명시해주세요. 그리고 RUN 명령어 여러 개를 && 로 합치면 레이어 수가 줄어요."

개발자: "아, root로 실행되고 있네요. USER 명령어로 non-root 사용자 추가하겠습니다."

주의사항

더 배우기