[Docker] 도커파일 작성법 (Node.js)
[1. Dockerfile]
1. 도커파일이란
- 도커에서 이미지를 생성하기 위해 작성하는 문서
- 'Dockerfile'이라는 이름으로 도커파일을 작성하고 명령어를 실행하면 이미지가 빌드된다
- 다른 이름으로 파일을 생성할 경우 파일명을 명령어에 직접 입력해줘야 함
docker build [옵션] [도커파일 경로]
2. 도커파일 주요 문법
1) FROM
- 애플리케이션을 빌드하는 단계
- 베이스 이미지 지정, 필수적인 요소
- 하나의 단계, 레이어를 생성하는 요소
- AS를 통해 참조 이름을 설정할 수 있음
2) WORKDIR
- 작업 디렉토리 지정, 파일 위치를 명확히 함
3) RUN
- 새로운 이미지 레이어를 생성 후 실행, 커밋함
4) COPY
- 필요한 파일을 컨테이너로 복사
6) EXPOSE
- 애플리케이션이 실행될 포트 입력
5) CMD
- 도커 컨테이너가 실행될 때 수행할 명령어
- 쉼표가 띄어쓰기 역할
3. 도커파일 예시
# 베이스 이미지 설정
FROM node:22-alpine
# 작업 디렉토리 설정
WORKDIR /app
# 의존성 파일을 컨테이너로 복사
COPY package*.json ./
# 의존성 설치
RUN npm install
# 애플리케이션 소스 코드를 컨테이너로 복사
COPY . .
# 애플리케이션 빌드 (선택적, 필요에 따라)
RUN npm run build
# 애플리케이션이 사용할 포트 설정
EXPOSE 3000
# 애플리케이션 실행 명령어 설정
CMD [ "npm", "start" ]
[2. 빌드 단계와 프로덕션 단계 분리하기]
1. 분리하는 이유
1) Docker 이미지의 레이어 구조
- 도커 이미지는 계층적인 구조로 이루어져 있으며 FROM명령어는 새로운 레이어를 생성
- 각 레이어는 이전 레이어 위에 쌓이고 도커는 변경된 레이어만 다시 빌드
2) 효율적인 빌드 캐싱
- 도커 이미지는 캐싱을 사용해 빌드 성능을 최적화함 (* 캐싱 : 파일 복사본을 캐시 또는 임시 저장 위치에 저장하여 보다 빠르게 액세스할 수 있도록 하는 프로세스)
- 레이어를 분리할 경우 (FROM으로 명령을 나눌 경우) 도커는 변경된 레이어만 재빌드함으로써 이미지 빌드 시간이 단축됨
3) 최적화
- 빌드 단계에서 필요한 도구나 개발 의존성은 프로덕션 이미지에 포함되지 않으므로 최종 프로덕셩 이미지의 크기가 줄어듦
- 프로덕셩 환경에서 불필요한 파일이나 도구를 제거하고 필요한 파일만 포함된 개끗한 이미지를 제공함으로써 보안과 관리 측면에 이점
2. 분리 예시
- 위의 예시 도커 파일을 빌드 단계와 프로덕션 단계로 분리해보자!
# 빌드 단계
FROM node:22-alpine AS build
# 작업 디렉토리 설정
WORKDIR /app
# 의존성 파일을 컨테이너로 복사
COPY package*.json ./
# 의존성 설치
RUN npm install
# 애플리케이션 소스 코드를 컨테이너로 복사
COPY . .
# 애플리케이션 빌드
RUN npm run build
# 프로덕션 단계
FROM node:22-alpine AS production
# 작업 디렉토리 설정
WORKDIR /app
# 빌드 단계에서 생성된 빌드 결과물을 복사
COPY --from=build /app/dist /app/dist
# 필요한 파일 및 디렉토리 복사
COPY --from=build /app/node_modules /app/node_modules
COPY --from=build /app/package*.json /app/
# 개발 의존성 제외하고 의존성 설치
RUN npm install --omit-dev
# 애플리케이션이 사용할 포트 설정
EXPOSE 3000
# 애플리케이션 실행 명령어 설정
CMD [ "npm", "start" ]