codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
노트›infra

Docker 기초

2026-04-28 게시· 2026-05-18 갱신·0회 조회

Docker 기초

컨테이너는 운영체제 위에 격리된 사용자 공간을 띄워 같은 모습의 애플리케이션을 어디서든 돌리는 길. Docker 는 이 컨테이너를 표준 도구로 묶어 대중화한 결정적 계기. 이 글은 Docker 의 출자 · 이미지 / 컨테이너 / 레이어 / 볼륨 / 네트워크 같은 기본 개념 · Dockerfile 핵심 명령 · 멀티스테이지 빌드 · BuildKit · 이웃 도구를 정리합니다.

1. Docker 에 대한 이야기

사건 시기
dotCloud 가 내부 도구로 출발 (Solomon Hykes 등) 2008–2013
Docker 오픈소스 공개 (PyCon 2013) 2013-03
Docker 0.9 — libcontainer 도입 (LXC 의존 제거) 2014
Docker 1.0 2014-06
OCI (Open Container Initiative) 발족 — Linux Foundation 2015
Multi-stage build (Dockerfile) Docker 17.05 / 2017
BuildKit 안정화 2018
Docker Desktop 라이선스 변경 (대기업 유료) 2021

OCI 가 표준화한 두 사양 — 이미지 사양 과 런타임 사양 — 덕분에 Docker 외 런타임 (containerd · CRI-O · Podman) 이 같은 이미지를 다룹니다.

2. 핵심 어휘

용어 의미
이미지 실행 가능한 파일시스템 스냅샷 + 메타데이터. 불변.
컨테이너 이미지에서 띄운 프로세스 격리 단위. 변경은 위쪽 레이어에.
레이어 이미지의 변경 단위. 캐시·재사용 단위.
볼륨 컨테이너 외부 데이터 영속화.
네트워크 컨테이너 간 통신 경계 (bridge · host · overlay).
레지스트리 이미지 저장소 (Docker Hub · ghcr.io · ECR).

3. 이미지와 레이어

Dockerfile 의 각 명령 (RUN · COPY · ADD) 이 하나의 레이어. 같은 명령 + 같은 입력이면 캐시 재사용. 레이어 순서를 잘 짜는 것이 빌드 시간의 큰 차이를 만듭니다.

FROM node:22-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci          # 의존만 변하면 여기서 캐시 무효화
COPY . .            # 소스만 변할 때는 위 레이어 재사용
CMD ["node", "server.js"]

4. Dockerfile 핵심 명령

명령 역할
FROM 베이스 이미지. 멀티스테이지에서는 여러 번.
WORKDIR 이후 명령의 현재 디렉터리.
COPY / ADD 파일 복사. ADD 는 URL · tar 자동 해제. 보통 COPY 권장.
RUN 빌드 시 실행. 셸 모드 vs exec 모드.
ENV 환경변수. 이미지에 고정.
EXPOSE 메타데이터 (문서화). 실제 포트 매핑은 런타임.
CMD 기본 실행 명령.
ENTRYPOINT 컨테이너의 진입점. CMD 와 결합 가능.

CMD 는 기본 인자, ENTRYPOINT 는 고정 명령. 두 가지 결합 — ENTRYPOINT ["node"] CMD ["server.js"] 처럼 쓰면 인자만 바꿔 끼울 수 있음.

5. 멀티스테이지 빌드

빌드 단계와 런타임 단계를 분리해 최종 이미지를 가볍게.

FROM node:22 AS build
WORKDIR /src
COPY . .
RUN npm ci && npm run build

FROM node:22-slim
WORKDIR /app
COPY --from=build /src/dist ./dist
COPY --from=build /src/node_modules ./node_modules
CMD ["node", "dist/server.js"]

빌드 도구 · 소스 · 테스트 산출물이 최종 이미지에 들어가지 않습니다.

6. BuildKit

빌드 엔진 재작성으로, 병렬 실행 · 캐시 마운트 · secret 마운트 제공.

# syntax=docker/dockerfile:1.7
RUN --mount=type=cache,target=/root/.npm \
    npm ci
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
    npm publish

docker buildx 는 BuildKit 위에서 멀티 아키텍처 (arm64 / amd64) 빌드, 원격 빌더 같은 기능을 제공.

7. 다른 도구

도구 메모
Podman Red Hat 주도. 데몬 없는 모델. Docker CLI 호환.
containerd Docker 가 분리해 CNCF 에 기증한 런타임. Kubernetes 가 표준 채택.
nerdctl containerd 의 Docker 호환 CLI.
LXC · LXD 리눅스 컨테이너의 오래된 형태. 시스템 컨테이너 강조.
Buildah Podman 진영의 빌더. Dockerfile 없이도 가능.

