반응형
Dockerfile 작성 시 주의해야 할 사항과 최적화 방법
Dockerfile은 단순히 컨테이너 이미지를 만드는 도구가 아니라, 배포 속도, 운영 효율성, 유지보수성에 직접적인 영향을 미치는 중요한 요소입니다.
이번 글에서는 Dockerfile을 작성하면서 고려해야 할 핵심 포인트를 정리했습니다.
1. 이미지 용량 최소화
이미지 용량이 커지면 배포 속도가 느려지고, 네트워크 트래픽·스토리지 비용도 증가합니다.
따라서 가벼운 이미지를 만드는 것이 첫 번째 목표입니다.
최적화 방법
- 가벼운 베이스 이미지 선택
풀 패키지 이미지 대신 alpine 버전을 사용해 기본 용량을 최소화합니다.
예: golang:1.16-alpine, python:3.8-slim - 불필요한 파일 제거
설치 중 생성된 패키지 캐시, 로그, 임시 파일 등을 삭제합니다.
예시:
RUN apk add --no-cache git \
&& rm -rf /var/cache/apk/* /tmp/*
- 레이어 수 최소화
RUN, COPY, ENV 등 각 명령은 새로운 레이어를 생성합니다.
가능한 명령을 &&로 묶어 실행해 불필요한 레이어를 줄입니다. - 멀티 스테이지 빌드 활용
빌드 단계(builder)와 실행 단계(runner)를 분리해, 실행 환경에 불필요한 빌드 도구가 포함되지 않도록 합니다.
예시:
FROM golang:1.16-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
# 실행 스테이지
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]
2. dumb-init으로 프로세스 안정성 확보
컨테이너는 기본적으로 PID 1 프로세스가 부모 프로세스로 동작합니다.
단일 프로세스만 실행한다면 문제가 없지만, 여러 자식 프로세스가 생성되는 경우에는 두 가지 문제가 발생합니다.
1) 좀비 프로세스 처리
Docker 컨테이너는 기본 init 시스템이 없기 때문에, 종료된 자식 프로세스를 회수하지 못하면 좀비 프로세스가 쌓입니다.
dumb-init은 경량 init 시스템으로, 자식 프로세스를 자동으로 회수하고 자원을 정리합니다.
2) 시그널 전달
컨테이너가 종료될 때, dumb-init은 부모 프로세스로서 모든 종료 시그널을 자식 프로세스에 전달해 정상 종료를 보장합니다.
예시:
FROM python:3.8-slim
RUN apt-get update && apt-get install -y dumb-init \
&& rm -rf /var/lib/apt/lists/*
COPY . /app
WORKDIR /app
ENTRYPOINT ["dumb-init", "--", "python", "app.py"]
3. ENV와 ARG를 적절히 활용하기
차이점
ARG
- Docker 빌드 시점에만 사용되는 변수
- 이미지 빌드 후에는 값이 유지되지 않음
ENV
- 컨테이너 실행 시점에도 사용되는 환경 변수
- docker run 실행 시 -e 옵션으로 오버라이드 가능
사용 전략
- 빌드 전용 값 → ARG 사용 (예: 빌드 타임 옵션, 컴파일 버전)
- 실행 환경 값 → ENV 사용 (예: 포트, 실행 모드, API 엔드포인트)
이미지를 범용적으로 사용하려면 ARG보다는 ENV를 기본값으로 설정하고,
컨테이너 실행 시 필요한 값만 오버라이드하는 방식을 추천합니다.
이번에 도커라이징을 하면서 느낀 것들은 정리해보았습니다.
이미지는 가벼울수록 좋지만, 안정성과 유지보수성도 함께 고려해야 한다는 것입니다.
- 무조건 작은 이미지보다는 용량·안정성·운영 편의성의 균형을 맞추는 것
- 범용적으로 재사용 가능한 이미지를 설계하는 것
이 두 가지가 실무에서는 특히 중요합니다.
반응형
'DOCKER' 카테고리의 다른 글
| Docker - Bridge 네트워크 사용 (0) | 2019.06.20 |
|---|---|
| Docker registry 구성 (0) | 2019.06.10 |
| Docker Hub 사용하기 (0) | 2019.06.09 |
| Dockerfile 작성방법 (0) | 2019.06.08 |
| Docker 명령어 (0) | 2019.06.05 |
