개발기록장

[Docker] Dockerfile 작성법 간단 정리 본문

TIL/Docker

[Docker] Dockerfile 작성법 간단 정리

yangahh 2021. 5. 25. 16:42

 

 

Dockerfile이란, Docker 이미지를 만드는 일종의 스크립트다. Docker build 명령어를 쓰면 파일을 읽어서 여기에 명시된 대로 이미지를 만든다.

Dockerfile 작성 예시

FROM ubuntu:14.04

LABEL version=0.1

# app 디렉토리 생성
RUN mkdir -p /app

# Docker 이미지 내부에서 RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리를 설정
WORKDIR /app


# 현재 디렉터리에 있는 파일들을 이미지 내부 /app 디렉터리에 추가함
ADD . /app


RUN apt-get update

RUN apt-get install apache2

RUN service apache2 start


VOLUME ["/data", "/var/log/httpd"]


# 외부로 노출하는 포트 지정
EXPOSE 80

# 이미지를 도커 컨테이너로 실행하기 전에 먼저 실행할 명령어
CMD ["/app/log.backup.sh"]

 

Dockerfile 형식

주의사항: 컨테이너에 담을 파일들은 Dockerfile 하위 디렉토리에 있어야 한다.

FROM 

FROM 이미지 이름:태그

 

base 이미지로 사용할 레이어를 가져오는 단계이다.

FROM <이미지 이름>:<태그> 형식으로 작성한다.
ex) ubuntu:14.04

 

LABEL

LABEL key=value

이미지의 버전 정보, 작성자, 코멘트와 같이 이미지의 메타 정보를 입력하는 부분으로 빌드 자동화 등에 사용될 수 있다.

** 라벨 확인 방법

docker image inspect --format='label key값' 이미지명

 

ENV

Dockerfile 또는 컨테이너 내부의 환경변수에 대한 선언을 하는 부분이다.

ex) JAVA_HOME /usr/lib/java

 

WORKDIR  
명령을 실행하기 위한 디렉토리를 지정하는 부분이다. WORKDIR 을 지정하면 RUN, CMD, ENTRYPOINT, COPY, ADD 등의 명령이 영향을 받는다. 이 명령어에서 컨테이너의 '.' 으로 명시하면 WORKDIR의 위치를 가르키는 것이다.

 

COPY

COPY [--chown=<user>:<group>] <src>... <dest>
# 공백이 포함된 경우는 
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

호스트OS의 파일 및 디렉토리를 컨테이너 내부로 복사하는 명령어이다. 소유자와 소유그룹도 수정이 가능하다.

 

ADD

ADD [--chown=<user>:<group>] <src>.. <dest>
# 공백이 필요한 경우는 
ADD [--chown=<user>:<group>] ["<src>".. "<dest>"]

COPY와 마찬가지로 파일 및 디렉토리를 컨테이너 내부로 복사하는 명령어이다. 추가적으로 URL 및 원격 파일 다운로드 또는 압축 해제 등과 같은 기능도 있다. Dockerfile 안에서 ADD시 절대경로는 사용이 불가능하다.

ex) ADD http://~~~/index.php /data/index.php


RUN 
도커 이미지가 생성되기 전에(=이미지를 빌드하는 시점에) 실행되는 쉘 명령어를 작성하는 부분이다.

RUN 명령은 설치/설정 등을 위한 용도로 쓰여서 image layer를 만들어낸다.

 

RUN을 사용하는 방법에는 2가지 형식이 있다.

1. /bin/bash -c command 형식으로 shell 명령을 실행

RUN "command" 
# 예) RUN yum install -y python

2. 

RUN ["executable", "param1", "param2"] 
# 예) RUN ["/bin/bash", "-c", "echo hello"]
  • executable 은 명령어를 실행할 양식 (bash, zsh, etc)을 지정.
  • executable 을 이용해서 별도의 python, ruby 스크립트를 실행 가능하다.
  • param1, param2 는 해당 명령어를 실행하면서 전달할 파라미터이다.

 

CMD
RUN 명령어는 이미지를 빌드하는 시점에 실행되는 반면에, CMD 는 컨테이너를 실행할 때(=컨테이너가 시작될 때) 수행되는 실행 파일 또는 셸 스크립트를 작성하는 부분이다.
주의 해야할 점은 Dockerfile 에서 CMD 는 1개만 적용되며 여러 개를 지정한 경우 마지막 CMD 만이 적용된다.

또한 docker run 을 사용하며 새로운 명령을 지정한 경우(=명령에 쉘 명령어 및 인자값 전달할 경우) CMD에 작성된 명령어와 인자값은 무시된다. 즉, 우선 순위는 docker run > CMD 이다.

 

CMD를 사용하는 방법에는 3가지 형식이 있다.

1. 가장 기본적인 형식

CMD ["executable","param1","param2"]
# 예) CMD ["gunicorn", "--bind", "0.0.0.0:8000", "test_project.wsgi:application"]

2. shell 명령을 실행

CMD command param1 param2

3. ENTRYPOINT 의 매개변수 전달

CMD ["param1","param2"]

 

ENTRYPOINT

ENTRYPOINT ["executable", "param1", "param2"]
# 또는
ENTRYPOINT command param1 param2

 

도커 컨테이너를 실행하기 전에 최종적으로 실행할 명령어를 적는 부분이다. CMD와 마찬가지로 1번만 수행할 수 있다.

CMD와의 차이점은 ENTRYPOINT는 CMD를 인자로 받아 사용할 수 있는 스크립트를 쓴다는 것이다.

또한 CMD는 docker run 을 사용하며 새로운 명령을 지정한 경우 CMD에 지정한 명령이 무시되지만, ENTRYPOINT는 docker run에서 지정한 명령과 관계 없이 실행된다는 차이가 있다.

 

VOLUME 

VOLUME ['컨테이너 디렉토리1', '컨테이너 디렉토리2' , .... ]

컨테이너 안에 있는 데이터는 컨테이너를 삭제하면 모든 데이터가 같이 삭제(휘발성 데이터) 되기 때문에 데이터를 보존하기 위해 VOLUME을 사용한다.
VOLUME에 명시된 (컨테이너에 있는) 디렉토리 안의 모든 데이터는 컨테이너에 저장하지 않고 호스트 OS에 저장하거나 컨테이너들간의 데이터를 공유가 가능하도록 설정된다.

Dockerfile 에서 생성한 볼륨은 호스트OS의 /var/lib/docker/volumes에 생성되며, Docker 에서 자동 생성한 hash값으로 디렉토리가 생긴다.


** docker run 명령에서 -v 옵션을 아래와 같이 사용하면 호스트 OS의 위치(볼륨 마운트의 위치)를 지정한 위치(아래의 예시에서는 /root/data)로 변경할 수 있다.
ex) -v /root/data:/data

 

EXPOSE 

EXPOSE <port> [<port>/<protocol>...]
# 예) EXPOSE 80/tcp
# 프로토콜 default는 tcp

컨테이너의 런타임에 지정된 네트워크 포트에서 수신 대기를 한다는 것을 나타낸다.

 

 

참고: docker docs

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

[Docker] Docker 개념 간단 정리  (0) 2021.05.21