Dockerfile

📌 Dockerfile은 컴퓨터에서 돌아가는 앱을 만들기 위한 레시피라고 보면 된다. 이 레시피대로 하면 Docker 이미지라는 걸 만들 수 있다. Docker 이미지는 앱을 실행하는 데 필요한 모든 것을 담고 있다.

 

 

Dockerfile을 사용하는 이유

 

1. 환경 일관성

  • 문제: 애플리케이션은 다양한 환경(OS, 라이브러리 버전, 설정)에 따라 다르게 동작할 수 있습니다.
  • Dockerfile의 역할:
    • Dockerfile을 통해 운영체제, 소프트웨어 버전, 라이브러리 등을 명시적으로 정의.
    • 개발, 테스트, 운영 환경에서 동일한 컨테이너 이미지를 사용하므로 환경 차이로 인한 문제를 방지.
    • "개발 환경에서 잘 동작하는데 프로덕션에서는 오류가 발생하는 문제"를 해소.

2. 자동화된 이미지 생성

  • 문제: 매번 애플리케이션을 설치하거나 빌드하는 과정을 수동으로 처리하면 시간이 낭비되고 오류가 발생할 수 있습니다.
  • Dockerfile의 역할:
    • Dockerfile은 애플리케이션 빌드 및 설치 과정을 자동화.
    • docker build 명령어로 간단히 이미지를 생성할 수 있음.
    • 변경 사항이 생길 경우 Dockerfile만 업데이트하여 쉽게 새로운 이미지를 생성 가능.

3. 이식성(Portability)

  • 문제: 다른 플랫폼(OS)에서 애플리케이션을 배포하려면 추가 설정과 조정이 필요할 수 있습니다.
  • Dockerfile의 역할:
    • Docker 이미지는 한 번 생성하면 어떤 환경에서든 동일하게 동작.
    • 컨테이너를 실행할 수 있는 곳이라면(로컬, 클라우드, 서버 등) 어디서나 배포 가능.
    • 운영 환경에 상관없이 안정적인 배포 보장.

4. 확장성과 모듈화

  • 문제: 복잡한 시스템은 여러 애플리케이션이나 서비스가 상호작용하며 구성됩니다.
  • Dockerfile의 역할:
    • Dockerfile을 사용해 애플리케이션별 컨테이너를 생성하고, 이를 조합하여 마이크로서비스 아키텍처를 구현.
    • 각 서비스는 독립적으로 배포, 확장 가능.

5. 버전 관리 및 재현성

  • 문제: 애플리케이션 업데이트나 변경이 과거 버전과 충돌하거나 재현이 어려울 수 있음.
  • Dockerfile의 역할:
    • Dockerfile 자체를 소스 코드와 함께 버전 관리(Git 등)할 수 있음.
    • 특정 시점의 Dockerfile로 언제든지 동일한 이미지를 재생성 가능.

6. 배포 자동화(CI/CD와 통합)

  • 문제: 애플리케이션 배포 과정을 수동으로 처리하면 효율성이 떨어지고 오류가 발생할 수 있음.
  • Dockerfile의 역할:
    • CI/CD 파이프라인에서 Dockerfile을 사용해 자동으로 이미지를 생성하고 테스트, 배포 가능.
    • GitHub Actions, Jenkins, GitLab CI/CD 등과 쉽게 통합 가능.

7. 리소스 격리

  • 문제: 하나의 서버에서 여러 애플리케이션을 실행하면 서로 충돌할 가능성이 있음.
  • Dockerfile의 역할:
    • 컨테이너화된 애플리케이션은 호스트와 격리된 상태로 실행.
    • 리소스(CPU, 메모리, 네트워크)를 독립적으로 관리 가능.

8. 경량성

  • 문제: VM(가상 머신)은 운영체제와 함께 많은 리소스를 소모.
  • Dockerfile의 역할:
    • 컨테이너는 운영체제를 포함하지 않으므로 VM에 비해 가볍고 빠름.
    • Dockerfile로 필요한 최소 구성만 정의해 경량화된 이미지를 생성.

