IaC/Container

Dockerfile이란?

Somaz 2023. 4. 28. 20:51
728x90
반응형

Overview

오늘은 Dockerfile이 무엇인지와 작성방법에 대해 공부해보려고 한다.

 

윈도우에서 WSL을 사용해 Docker Desktop을 사용해보고 싶다면 아래의 사이트를 참고하길 바란다.

2023.04.26 - [유용한 IT Tool] - WSL 2 Docker 설치 방법


Dockerfile이란?

Dockerfile은 Docker 이미지를 생성하기 위한 지침이 포함된 스크립트이다.

어떤 환경에서도 쉽게 실행할 수 있고 가볍다. 그리고 컨테이너를 만드는 프로세스를 자동화한다. Docker 이미지는 기본 이미지에서 빌드되며 특정 애플리케이션에 필요한 추가 소프트웨어, 라이브러리 또는 도구를 포함한다.

 

아래의 사진은 Dockerfile의 빌드 과정과 Container Registry에 올리는 과정이다.

How to Build Docker Image : Comprehensive Beginners Guide


Dockerfile 설명

Dockerfile는 Instructions와 Argument가 있는 간단한 텍스트 파일이다.

 

How to Build Docker Image : Comprehensive Beginners Guide

Dockerfile에서 왼쪽의 모든 항목은 INSTRUCTION 이고 오른쪽은 해당 지침에 대한 ARGUMENT이다.

 

Dockerfile
Instruction
Explanation
FROM 베이스 이미지 지정 (Docker hub, GCR, Quay, ECR, etc)
RUN 명령 실행 (docker build시 실행시 수행)
ENV 환경변수
COPY 파일복사
EXPOSE 컨테이너에 노출될 포트 지정
ADD 파일 / 디렉토리 추가
WORKDIR 작업 디렉토리
VOLUME 볼륨 마운트
USER 사용자 지정
LABEL 라벨 설정
ARG Dockerfile 안의 변수
CMD 실행 중인 컨테이너에서 명령을 실행하는 데 사용됩니다. 하나의 CMD만 있을 수 있으며 여러 CMD가 있는 경우 마지막 CMD에만 적용됩니다. Docker CLI에서 재정의한다.
ENTRYPOINT Docker 컨테이너가 시작될 때 실행할 명령을 지정합니다. ENTRYPOINT를 지정하지 않으면 기본값은 </bin/sh -c.> 이다.  CLI를 사용하여 플래그를 사용하여 ENTRYPOINT를 재정의한다.

 

 

 

RUN, CMD, ENTRYPOINT 차이점

 


 

RUN

 

RUN 명령은 Dockerfile에서 이미지 빌드 프로세스 중에 명령을 실행하는 데 사용된다.

주로 소프트웨어 패키지 설치, 구성 설정 또는 이미지 내에서 원하는 환경을 만드는 데 필요한 기타 작업을 수행하는 데 사용된다. 각 RUN 명령은 이미지에 새 레이어를 생성한 다음 중간 이미지로 저장한다.

생성된 레이어 수를 최소화하기 위해 "&&" 연산자와 함께 단일 라인을 사용하여 여러 RUN 명령을 함께 연결한다.

 

Syntax

RUN <command>

Example

RUN apt-get update && apt-get install -y curl

 

 


 

 

CMD

 

CMD 명령은 빌드된 이미지에서 컨테이너가 실행될 때 실행할 기본 명령을 정의하는 데 사용된다.

사용자가 컨테이너를 실행할 때 명령을 제공하지 않으면 CMD 명령이 실행된다.

그러나 사용자가 컨테이너를 시작할 때 명령을 지정하면 CMD 명령을 무시한다.

Dockerfile에는 하나의 CMD 명령만 있을 수 있으며 여러 CMD 명령이 제공되는 경우 마지막 명령만 적용된다.

 

Syntax

CMD ["executable", "param1", "param2", ...]

Example

CMD ["python", "app.py"]

 


 

 

ENTRYPOINT

 

ENTRYPOINT 명령은 컨테이너가 실행될 때 항상 실행되는 컨테이너의 기본 실행 파일을 정의하는 데 사용된다.

CMD와 달리 ENTRYPOINT 명령은 사용자가 컨테이너를 시작할 때 명령을 지정하면 재정의되지 않는다.

대신 사용자가 제공하는 모든 명령이 ENTRYPOINT에 인수로 전달된다.

CMD 명령을 ENTRYPOINT와 함께 사용하여 기본 인수를 제공할 수 있다.

 

Syntax

ENTRYPOINT ["executable", "param1", "param2", ...]

Example

ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8080"]

 


Dockerfile 실습

 


 

1.  nginx-image & files 디렉토리 생성 

$ mkdir nginx-image && cd nginx-image
$ mkdir files

 


 

2. .dockerignore 파일 생성

.dockerignore 파일은 docker 데몬으로 보내기 전에 컨텍스트의 루트 디렉터리에서 이름이 지정된 파일을 찾는다 . 

이 파일이 있는 경우 CLI는 컨텍스트를 수정하여 패턴과 일치하는 파일 및 디렉터리를 제외한다.

 

아래는 .dockerignore 파일의 예시다.

$ touch .dockerignore

$ vi .dockerignore

# Versioning and metadata
.git
.gitignore
.dockerignore

