* Dockerfile이란이란?
- 도커 명령어로 컨테이너를 구성하기 위해서는 컨테이너 생성, 컨테이너 안에서 OS설정, 미들웨어 설치, 파라미터 설정 등은 모두 직접 수행해야 한다.
- 이러한 일련의 작업을 자동으로 수행하도록 스크립트로 만든 것이 dockerfile이다.
- 이러한 Dockerfile은 필요한 환경설정이 모두 세팅된 image를 만드는 데 목적이 있으며, 또한 자동화로써 사용할 수 있고 스크립트이므로 변경해서 재사용할 수도 있다.
- 이러한 도커파일의 내용은 아래와 같은 정보들을 기술한다.
1. 베이스가 될 도커 이미지
2. 도커 컨테이너 안에서 수행할 명령, 조작 등
3. 환경변수 등의 설정
4. 도커 컨테이너 안에서 작동시킬 데몬 실행
* Dockerfile 구문 기본
- Dockerfile은 텍스트 형식이며 확장자는 없다.
- 만들기 위해서는 어떤 에디터도 상관없다.
- 메모장도 좋고, vi editor, notepad++, ultraedit 등등 어떤 프로그램도 상관없다.
- visual studio code는 dockerfile 작성을 위한 확장 파일을 제공하므로 좀 더 편하게 사용할 수 있다.
- 이러한 텍스트 파일의 이름은 기본적으로 Dockerfile 이라는 이름을 사용한다.
- 만약 이름을 변경하는 경우, 이미지 build 시 따로 옵션을 줘서 해당 파일명을 명시해줘야 한다.
기본 서식은 "명령 인수" 형식이다. FROM centos:centos7 이런 식.
또한 명령 부분은 대소문자를 가리지는 않지만, 가독성을 위해 관례적으로 대문자를 사용한다.
또한 주석도 가능하며 주석은 맨 앞에 #을 붙이면 된다.
명령의 종류는 아래와 같으며, 각 상세 명령의 사용과 설명은 맨 아래 Docker 명령 상세 설명 부분을 참고하자.
명령 | 설명 | 상세 |
FROM | 베이스 이미지 지정 | docker 컨테이너를 어떤 docker 이미지로부터 생성할지 기술 |
RUN | 명령 실행 | from에서 지정한 베이스 이미지에 대해 수행하는 명령 |
CMD | 컨테이너 실행 명령 | from에서 지정한 베이스 이미지에 대해 데몬을 실행하는데 자주 사용 |
LABEL | 라벨 설정 | 도커파일에 기술할 기타정보들을 기록한다. 만든사람, 버전 등 |
EXPOSE | 포트 익스포트 | 포트를 오픈한다 |
ENV | 환경변수 | 도커파일 안에서 환경변수를 설정한다. |
ADD | 파일/디렉토리 추가 | |
COPY | 파일 복사 | |
ENTRYPOINT | 컨테이너 실행 명령 | cmd와 동일하나 컨테이너 생성명령 수행시 무조건 우선적이다. |
VOLUME | 볼륨 마운트 | |
USER | 사용자 지정 | 특정 명령을 수행할 때 사용할 사용자를 명시한다. |
WORKDIR | 작업 디렉토리 | 명령어가 실행될 경로를 지정 |
ARG | dockerfile 안의 변수 | 도커파일에서 변수를 만들 때 사용 |
ONBUILD | 빌드 완료 후 실행되는 명령 | 빌드한 후 나온 이미지를 다시 빌드할 때 실행되는 명령 |
STOPSIGNAL | 시스템 콜 시그널 설정 | 컨테이너 종료시 사용할 시그널 설정 |
HEALTHCHECK | 컨테이너의 헬스체크 | 일정 주기로 컨테이너의 헬스체크하고 inspect로 볼수있게 한다. |
SHELL | 기본 쉘 설정 | 도커파일에서 사용할 쉘 지정 |
* Dockerfile 만들기
1. docker build 명령
docker build 명령은 dockerfile에 기술된 구성정보를 바탕으로 도커 이미지를 생성한다.
즉 dockerfile을 사용하는 프로세스는 다음과 같은 절차로 작업이 진행되게 된다.
dockerfile 생성 → docker build 로 이미지 생성 → 생성된 이미지로 docker container run 수행
- dockerfile에 명시된 이미지가 없는 경우 자동으로 다운로드를 받으며, 그것이 베이스 이미지가 된다.
- 그리고 이후 명령어들을 모두 수행한 다음, 그 상태를 이미지로 만든다.
- 만들어진 이미지의 이름을 build 명령 수행 시 명시해야 한다.
- 또한 Dockerfile 그대로 이름을 쓰지 않고 따로 임의의 파일명을 사용하는 경우, -f 옵션을 사용해야 한다.
- 참고로, 임의의 파일명을 쓰는 경우 Docker hub에서 이미지 자동 생성 기능을 사용할 수 없다.
Command 형식
#docker build -t [생성할이미지명]:[태그명] [dockerfile위치]
ex command
#docker build -t sample -f Dockerfile-base .
- 예시 맨 뒤의. 은 현재 경로를 의미한다. 현재 경로에 Dockerfile-base 파일이 있는 것.
주의사항 1.
- Dockerfile을 빌드할 때, 내용을 검증하지 않는다.
- 있는 그대로 만들 뿐이므로 에러가 있지 않도록 직접 잘 검증해야 한다.
주의사항 2.
- dockerfile 빌드 시, 해당 dockerfile이 있는 디렉토리 전체의 내용을 모두 docker daemon으로 전송한다.
- 예를 들어 루트디렉토리에 dockerfile을 놓고 build를 실행해버리면 영 좋지 않을 것이다.
- 따라서 dockerfile은 따로 빈 디렉토리 안에 만들어 놓고 build를 수행해야 한다.
참고 : 빌드할 때 불필요한 파일 제외하기
- 도커에서 빌드하면 빌드를 실행한 디렉토리 아래에 있는 모든 파일이 docker 데몬으로 전송된다.
- 빌드에서 제외하고 싶은 파일이 있는 경우, ".dockerignore" 라는 이름의 파일 안에 해당 파일명을 기술하면, 해당 파일은 제외된다.
- 여러 개의 파일을 지정할 때는 줄 바꿈을 해서 파일명을 나열한다.
- 경로 /test에 Dockerfile hello.txt 가 있는데 hello.txt는 제외하고 싶다면, 해당 경로에 .dockerignore를 만들고 내용에 hello.txt를 입력하면 된다.
- 만약 제외하도록 명시한 파일을 Dockerfile에 ADD 등으로 들어가게 하면, 도커 파일 빌드할 때 파일이 없다고 에러가 발생하므로 참고할 것.
2. docker history 명령
dockerfile을 빌드한 후 생성된 이미지에 대해 어떤 이미지가 순차적으로 만들어져 있고, 용량은 얼마이고, 이미지 ID는 무엇인지 등 상세한 정보를 확인할 수 있다.
#docker history 이미지명
- 이러한 docker history의 결과는 아래서부터 시작하여 맨 위가 끝인 순서로 기록된다.
- missing 부분은 base image의 history이다.
- 중요하게 봐야 할 것은 missing이 아닌 부분이며 이것들이 실제로 dockerfile에 기록된 각 step이다.
- 또한 CREATED BY 아래에 #(nop)라는 부분이 있는데, 그것의 의미는 명령어가 아닌 것들을 의미한다.
- 명령어는 "실행" 된다.
- 하지만 #(nop)가 있는 것은 "실행"하는 게 아니다.
- 예를 들어 ENV foo=bar 이런 것은 "실행"하는 것이 아님.
* Dockerfile과 Docker image
- Dockerfile 명령은 해당 스크립트를 build 할 때 각 항목들을 Image Layer 로서 중간 이미지들을 생성한다.
- 이렇게 하면 다른 이미지를 빌드할 때 이런 중간 이미지들을 내부적으로 재이용하여 빌드의 속도를 높이고 용량 낭비도 줄일 수 있다.
- 아래 예시를 통해 이미지가 어떻게 사용되는지 확인할 수 있다.
예시 : Dockerfile과 Docker image의 관계
ㆍ 사전 정보 1 : Dockerfile 내용
FROM ubuntu:16.04
RUN apt-get -y update && apt-get -y upgrade
RUN apt-get -y install nginx
EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
ㆍ 사전정보 2 : docker images 명령
- 사전정보 1에서는 ubuntu:16.04 이미지를 사용한다.
- 그리고 사전정보 2를 보면 이미 ubuntu 16.04 이미지를 이미 보유한 상태로 확인할 수 있다.
- 이미지 아이디는 005d2078bdfa 이다. 기억해두자.
- 이제 다음과 같이 빌드를 수행하면, 아래와 같은 Step을 진행한다.
Command
#docker build -t dockerfile_ubuntu-nginx .
Step 1/5 : FROM ubuntu:16.04
---> 005d2078bdfa
Step 2/5 : RUN apt-get -y update && apt-get -y upgrade
---> Running in 23ec84a0a536
Get:1 http://arcahive.ubuntu.com/ubuntu xenial Inrelease [247KB]
Processing triggers for libc-bin (2.23-0ubuntu11) ...
(중략)
Removing intermediate container 23ec84a0a536
---> 3d241e1c26f6
Step 3/5 : RUN apt-get install -y -q nginx
---> Running in a1a6eaaa9313
Reading package lists...
(중략)
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
Processing triggers for systemd (229-4ubuntu21.28) ...
Removing intermediate container a1a6eaaa9313
---> 90f723b65664
Step 4/5 : EXPOSE 80
---> Running in 38f032d07f6a
Removing intermediate container 38f032d07f6a
---> d62272ebb369
Step 5/5 : CMD ["nginx", "-g", "daemon off;"]
---> Running in 88d82f578ea5
Removing intermediate container 88d82f578ea5
---> c6dca2667105
- Dockerfile의 각 라인이 하나의 Step이 되며, 각 Step마다 붉은색으로 IMAGE ID가 생성되는 것을 확인할 수 있다.
- Step 1/5 를 보면, ubuntu:16.04를 받아야 하는데, 이미 보유하고 있으므로 다운로드하지 않는다.
- 또한 출력되는 IMAGE ID는 005d2078bdfa인데, 이 코드는 docker images의 결과로 나왔던 ubuntu 16.04 버전과 동일한 ID이다.
- 따라서 Dockerfile을 build할 때는 원래 있는 이미지는 재사용하는 것을 알 수 있다.
- 도커 이미지뿐만 아니라 위 1~5 Step의 모든 항목들은 이미지화되며, 이러한 이미지들을 저장해 두었다가 다른 Dockerfile에서 동일한 내용을 사용할 때 이미지를 재사용하는 것이다.
- 이렇게 모아져서 만들어진 최종 이미지인 dockerfile_ubuntu-nginx 는005d2078bdfa, 3d241e1c26f6, 90f723b65664, d62272ebb369, c6dca2667105 이미지들이 layer로 겹쳐져서 생성되는 것이다.
- dockerfile을 build할 때는, 각 항목을 실행하고 컨테이너를 만들고 컨테이너를 이미지화하고 컨테이너를 삭제하는 일련의 작업을 반복한다.
- 그래서 위처럼 이미지가 생성되는 것이다.
- 그런데 dockerfile을 build 할 때 실패하거나 중단하는 경우, docker images나 docker container ls에 이상한 것들이 있을 수 있다.
- 이것들은 위의 컨테이너 생성, 이미지화, 삭제 등의 일련의 진행 중 취소나 중단이 되었기 때문에 생기는 것이다.
- 이런 것들은 따로 삭제해주면 된다.
참고 : 도커 파일의 레이어 이미지 (중간 이미지) 개수를 줄이기
- 여러 가지 방법이 있는데, 대표적으로 RUN 명령이 여러 개라면 하나로 합칠 수 있다.
- 예를 들어, yum -y install httpd , yum -y install php 이렇게 2개라면, yum -y install httpd php 이렇게 합친다.
- 이런 식으로 명령어들을 제작자가 입맛에 맞춰 만들 수 있다. && 같은 다중 명령어 등도 사용할 수 있다.
'IT Technology > Cloud' 카테고리의 다른 글
도커 이미지란? Docker image ? (0) | 2021.04.22 |
---|---|
Dockerfile 상세 구문 (0) | 2021.04.17 |
Docker 단독 컨테이너 실행 실습하기 (0) | 2021.04.13 |
Docker 중요 명령어 (docker run) 운영체제, 소프트웨어 컨테이너 (0) | 2021.04.12 |
Docker 기본명령어(컨테이너 실행, 조작 명령) (0) | 2021.03.25 |