DevOps/Docker

Dockerfile 개념과 작성 방법

whooooo 2025. 1. 27. 18:22

Dockerfile은 Docker 이미지를 생성하기 위한 텍스트 기반의 스크립트 파일입니다. 개발자들이 명령어를 토대로 작성한 Dockerfile을 기반으로 애플리케이션의 실행 환경을 포함한 이미지를 생성할 수 있습니다. 이번 글에서는 Dockerfile의 개념, 작성 방법, 유의사항들에 대하여 알아보도록 하겠습니다. 

 

Dockerfile

Dockerfile은 Docker 이미지를 정의하는 데 사용되는 구성 파일입니다. 파일에 작성된 명령어를 순차적으로 실행하여 컨테이너 이미지를 빌드합니다. Dockerfile은 애플리케이션의 배포와 관리를 용이하게 만들어 DevOps 환경에서 필수적인 도구로 자리 잡았습니다.

Dockerfile Reference 보러 가기 

주요 특징

  • 컨테이너 실행 환경을 코드로 관리
  • 일관된 개발 및 배포 환경 제공
  • 재사용 및 확장 가능

Dockerfile은 이미지 빌드를 위해 명령어들이 단계별로 작성됩니다. 애플리케이션 실행을 위한 환경, 패키지 정보 등이 포함되어 작성되며, 이를 사용하면 일관된 환경을 유지할 수 있습니다. 따라서 개발 및 배포 과정에서 발생하는 환경 설정 이슈를 효과적으로 해결할 수 있습니다. (특히, "제 PC에서는 돌아가는데요?"와 같은 문제를 방지할 수 있습니다. 😃)

생성된 도커 이미지는 컨테이너 실행 시 사용되며, 컨테이너가 실행되는 완전한 환경을 캡슐화한 형태를 가집니다.

Dockerfile 내용을 이해하면 컨테이너 환경을 파악하고 활용하는 데 큰 도움이 됩니다.

 

Dockerfile 구조

도커파일 이미지 출처

 

 

Dockerfile 기본 구조

주요 명령어

  1. FROM
    • 모든 Dockerfile은 FROM 명령어로 시작되며 운영 체제 이미지를 설정
    • <이미지이름>:<태그> 구조로 작성되며 태그를 입력하지 않은 경우 자동으로 latest 버전으로 실행 
    • 예: FROM ubuntu:20.04
  2. RUN
    •  이미지를 빌드하는 동안 컨테이너 내에서 입력된 명령어를 실행하여 이미지를 구성, 주로 소프트웨어를 설치하거나, 파일을 생성하거나, 설정을 변경하는 데 사용

    • RUN 명령어와 동시에 apt-get update와 install을 함께 실행하는 것을 추천 
    • 예: RUN apt-get update && apt-get install -y nginx
  3. CMD
    • 컨테이너가 실행 시 기본으로 실행될 명령어
    • Dockerfile내에는 하나의 CMD만 존재할 수 있고, 여러개의 CMD가 존재하는 경우 마지막 라인의 CMD가 적용됨
    • 예: CMD ["nginx", "-g", "daemon off;"]
  4. COPY
    • 로컬 파일을 컨테이너 이미지로 복사
    • 예: COPY index.html /usr/share/nginx/html/
  5. WORKDIR
    • 작업 디렉토리를 설정
    • 예: WORKDIR /app
  6. EXPOSE
    • 컨테이너에서 사용할 포트 지정
    • 예: EXPOSE 80
  7. ENTRYPOINT
    • 컨테이너가 실행될 때 고정적으로 실행할 명령어를 설정
    • 예: ENTRYPOINT ["/bin/bash"]

실무에서 자주 사용되는 명령어

  1. ADD
    • COPY와 유사하지만, URL에서 파일을 다운로드하거나 tar 파일을 자동으로 압축 해제 가능 
    • 예: ADD https://example.com/app.tar.gz /app
  2. LABEL
    • 이미지를 설명하는 메타데이터 추가 
    • 예: LABEL maintainer="your_email@example.com"
  3. ENV
    • 환경 변수를 설정
    • 예: ENV SPRING_PROFILES_ACTIVE=prod
  4. ARG
    • 빌드 시 사용하는 변수
    • 예: ARG JDK_VERSION=17
  5. VOLUME
    • 컨테이너에서 데이터를 유지하기 위한 볼륨 설정
    • 예: VOLUME /data
  6. USER
    • 실행 사용자 및 그룹 설정
    • 예: USER appuser
  7. HEALTHCHECK
    • 컨테이너의 상태를 주기적으로 확인
    • 예: HEALTHCHECK --interval=30s CMD curl -f http://localhost:8080/health || exit 1
  8. ONBUILD
    • 상속받는 Dockerfile에 명령어를 추가할 때 사용
    • 예: ONBUILD COPY . /app
  9. SHELL
    • 명령어 실행 시 사용할 기본 셸을 변경
    • 예: SHELL ["/bin/bash", "-c"]

 

Dockerfile 예시

Spring Boot 애플리케이션을 위한 Dockerfile

# Base image 설정
FROM openjdk:17-jdk-slim

# 유지보수를 위한 메타데이터 추가
LABEL maintainer="your_email@example.com"

# 빌드 시 사용할 변수 설정
ARG JAR_FILE=target/my-spring-boot-app.jar

# 환경 변수 설정 (dev 환경)
ENV SPRING_PROFILES_ACTIVE=dev

# 작업 디렉토리 설정
WORKDIR /app

# 애플리케이션 JAR 파일 복사
COPY ${JAR_FILE} app.jar

# 애플리케이션이 의존하는 추가 파일 복사 (예: 설정 파일)
ADD config/dev/application-dev.yml /app/config/application.yml

# 애플리케이션 실행에 사용할 포트 노출
EXPOSE 8080

# 컨테이너 상태를 확인하기 위한 Healthcheck 설정
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

# 실행 명령어 설정
ENTRYPOINT ["java", "-jar", "app.jar"]

빌드 및 실행 방법

  1. Dockerfile이 위치한 디렉토리에서 이미지를 빌드합니다.
  2. docker build -t my-spring-boot-app .
  3. 생성된 이미지를 기반으로 컨테이너를 실행합니다.
  4. docker run -p 8080:8080 my-spring-boot-app
 

Dockerfile 작성 시 주의사항

  1. 이미지 크기 최적화
    • 불필요한 파일을 COPY하지 않도록 .dockerignore 파일 사용
    • 멀티스테이지 빌드를 활용하여 최종 이미지 크기를 줄입니다.
  2. 캐싱 활용
    • 명령어 순서를 신중히 작성하여 캐싱 효과를 극대화합니다.
  3. 보안 고려
    • 민감한 정보를 Dockerfile에 포함하지 않고, 공식 이미지를 사용 
  4. 레이어 수 줄이기
    • 여러 명령어를 RUN에 결합하여 불필요한 레이어 생성 방지
  5. 컨테이너 실행 사용자 설정
    • 보안 강화를 위해 USER 명령어를 사용, 루트 사용자로 실행되는 것을 방지하