본문으로 건너뛰기
김신건의 로그

[Container] Image Best Practices: 작게, 안전하게

· 수정 · 📖 약 1분 · 308자/단어 #container #docker #security #best-practices #cloud
distroless, scratch, image scan, Trivy, SBOM, multi-stage build, non-root user, secret 처리

5가지 원칙

flowchart TB
    Q[Image Best Practices]
    Q --> Small[1. 작게]
    Q --> Sec[2. 안전하게]
    Q --> Cache[3. Layer cache 활용]
    Q --> Repro[4. Reproducible]
    Q --> Sign[5. Sign + Scan]

1. Base Image 선택

Base크기적합
ubuntu:24.04~70 MB개발 / 디버깅 친화
debian:12-slim~40 MB일반
alpine:3.20~5 MB작음, musl libc (glibc 의존성 주의)
distroless/static~2 MBGo / Rust 정적 binary
distroless/nodejs22~150 MBNode, 안전
distroless/java21~200 MBJava
scratch0정적 binary 만

Distroless = shell / package manager 없음. 공격 면 감소. Google 권장.

2. Multi-stage build

FROM golang:1.23 AS builder
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/server

FROM gcr.io/distroless/static:nonroot
COPY --from=builder /app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]

최종 image 에 빌드 도구 없음. 수십 MB → 수 MB.

3. Layer Cache

# ❌ 모든 코드 복사 후 install
COPY . .
RUN npm ci

# ✅ 의존성 파일만 먼저
COPY package*.json ./
RUN npm ci
COPY . .

코드 변경npm ci layer 캐시 활용. 빌드 시간 수배 단축.

4. Non-root User

RUN addgroup -g 1000 app && adduser -D -u 1000 -G app app
USER 1000:1000

또는 distroless 의 :nonroot.

5. Secret 처리

# BuildKit secret (image layer 에 안 남음)
RUN --mount=type=secret,id=npmrc cp /run/secrets/npmrc ~/.npmrc \
    && npm ci
docker buildx build --secret id=npmrc,src=$HOME/.npmrc .

CAUTION

ARG / ENV 로 secret 전달 절대 금지. layer 에 영구 남음.

6. .dockerignore

node_modules
.git
.env
**/*.log
.DS_Store
dist
coverage

7. HEALTHCHECK

HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

K8s 에서는 Liveness/Readiness probe 가 우선이지만 docker run 환경에서는 HEALTHCHECK 가 유용.

8. Image Scan

trivy image myapp:1.0
# CVE 검사

cosign sign myapp:1.0
cosign verify myapp:1.0
# 서명 + 검증

syft myapp:1.0 -o spdx-json > sbom.json
# SBOM 생성
도구용도
TrivyCVE / misconfig scan
GrypeCVE scan
Cosign서명 + verify
SyftSBOM 생성
Notaryimage trust

9. Reproducible Build

ARG BUILD_DATE
ARG GIT_SHA
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.revision=$GIT_SHA

같은 입력 → 같은 output. supply chain security 의 토대.

흔한 함정

WARNING

  1. apt install ... && apt clean 한 줄로 = layer 작아짐. 별도 RUN 이면 clean 효과 없음.
  2. COPY . /app = .dockerignore 없으면 .git, node_modules 까지.
  3. latest tag = build 마다 다른 결과.
  4. root 사용자 + privileged = 컨테이너 의미 없음.

관련 위키

이 글의 용어 (5개)
[AWS] Secrets Manager + Parameter Storecloud
정의 | | Secrets Manager | Parameter Store (SSM) | |---|---|---| | 가격 | $0.40/secret/월 + $0.05/10k AP…
[Container] cgroups + namespaces: 컨테이너의 두 기둥virtualization
정의 컨테이너 = namespaces + cgroups + 파일시스템 (overlay). VM 이 아니라 host 의 프로세스 + 격리. Namespaces (격리) | Name…
[Container] Docker: image, layer, registryvirtualization
정의 Docker = 컨테이너 빌드 + 실행 + 배포 의 표준 도구. 2013 출시 → 컨테이너 시대 의 시작. 현재는 OCI 표준 으로 진화 ( , , 등 호환). Layere…
[Container] OCI Image: spec, manifest, layer 표준cloud
정의 OCI (Open Container Initiative) = 컨테이너 표준 (Linux Foundation, 2015). image format + runtime + dis…
[K8s] Pod: 컨테이너의 최소 단위, sidecar, lifecyclekubernetes
정의 Pod = K8s 의 가장 작은 배포 단위. 1개 이상의 컨테이너 + 공유 네트워크 + 공유 스토리지. [!IMPORTANT] Pod 는 컨테이너의 wrapping 이 아니…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기