요약: Dockerfile 사용하는 이유

이유  설명
환경 일관성 개발, 테스트, 운영 환경 간 차이를 없애 동일한 애플리케이션 동작 보장.
자동화 애플리케이션 빌드 및 설정 과정을 자동화.
이식성 어디서나 동일하게 실행 가능한 이미지를 제공.
확장성 마이크로서비스 아키텍처 및 독립적인 서비스 확장을 지원.
재현성 버전 관리를 통해 특정 시점의 동일 환경을 재생성 가능.
CI/CD 통합 자동화된 빌드와 배포를 지원하여 DevOps 환경에 최적화.
격리 및 안전성 컨테이너 간 리소스 격리로 안정성 향상.
경량성 VM보다 적은 리소스 사용으로 효율적.

 

 

Dockerfile 사용법

 

Dockerfile 예제

# Dockerfile
FROM ubuntu:latest  # 베이스 이미지를 Ubuntu 최신 버전으로 설정
MAINTAINER Your Name <your-email@example.com>  # 이미지 제작자 정보

# 필요한 패키지 업데이트 및 Nginx 설치
RUN apt-get update && apt-get install -y nginx  

# index.html 파일을 Nginx의 기본 HTML 디렉토리로 복사
COPY index.html /usr/share/nginx/html  

# 컨테이너가 노출할 포트를 설정
EXPOSE 80  

# 컨테이너 실행 시 Nginx를 실행하고 데몬 모드를 비활성화
CMD ["nginx", "-g", "daemon off;"]  

Dockerfile 명령어 설명

명령어 설명
FROM 베이스 이미지를 설정 (컨테이너의 기반 OS 또는 환경).
MAINTAINER 이미지를 제작한 사람의 이름과 이메일 주소를 설정.
RUN 컨테이너 이미지를 빌드할 때 실행할 명령어 (예: 패키지 설치).
COPY 로컬 파일을 컨테이너 이미지로 복사.
EXPOSE 컨테이너가 외부에 노출할 포트를 지정.
CMD 컨테이너가 실행될 때 기본으로 실행할 명령어를 설정.

Docker 이미지 생성 명령어

  1. Docker 이미지를 생성하는 명령:
    docker buildx build -t my-nginx:latest .
    
    • -t: 이미지에 태그를 설정 (예: my-nginx:latest).
    • .: 현재 디렉토리에서 Dockerfile을 찾음.
    • buildx: 빌드 실행 도구. 일반적인 빌드 명령은 docker build를 사용.

Docker 컨테이너 실행 명령어

  1. 컨테이너 실행 명령:
    docker run -d -p 80:80 my-nginx:latest
    
    • -d: 컨테이너를 백그라운드에서 실행.
    • -p 80:80: 호스트의 80번 포트를 컨테이너의 80번 포트에 매핑.
    • my-nginx:latest: 생성한 Docker 이미지를 기반으로 컨테이너 실행.

Docker 컨테이너 관리

  1. 컨테이너 종료:
    • my-nginx: 실행 중인 컨테이너 이름 또는 ID.
  2. docker stop my-nginx
  3. 컨테이너 재시작:
  4. docker start my-nginx
  5. 실행 중인 컨테이너 확인:
  6. docker ps
  7. 중지된 컨테이너 포함 확인:
  8. docker ps -a

Docker 이미지 공유

  1. Docker 레지스트리:
    • Docker 이미지를 공유하고 저장하는 서비스.
    • 예: Docker Hub, AWS ECR, Google Container Registry 등.
  2. 이미지 업로드 명령:
    • username/my-nginx:latest: Docker Hub에 업로드할 이미지 이름.
    • Docker Hub에 업로드하려면 먼저 docker login으로 인증 필요.
  3. docker push username/my-nginx:latest
  4. 이미지 다운로드 명령:
    • 공유된 이미지를 다른 사용자나 서버에서 다운로드하여 사용.
  5. docker pull username/my-nginx:latest