# Build dependencies
dist
node_modules
coverage

# Environment (contains sensitive data)
.env

# Files not required for production
.editorconfig
Dockerfile
README.md
tslint.json
nodemon.json

 


 

3. HTML & Config file 생성(Sample)

$ cd files

$ vi index.html

<html>
  <head>
    <title>Dockerfile</title>
  </head>
  <body>
    <div class="container">
      <h1>My App</h1>
      <h2>This is my first app</h2>
      <p>Hello everyone, This is running via Docker container</p>
    </div>
  </body>
</html>

----------------------------------------------------------------------

$ vi default

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    
    root /usr/share/nginx/html;
    index index.html index.htm;

    server_name _;
    location / {
        try_files $uri $uri/ =404;
    }
}

 


 

4. Dockerfile 생성

$ vi Dockerfile

FROM ubuntu:20.04  
LABEL maintainer="somaz@gmail.com" 
RUN  apt-get -y update && apt-get -y install nginx
COPY files/default /etc/nginx/sites-available/default
COPY files/index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
  • FROM명령은 Docker 허브에서 Ubuntu 20.04 버전 이미지를 가져온다.
  • LABEL은 내가 해당 이미지를 만들었다는 것을 추가하는 것이다.
  • RUN은 우분투에 nginx 패키지를 설치한다.
  • COPY 명령어는 local에 있는 file들을 이미지 안으로 복사할 수 있다.
    • default 파일과 index.html 파일을 복사해준다.
  • EXPOSE는 컨테이너 노출포트이다.
  • CMD 명령은 컨테이너가 실행될 때 실행될 기본 명령을 지정한다.
    • /usr/sbin/nginx: Nginx 웹 서버용 실행 파일이다.
    • -g "daemon off;": 이 플래그는 Nginx가 (데몬이 아닌) 포그라운드에서 실행하도록 지시하여 백그라운드로 분기되지 않도록 한다.
    • 컨테이너를 활성 상태로 유지하기 위해 foreground에서 프로세스를 실행해야 하므로 Docker 컨테이너에 필요하다.

 


 

5. Dockerfile 이미지 빌드

최종 폴더 및 파일 구조는 다음과 같다.

~/nginx-image$ tree .
.
├── Dockerfile
└── files
    ├── default
    └── index.html

1 directory, 3 files

 

Docker 명령을 사용하여 이미지를 빌드한다.

# 파일지정
$ docker build -f Dockerfile -t nginx:somaz .

# Dockerfile이 하나일 경우
$ docker build -t nginx:somaz .

# build 테스트시 이전 build 캐시 삭제
$ docker build --no-cache -f Dockerfile -t nginx:somaz .
  • -f 는 Dockerfile을 지정한다. 
  • -t는 이미지 name과 tag를 지정한다.
    • ex. <image name>:<tag>
  • "."은 Dockerfile 위치를 도커 빌드 컨텍스트로 참조한다. 간단히 말하면 현재 작업디렉토리를 나타낸다.

Dockerfile 빌드 과정

도커 이미지를 확인해준다.

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
nginx        somaz     a538e5aba903   About a minute ago   174MB

 


 

6. Docker 이미지 테스트

Docker 이미지를 실행해본다.

$ docker run -d -p 9090:80 --name webserver nginx:somaz
66dae9b6136e42843b192874ef374bda9da25e1c7f1698ece306f2af2a91e46f
  • -d 플래그는 분리 모드에서 컨테이너를 실행하기 위한 것이다.
  • -p 포트 번호에 대한 플래그, 형식은 <local-port>:<container-port> 이다.
  • --name 은 컨테이너 이름이다.

작동중인 컨테이너를 확인해본다.

$ docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED              STATUS              PORTS                  NAMES
66dae9b6136e   nginx:somaz   "/usr/sbin/nginx -g …"   About a minute ago   Up About a minute   0.0.0.0:9090->80/tcp   webserver

 

이제 브라우저에서 로 이동하면 http://<host-ip>:9090 을 입력하면 아래와 같이 페이지가 잘뜬다.

 

 

실습을 마쳤다면 리소스를 삭제해준다.

$ docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                  NAMES
66dae9b6136e   nginx:somaz   "/usr/sbin/nginx -g …"   7 minutes ago   Up 7 minutes   0.0.0.0:9090->80/tcp   webserver

$ docker stop 66dae9b6136e

$ docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS                      PORTS     NAMES
66dae9b6136e   nginx:somaz   "/usr/sbin/nginx -g …"   10 minutes ago   Exited (0) 53 seconds ago             webserver

$ docker rm 66dae9b6136e
66dae9b6136e

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
nginx        somaz     a538e5aba903   15 minutes ago   174MB

$ docker rmi a538e5aba903
Untagged: nginx:somaz
Deleted: sha256:a538e5aba9031f7cc44475e24e9549a5612f0c83ee4799fe555bcccfc8f6fd66

 

 

위와 같이 간단하게 Dockerfile을 작성해 이미지 빌드 후 실행까지 해보았다.

 

이상입니다.

 


Reference

Dockerfile Reference(공식 사이트)

 

How to Build Docker Image : Comprehensive Beginners Guide

 

A Beginner’s Guide to Understanding and Building Docker Images

 

Dockerfile 작성 가이드

 

semantic versioning 가이드(Semver)

728x90
반응형