Dockerfile
2026.10.01 · 15분
1. Dockerfile이란?
Dockerfile은 Docker Image를 만드는 방법을 적어 둔 텍스트 파일입니다.
어떤 OS 위에서, 어떤 파일을 복사하고, 어떤 명령을 실행하고, 마지막에 무엇을 실행할지를 순서대로 적습니다.
Dockerfile ──(docker build)──> Image ──(docker run)──> Container
설계도 완성품 실행 중인 프로그램요리로 비유하면 Dockerfile은 레시피입니다. 레시피만 있으면 누가 어디서 만들어도 같은 요리가 나옵니다.
2. 기본 예시
Node.js 애플리케이션을 예로 들어 보겠습니다.
FROM node:22
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]위에서 아래로 한 줄씩 실행되며, 각 줄을 명령어(instruction)라고 부릅니다.
1. node:22 Image에서 시작한다
2. 작업 디렉터리를 /app으로 정한다
3. package.json을 복사하고 의존성을 설치한다
4. 나머지 소스 코드를 복사한다
5. 3000번 포트를 쓴다고 표시한다
6. Container가 시작되면 npm start를 실행한다3. 이미지 빌드하기
docker build -t my-app:1.0 .| 부분 | 의미 |
|---|---|
-t my-app:1.0 | 만들어질 Image의 이름과 태그 |
. | 빌드 컨텍스트(build context) 경로 |
빌드 컨텍스트
마지막의 .은 "현재 디렉터리의 파일을 Docker에게 넘긴다"는 뜻입니다.
COPY는 이 빌드 컨텍스트 안의 파일만 복사할 수 있습니다. 컨텍스트 밖의 파일(../config 같은 경로)은 복사할 수 없습니다.
my-project/ ← 빌드 컨텍스트
├── Dockerfile
├── package.json
└── src/다른 이름의 Dockerfile을 쓰려면 -f 옵션을 씁니다.
docker build -f Dockerfile.dev -t my-app:dev .4. 주요 명령어
FROM
어떤 Image에서 시작할지 정합니다. 보통 Dockerfile의 첫 줄에 옵니다.
FROM node:22-alpinealpine, slim처럼 크기가 작은 버전을 고르면 Image 크기를 줄일 수 있습니다.
WORKDIR
이후 명령어가 실행될 작업 디렉터리를 정합니다. 디렉터리가 없으면 만들어 줍니다.
WORKDIR /appRUN cd /app은 그 줄에서만 효과가 있으므로, 디렉터리 이동은 WORKDIR로 합니다.
COPY
빌드 컨텍스트의 파일을 Image 안으로 복사합니다.
COPY package.json ./
COPY src/ ./src/비슷한 명령어로 ADD가 있습니다. ADD는 압축 파일 자동 해제, URL 다운로드 같은 기능이 더 있지만, 단순 복사라면 동작이 명확한 COPY를 씁니다.
RUN
Image를 만드는 빌드 시점에 명령을 실행합니다. 패키지 설치에 주로 씁니다.
RUN npm install
RUN apt-get update && apt-get install -y curlENV
환경 변수를 설정합니다. 빌드 중에도, Container 실행 중에도 남아 있습니다.
ENV NODE_ENV=productionARG
빌드할 때만 쓰는 변수입니다. Container 실행 시에는 남지 않습니다.
ARG NODE_VERSION=22
FROM node:${NODE_VERSION}docker build --build-arg NODE_VERSION=20 -t my-app .5. 레이어와 캐시
Dockerfile의 명령어(RUN, COPY, ADD)는 각각 하나의 레이어를 만듭니다. Docker는 레이어를 캐시해 두고, 바뀌지 않은 부분은 다시 실행하지 않습니다.
어떤 레이어가 바뀌면 그 아래 레이어는 모두 다시 빌드됩니다.
나쁜 순서
COPY . .
RUN npm install소스 코드 한 줄만 고쳐도 COPY . .가 바뀌므로 npm install이 매번 다시 실행됩니다.
좋은 순서
COPY package*.json ./
RUN npm install
COPY . .package.json 그대로 → npm install 캐시 사용 (빠름)
소스 코드만 변경 → 마지막 COPY만 다시 실행원칙은 자주 바뀌지 않는 것을 위에, 자주 바뀌는 것을 아래에 두는 것입니다.
RUN 합치기
RUN apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*설치와 정리를 한 RUN에서 해야 정리한 파일이 Image에 남지 않습니다. 다른 RUN에서 지우면 앞 레이어에 파일이 그대로 남아 Image 크기가 줄지 않습니다.
6. .dockerignore
빌드 컨텍스트에서 제외할 파일을 적습니다. 문법은 .gitignore와 비슷합니다.
node_modules
.git
.env
*.log
dist- 빌드 컨텍스트가 작아져 빌드가 빨라집니다.
.env같은 비밀 파일이COPY . .로 Image에 들어가는 것을 막습니다.- 로컬의
node_modules가 Container 안에서 설치한 것을 덮어쓰지 않습니다.
7. 멀티 스테이지 빌드
빌드에 필요한 도구와 실행에 필요한 파일은 다릅니다. 멀티 스테이지 빌드는 빌드 단계와 실행 단계를 나눠 최종 Image에는 실행에 필요한 것만 남깁니다.
하나의 파일, 여러 개의 FROM
단계별로 파일을 나누지 않습니다. 하나의 Dockerfile 안에 FROM을 여러 번 쓰고, FROM이 나올 때마다 새 단계(stage)가 시작됩니다. 빌드도 평소처럼 docker build 한 번이면 됩니다.
# 1단계: 빌드
FROM node:22 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 2단계: 실행
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --omit=dev
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/main.js"]builder 단계: 소스 코드, devDependencies, 빌드 도구 → 버려짐
최종 단계: dist 결과물, 운영 의존성만 → 최종 ImageCOPY --from=builder로 앞 단계의 결과물만 가져옵니다. Image 크기가 줄고, 소스 코드나 빌드 도구가 운영 Image에 남지 않습니다.
단계마다 서로 다른 작업 공간
같은 파일 안에 있어도 단계끼리는 완전히 분리됩니다. 각 FROM이 깨끗한 새 Image에서 다시 시작하기 때문입니다.
┌─── builder 단계 (node:22) ─────────┐ ┌─── 최종 단계 (node:22-alpine) ───┐
│ /app/src/ 소스 코드 │ │ /app/package.json │
│ /app/node_modules/ devDeps 포함 │ │ /app/node_modules/ 운영 의존성만 │
│ /app/dist/ 빌드 결과물 ─────┼─────┼→ /app/dist/ │
│ TypeScript, 빌드 도구 │ │ │
└─────────────────────────────────────┘ └───────────────────────────────────┘
버려짐 최종 Image가 됨- 뒤 단계는 앞 단계의 파일을 자동으로 물려받지 않습니다.
- 앞 단계의 파일이 필요하면
COPY --from=단계이름으로 직접 가져옵니다. docker build가 만드는 Image에는 마지막 단계만 남습니다. 앞 단계는 빌드 중에만 쓰이고 결과 Image에 포함되지 않습니다.
단일 단계와 비교
8. 작성 체크리스트
- 작은 베이스 Image(
alpine,slim)를 쓰고 태그를 명시한다 (latest대신node:22). - 자주 바뀌지 않는 명령을 위에 둬서 캐시를 활용한다.
.dockerignore로 불필요한 파일과 비밀 파일을 제외한다.- 비밀 값을
ENV,ARG로 넣지 않는다. - 가능하면
USER로 root가 아닌 사용자로 실행한다. CMD,ENTRYPOINT는 exec 형식으로 쓴다.- 빌드 결과물만 필요하면 멀티 스테이지 빌드를 쓴다.
9. 정리
| 명령어 | 시점 | 역할 |
|---|---|---|
FROM | 빌드 | 시작 Image 선택 |
WORKDIR | 빌드·실행 | 작업 디렉터리 설정 |
COPY | 빌드 | 파일 복사 |
RUN | 빌드 | 명령 실행 (패키지 설치 등) |
ENV | 빌드·실행 | 환경 변수 |
ARG | 빌드 | 빌드 변수 |
EXPOSE | - | 사용 포트 표시 (문서용) |