정리된 작업 흐름

  1. Dockerfile 작성:
    • 애플리케이션과 설정을 정의.
  2. 이미지 생성:
    • docker build 명령으로 이미지를 생성.
  3. 컨테이너 실행:
    • docker run 명령으로 컨테이너 실행.
  4. 컨테이너 관리:
    • 컨테이너를 start, stop, restart 명령으로 제어.
  5. 이미지 공유:
    • Docker Hub 등 레지스트리에 이미지를 업로드하여 협업 또는 배포.

Dockerfile 명령어

명령어 설명  예제
FROM 베이스 이미지를 지정. Dockerfile은 항상 FROM으로 시작. FROM ubuntu:22.04
MAINTAINER Dockerfile 작성자 정보 (이제는 LABEL 사용 권장). MAINTAINER naebaecaem <nbcamp@spartacoding.co>
LABEL 이미지에 메타데이터 추가. LABEL purpose='nginx test'
RUN 이미지를 생성하는 동안 실행할 명령어. root 권한으로 실행. RUN apt update && apt upgrade -y
CMD 컨테이너 생성 시 실행할 명령어. 컨테이너 시작 시 한 번만 실행. CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT 컨테이너 시작 시 무조건 실행할 명령어. 추가 명령어와 결합 가능. ENTRYPOINT ["npm", "start"]
ENV 환경 변수를 설정. ENV STAGE stagingENV JAVA_HOME /usr/lib/jvm/java-8-oracle
WORKDIR 작업 디렉토리를 설정. WORKDIR /app
COPY 호스트의 파일/디렉토리를 컨테이너에 복사. Docker Context 내의 파일만 가능. COPY index.html /usr/share/nginx/html
USER 컨테이너 내에서 사용할 기본 사용자를 설정. USER userRUN ["useradd", "user"]
EXPOSE 컨테이너에서 노출할 포트를 설정. EXPOSE 80
ARG 빌드 시점에 전달할 변수를 설정. ENV와 달리 빌드 후에는 사라짐. ARG STAGERUN sh -c 'echo "STAGE=$STAGE" > .env'

Dockerfile 예제 1: FastAPI 앱 실행

# Python 3.11 베이스 이미지 사용
FROM python:3.11

# pipenv 설치
RUN pip install pipenv

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

# 로컬 파일을 컨테이너로 복사
ADD . /app/

# pipenv 환경 설정
RUN pipenv --python 3.11
RUN pipenv run pip install poetry
RUN pipenv sync
RUN pipenv run pip install certifi

# 빌드 시 입력 가능한 변수 설정
ARG STAGE
RUN sh -c 'echo "STAGE=$STAGE" > .env'
RUN sh -c 'echo "PYTHONPATH=." >> .env'

# 실행 스크립트에 실행 권한 부여
RUN chmod +x ./scripts/run.sh
RUN chmod +x ./scripts/run-worker.sh

# 컨테이너 시작 시 실행할 명령어 설정
CMD ["./scripts/run.sh"]

Dockerfile 예제 2: Nginx 웹 서버

Dockerfile

# Ubuntu 22.04 베이스 이미지 사용
FROM ubuntu:22.04

# 작성자 정보
MAINTAINER your-name <your-email@example.com>

# 이미지 메타데이터 추가
LABEL purpose=Web Server

# Nginx 설치
RUN apt-get update && apt-get install -y nginx

# Nginx 설정 파일 복사
COPY nginx.conf /etc/nginx/nginx.conf

# 컨테이너 실행 시 Nginx 시작
CMD ["nginx", "-g", "daemon off;"]

Nginx 설정 파일 (nginx.conf):

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;

    gzip  on;
    gzip_disable "msie6";

    include /etc/nginx/conf.d/*.conf;
}

 

'Docker > Docker' 카테고리의 다른 글

[Docker] Docker 모니터링&로깅  (0) 2025.02.04
[Docker] Docker Compose  (0) 2025.02.03
[CI/CD] Github Actions CI  (0) 2025.01.31
[Docker] Docker+CI/CD  (0) 2025.01.30
[Docker] Docker 기초  (0) 2025.01.29

+ Recent posts