8. 베이스 이미지 선택지

  • alpine — 크기가 작음 (수 MB). musl libc. 일부 glibc 기반 바이너리와 호환 문제가 자주.
  • distroless (Google) — OS 도구 없이 런타임만. 보안 표면 축소.
  • scratch — 완전히 빈 이미지. 정적 바이너리 (예: Go) 에 어울림.
  • slim 변형 (debian:slim · node:slim) — 균형점.

9. 자주 쓰는 모양

.dockerignore — .gitignore 와 비슷. 빌드 컨텍스트 축소로 빌드 시간 · 이미지 크기 감소.

node_modules
.git
*.log
.env*

비루트 사용자 — 컨테이너 내부 root 권한 노출 축소:

RUN useradd -m -u 10001 app
USER app

헬스체크 — 오케스트레이터 (compose · k8s) 가 기동 · 재시작 판단에 활용:

HEALTHCHECK --interval=30s --timeout=3s CMD curl -fsS http://localhost:8080/health || exit 1

스택별 runtime 슬림화 — 빌드 도구가 runtime 에 남는 게 가장 흔한 비대화 원인. 언어별 표준 단편:

  • Next.js (Node) — next.config.ts 의 output: 'standalone'. runner stage 는 .next/standalone + .next/static + public/ 만 COPY. node server.js 로 실행. node_modules 통째 복사 대비 60~80% 축소.
  • FastAPI (Python) — builder/runtime 2-stage. psycopg2-binary 쓰면 gcc/libpq-dev 가 runtime 에 불필요. Playwright 브라우저(chromium) 는 builder 에서 다운로드 후 runtime 으로 복사하고, 시스템 라이브러리(libnss3 등) 만 runtime 에서 playwright install-deps.
  • Spring Boot (Java) — JDK builder → JRE runner 2-stage. Boot 4 의 extract --layers 는 표준 4 디렉터리 추출이 깨져있음 — 단일 jar COPY *.jar app.jar + ENTRYPOINT ["java", "-jar", "app.jar"] 가 안전.

apt 패키지는 정말 runtime 에서 쓰이는지 코드 (subprocess/spawn) 추적. Node 진영에서 gzip 같은 CLI 는 보통 zlib.createGzip 으로 대체 가능 — 패키지 자체 제거.

10. 자주 걸리는 자리

COPY . . 의 캐시 무효화 — 소스 한 번 바뀌면 의존 설치 단계까지 다시 돌음. 의존 파일을 먼저 복사하는 순서가 정석.

컨테이너 안의 1번 프로세스 시그널 처리 — npm start 같은 래퍼는 SIGTERM 을 자식에게 잘 전달 못 할 수 있음. exec 모드 (CMD ["node", "server.js"]) 또는 tini.

이미지 크기 — node_modules · 빌드 캐시 · OS 패키지 잔재. 멀티스테이지 + slim / distroless 베이스로 큰 차이.

Windows 와 Linux 컨테이너 혼동 — Docker Desktop 의 모드 전환에 따라 베이스 이미지의 OS 가 달라짐. Windows 에서는 daemon.json · WSL2 백엔드 설정 확인.

latest 태그 — 재현 가능성이 깨짐. 명시적 버전 태그 · digest 핀 권장.

같은 태그로 재빌드 시 dangling <none> 이미지 누적 — 동일 태그 (myapp:dev) 로 새 빌드를 돌리면 이전 이미지가 untag 되어 dangling 으로 남음. 정상 메커니즘이지만 자동 정리가 없으면 디스크가 빠르게 찬다. CI 스크립트 종료 시 docker image prune -f 한 줄로 누적 차단. WSL2 백엔드는 sparse VHDX 라 docker prune 만으로는 호스트 디스크 회수 안 됨 — Optimize-VHD -Mode Full 또는 diskpart compact vdisk 까지 돌려야 실제 환원.

하고픈 말

Docker 는 컨테이너의 표준 도구이자 출발점입니다. 멀티스테이지 + BuildKit 캐시 마운트 + .dockerignore 셋이 함께 있을 때 빌드 시간 · 이미지 크기 · 재현 가능성 세 자리가 모두 좋아집니다. latest 태그를 피하고 명시적 버전 핀.

Next

  • docker-compose-patterns
  • caddy-not-nginx

Docker 공식 문서 · Dockerfile 레퍼런스 · BuildKit · OCI Image Spec · OCI Runtime Spec · Podman · Distroless 를 참고합니다.

infra 카테고리의 다른 글

카테고리 전체 보기 →
  • 클라우드 에뮬레이터 스택 — 4번째 환경의 설계
  • 로컬 HTTPS — mkcert 와 자체 CA
  • 단일 서버 운영의 자리
  • 루프백 바인딩과 SSH 터널
  • Caddy 와 nginx — 비교의 자리
  • Docker Compose 패턴