Docker를 사용하는 가장 큰 이유는 동일한 실행 환경을 언제 어디서나 재현할 수 있기 때문입니다.
이러한 환경을 코드로 정의하는 파일이 바로 Dockerfile입니다.
Dockerfile을 작성하면 애플리케이션 실행에 필요한 운영체제, 라이브러리, 프로그램, 환경 변수 등을 하나의 이미지로 자동 생성할 수 있습니다.
이번 글에서는 Dockerfile의 개념부터 주요 명령어인 FROM, RUN, COPY, WORKDIR, CMD, ENTRYPOINT의 역할과 이미지 생성 실습까지 자세히 알아보겠습니다.
Dockerfile이란?
Dockerfile은 Docker Image를 자동으로 생성하기 위한 설정 파일입니다.
텍스트 파일 형태이며, 각 줄마다 하나의 명령을 작성합니다.
전체 구조는 다음과 같습니다.
Dockerfile
↓
docker build
↓
Docker Image
↓
docker run
↓
Docker Container
한 번 작성한 Dockerfile은 여러 환경에서 동일한 이미지를 생성할 수 있습니다.
Dockerfile이 필요한 이유
Dockerfile을 사용하지 않으면 컨테이너 내부에서 직접 프로그램을 설치해야 합니다.
하지만 Dockerfile을 사용하면 설치 과정까지 자동화할 수 있습니다.
장점은 다음과 같습니다.
- 반복 작업 제거
- 동일한 환경 구축
- 버전 관리 가능
- CI/CD 자동화
- 협업 효율 향상
실무에서는 대부분 Dockerfile을 이용하여 이미지를 생성합니다.
Dockerfile 기본 구조
가장 간단한 예제입니다.
FROM ubuntu:24.04
RUN apt update
CMD ["bash"]
동작 순서는 다음과 같습니다.
Ubuntu Image
↓
패키지 업데이트
↓
새로운 Image 생성
↓
Container 실행
FROM 명령어
FROM은 기준이 되는 베이스 이미지를 지정하는 명령어입니다.
예를 들어 Ubuntu를 사용하려면 다음과 같이 작성합니다.
FROM ubuntu:24.04
Python 환경이라면
FROM python:3.12
Node.js 환경이라면
FROM node:22
Dockerfile은 반드시 FROM으로 시작하는 것이 일반적입니다.
RUN 명령어
RUN은 이미지를 생성하는 과정에서 명령을 실행합니다.
예를 들어
RUN apt update
RUN apt install -y nginx
이미지 생성 시 Nginx가 설치됩니다.
여러 명령은 하나로 합치는 것이 효율적입니다.
RUN apt update && apt install -y nginx
이렇게 하면 Layer 수를 줄일 수 있습니다.
COPY 명령어
COPY는 호스트의 파일을 이미지 내부로 복사합니다.
예를 들어
COPY index.html /var/www/html/
현재 폴더의 index.html 파일이 컨테이너 내부로 복사됩니다.
프로젝트 전체를 복사하려면
COPY . .
를 사용할 수 있습니다.
ADD 명령어
ADD도 파일을 복사하지만 추가 기능이 있습니다.
ADD app.tar.gz /app/
압축 파일을 자동으로 해제합니다.
또한 URL 다운로드 기능도 지원하지만, 현재는 대부분 COPY 사용이 권장됩니다.
WORKDIR 명령어
작업 디렉터리를 지정합니다.
WORKDIR /app
이후 실행되는 명령은 /app 디렉터리에서 수행됩니다.
예를 들어
WORKDIR /app
COPY . .
RUN npm install
npm install은 /app에서 실행됩니다.
ENV 명령어
환경 변수를 설정합니다.
ENV NODE_ENV=production
또는
ENV PORT=8080
애플리케이션에서 환경 변수로 사용할 수 있습니다.
EXPOSE 명령어
컨테이너가 사용할 포트를 문서화합니다.
EXPOSE 80
또는
EXPOSE 8080
EXPOSE는 실제 포트를 개방하지는 않으며, 어떤 포트를 사용하는지 알려주는 역할을 합니다.
실제 연결은 docker run -p 옵션으로 수행합니다.
CMD 명령어
컨테이너가 시작될 때 실행할 기본 명령입니다.
예를 들어
CMD ["nginx","-g","daemon off;"]
또는
CMD ["python","app.py"]
하나의 Dockerfile에는 일반적으로 하나의 CMD만 사용합니다.
ENTRYPOINT 명령어
항상 실행되어야 하는 프로그램을 지정합니다.
ENTRYPOINT ["python"]
실행 시 추가 인수를 받을 수 있습니다.
docker run myimage app.py
실제로는
python app.py
처럼 실행됩니다.
CMD와 ENTRYPOINT 차이
| 항목 | CMD | ENTRYPOINT |
|---|---|---|
| 기본 실행 명령 | O | O |
| 실행 시 변경 가능 | 쉬움 | 어려움 |
| 추가 인수 전달 | 제한적 | 가능 |
| 주 사용 목적 | 기본 실행 | 고정 실행 |
일반적인 애플리케이션은 CMD를 많이 사용합니다.
LABEL 명령어
이미지에 메타데이터를 추가합니다.
LABEL maintainer="admin@example.com"
또는
LABEL version="1.0"
이미지 관리에 도움이 됩니다.
USER 명령어
컨테이너 실행 사용자를 지정합니다.
USER nginx
보안을 위해 root 대신 일반 사용자로 실행하는 것이 권장됩니다.
실제 Dockerfile 예제
간단한 Nginx 웹 서버 예제입니다.
FROM nginx:latest
COPY index.html /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
이미지 생성
docker build -t myweb .
컨테이너 실행
docker run -d -p 8080:80 myweb
브라우저에서 http://localhost:8080으로 접속하면 복사한 index.html이 표시됩니다.
Dockerfile Layer 구조
Dockerfile의 각 명령은 하나의 Layer를 생성합니다.
FROM
↓
RUN
↓
COPY
↓
ENV
↓
CMD
변경되지 않은 Layer는 캐시를 재사용하므로 빌드 속도가 빨라집니다.
Dockerfile 작성 시 모범 사례
다음 사항을 지키면 더 효율적인 이미지를 만들 수 있습니다.
- 최신 버전 대신 명확한 버전 태그 사용
RUN명령은 가능한 한 합치기- 불필요한 파일은
.dockerignore로 제외 COPY순서를 최적화하여 캐시 활용- root 사용자 대신 일반 사용자 사용
- 이미지 크기를 최소화하기 위해 Alpine 기반 이미지를 검토
실무에서 자주 사용하는 명령어
이미지 생성
docker build -t myapp .
Dockerfile 지정
docker build -f Dockerfile .
빌드 로그 자세히 보기
docker build --progress=plain .
이미지 실행
docker run myapp
이미지 목록 확인
docker images
실무 사례
예를 들어 Flask 웹 애플리케이션을 운영한다고 가정해 보겠습니다.
python:3.12이미지를 기반으로 Dockerfile을 작성합니다.requirements.txt를 복사한 후 필요한 라이브러리를 설치합니다.- 애플리케이션 소스를 복사합니다.
CMD ["python", "app.py"]를 지정합니다.docker build -t flask-app:v1 .으로 이미지를 생성합니다.- 운영 서버에서는 동일한 이미지를 사용하여 컨테이너를 실행합니다.
이 과정을 통해 개발 환경과 운영 환경을 동일하게 유지할 수 있으며, 새로운 서버에서도 몇 분 안에 동일한 서비스를 배포할 수 있습니다.
자주 묻는 질문
Dockerfile과 Docker Image는 같은 것인가요?
아닙니다. Dockerfile은 이미지를 생성하기 위한 설정 파일이며, Docker Image는 Dockerfile을 빌드한 결과물입니다.
Dockerfile에서 반드시 FROM을 사용해야 하나요?
대부분의 경우 그렇습니다. FROM을 통해 베이스 이미지를 지정한 뒤 필요한 내용을 추가하는 방식으로 이미지를 생성합니다.
RUN과 CMD의 차이는 무엇인가요?
RUN은 이미지를 빌드하는 과정에서 실행되고, CMD는 컨테이너가 시작될 때 실행됩니다. 두 명령은 실행 시점이 다르므로 용도에 맞게 사용해야 합니다.
마무리
Dockerfile은 Docker를 자동화하는 핵심 요소입니다. 설치 과정과 실행 방법을 코드로 관리할 수 있어 누구나 동일한 이미지를 생성할 수 있으며, CI/CD와 클라우드 환경에서도 필수적으로 활용됩니다. FROM, RUN, COPY, WORKDIR, CMD 등 기본 명령어를 이해하면 다양한 애플리케이션을 손쉽게 컨테이너화할 수 있습니다.