2015년 3월 23일 월요일

Dockerfile 명령어 정리

1.1    Dockerfile

Dockerfile Docker 이미지 설정 파일입니다. Dockerfile에 설정된 내용대로 이미지를 생성합니다.
여러가지 명령을 토대로 기본 이미지에서 개발환경을 셋팅한 이미지를 생성할 수 있습니다.

1.1.1     FROM

FROM은 어떤 이미지를 기반으로 이미지를 생성할지 설정합니다. Dockerfile로 이미지를 생성할 때는 항상 기존에 있는 이미지를 기반으로 생성하기 때문에 FROM은 반드시 설정해야 합니다.

다음과 같이 이미지 이름을 설정하거나 이미지 이름과 태그를 함께 설정할 수도 있습니다. 이미지 이름만 설정하면 latest를 사용합니다. 또한, 이미지 이름은 생략할 수 없습니다.
FROM ubuntu:14.04

FROM <이미지> 또는 FROM <이미지>:<태그> 형식입니다.

앞에서 설명한 것처럼 FROM은 항상 설정해야 하고 맨 처음에 와야 합니다. 이미지를 생성할 때 FROM에 설정한 이미지가 로컬에 있으면 바로 사용하고, 없으면 Docker Hub에서 받아옵니다.

Dockerfile 파일 하나에 FROM을 여러 개 설정할 수 있습니다. FROM을 두 개 설정했다면 이미지가 두 개 생성됩니다. --tag 옵션으로 이미지 이름을 설정했다면 맨 마지막 FROM에 적용됩니다.

1.1.2     MAINTAINER

MAINTAINER는 이미지를 생성한 사람의 정보를 설정합니다. 형식은 자유이며 보통 다음과 같이 이름과 이메일을 입력합니다.
Dockerfile
MAINTAINER    Hong, Gildong <gd@yuldo.com>

MAINTAINER <작성자 정보> 형식입니다. MAINTAINER는 생략할 수 있습니다.

1.1.3     RUN

RUN FROM에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행합니다. 여기서 RUN으로 실행한 결과가 새 이미지로 생성되고, 실행 내역은 이미지의 히스토리에 기록됩니다.

(/bin/sh)로 명령 실행하기

Dockerfile
RUN apt-get install -y nginx
RUN echo "Hello Docker" > /tmp/hello
RUN curl -sSL https://golang.org/dl/go1.3.1.src.tar.gz | tar -v -C /usr/local -xz
RUN git clone https://github.com/docker/docker.git

RUN <명령> 형식이며 셸 스크립트 구문을 사용할 수 있습니다. FROM으로 설정한 이미지에 포함된 /bin/sh 실행 파일을 사용하게 되며 /bin/sh 실행 파일이 없으면 사용할 수 없습니다.

셸 없이 바로 실행하기

Dockerfile
RUN ["apt-get", "install", "-y", "nginx"]
RUN ["/user/local/bin/hello", "--help"]
RUN ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] 형식입니다. 실행 파일과 매개 변수를 배열 형태로 설정합니다. FROM으로 설정한 이미지의 /bin/sh 실행 파일을 사용하지 않는 방식입니다. 셸 스크립트 문법이 인식되지 않으므로 셸 스크립트 문법과 관련된 문자를 그대로 실행 파일에 넘겨줄 수 있습니다.

RUN으로 실행한 결과는 캐시되며 다음 빌드 때 재사용합니다. 캐시된 결과를 사용하지 않으려면 docker build 명령에서 --no-cache 옵션을 사용하면 됩니다.

1.1.4     CMD

CMD는 컨테이너가 시작되었을 때 스크립트 혹은 명령을 실행합니다. docker run 명령으로 컨테이너를 생성하거나, docker start 명령으로 정지된 컨테이너를 시작할 때 실행됩니다. CMD Dockerfile에서 한 번만 사용할 수 있습니다.

(/bin/sh)로 명령 실행하기

Dockerfile
CMD touch /home/hello/hello.txt
CMD <명령> 형식이며 셸 스크립트 구문을 사용할 수 있습니다. FROM으로 설정한 이미지에 포함된 /bin/sh 실행 파일을 사용하게 되며 /bin/sh 실행 파일이 없으면 사용할 수 없습니다.

셸 없이 바로 실행하기

Dockerfile
CMD ["redis-server"]
셸 없이 바로 실행할 때 매개 변수 설정하기

Dockerfile
CMD ["mysqld", "--datadir=/var/lib/mysql", "--user=mysql"]

CMD ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] 형식입니다. 실행 파일과 매개 변수를 배열 형태로 설정합니다. FROM으로 설정한 이미지의 /bin/sh 실행 파일을 사용하지 않는 방식입니다. 셸 스크립트 문법이 인식되지 않으므로 셸 스크립트 문법과 관련된 문자를 그대로 실행 파일에 넘겨줄 수 있습니다.

ENTRYPOINT를 사용하였을 때

Dockerfile
ENTRYPOINT ["echo"]
CMD ["hello"]
CMD ["<매개 변수1>", "<매개 변수2>"] 형식입니다. ENTRYPOINT에 설정한 명령에 매개 변수를 전달하여 실행합니다. Dockerfile ENTRYPOINT가 있으면 CMD ENTRYPOINT에 매개 변수만 전달하는 역할을 합니다. 그래서 CMD 독자적으로 파일을 실행할 수 없게 됩니다.

1.1.5     EXPOSE

EXPOSE는 호스트와 연결할 포트 번호를 설정합니다. docker run 명령의 --expose 옵션과 동일합니다.

Dockerfile
EXPOSE 80
EXPOSE 443
EXPOSE 80 443
EXPOSE <포트 번호> 형식입니다. EXPOSE 하나로 포트 번호를 두 개 이상 동시에 설정할 수도 있습니다.

EXPOSE는 호스트와 연결만 할 뿐 외부에 노출은 되지 않습니다. 포트를 외부에 노출하려면 docker run 명령의 -p, -P 옵션을 사용해야 합니다.

1.1.6     WORKDIR

RUN, CMD and ENTRYPOINT에서 설정한 실행 파일이 실행될 디렉터리입니다.
WORKDIR /path/to/workdir


1.1.7     ENV

ENV는 환경 변수를 설정합니다. ENV로 설정한 환경 변수는 RUN, CMD, ENTRYPOINT에 적용됩니다.

Dockerfile
ENV GOPATH /go
ENV PATH /go/bin:$PATH
ENV <환경 변수> <> 형식입니다. 환경 변수를 사용할 때는 $를 사용하면 됩니다.

환경 변수는 docker run 명령에서도 설정할 수 있습니다.
$ sudo docker run -e HELLO=4321 example
4321
-e <환경 변수>=<> 형식입니다. -e 옵션은 여러 번 사용할 수 있고, --env 옵션과 같습니다.

1.1.8     ADD

ADD는 파일을 이미지에 추가합니다.

Dockerfile
ADD hello-entrypoint.sh /entrypoint.sh
ADD http://example.com/hello.txt /hello.txt
ADD *.txt /root/

ADD <복사할 파일 경로> <이미지에서 파일이 위치할 경로> 형식입니다.

<복사할 파일 경로>는 컨텍스트 아래를 기준으로 하며 컨텍스트 바깥의 파일, 디렉터리나 절대 경로는 사용할 수 없습니다.
) ADD ../hello.txt /home/hello (X)
) ADD /home/hello/hello.txt /home/hello (X)
<복사할 파일 경로>는 파일뿐만 아니라 디렉터리도 설정할 수 있으며, 디렉터리를 지정하면 디렉터리의 모든 파일을 복사합니다. 또한, 와일드카드를 사용하여 특정 파일만 복사할 수 있습니다.
) ADD *.txt /root/
<복사할 파일 경로>에 인터넷에 있는 파일의 URL을 설정할 수 있습니다.
<이미지에서 파일이 위치할 경로>의 마지막에 /가 있으면 디렉터리가 생성되고 파일은 그 아래에 복사됩니다. ADD http://example.com/hello.txt /home/hello/ 와 같이 설정하면 /home/hello/hello.txt에 파일이 복사됩니다.
로컬에 있는 압축 파일(tar.gz, tar.bz2, tar.xz)은 압축을 해제하고 tar를 풀어서 추가됩니다. , 인터넷에 있는 파일 URL은 압축만 해제한 뒤 tar 파일이 그대로 추가됩니다.
) ADD hello.tar.gz / (압축을 해제하고 tar를 풀어서 추가합니다.)
) ADD http://zlib.net/zlib-1.2.8.tar.gz / (gzip 압축만 해제한 뒤 tar 파일을 추가합니다. 단 파일 내용은 tar이지만 파일 이름은 zlib-1.2.8.tar.gz처럼 .gz가 붙어있습니다.)
<이미지에서 파일이 위치할 경로>는 항상 절대 경로로 설정해야 합니다. 그리고 마지막이 /로 끝나면 디렉터리가 생성되고 파일은 그 아래에 복사됩니다.
ADD ./ /hello와 같이 현재 디렉터리를 추가할 때 .dockerignore 파일에 설정한 파일과 디렉터리는 제외됩니다.

ADD로 추가되는 파일은 소유자(UID) 0, 그룹(GID) 0으로 설정되고 권한은 기존 파일의 권한을 따릅니다. URL로 추가하면 권한은 600으로 설정됩니다.

1.1.9     COPY

COPY는 파일을 이미지에 추가합니다. ADD와는 달리 COPY는 압축 파일을 추가할 때 압축을 해제하지 않고, 파일 URL도 사용할 수 없습니다.

Dockerfile
COPY hello-entrypoint.sh /entrypoint.sh
COPY hello-dir /hello-dir
COPY zlib-1.2.8.tar.gz /zlib-1.2.8.tar.gz
COPY *.txt /root/
COPY <복사할 파일 경로> <이미지에서 파일이 위치할 경로> 형식입니다.

<복사할 파일 경로>는 컨텍스트 아래를 기준으로 하며 컨텍스트 바깥의 파일, 디렉터리나, 절대 경로는 사용할 수 없습니다.
) COPY ../hello.txt /home/hello (X)
) COPY /home/hello/hello.txt /home/hello (X)
<복사할 파일 경로>는 파일뿐만 아니라 디렉터리도 설정할 수 있으며, 디렉터리를 지정하면 디렉터리의 모든 파일을 복사합니다. 또한, 와일드카드를 사용하여 특정 파일만 복사할 수 있습니다.
) COPY *.txt /root/
<복사할 파일 경로>에 인터넷에 있는 파일의 URL은 사용할 수 없습니다.
압축 파일은 압축을 해제하지 않고 그대로 복사됩니다.
<이미지에서 파일이 위치할 경로>는 항상 절대 경로로 설정해야 합니다. 그리고 마지막이 /로 끝나면 디렉터리가 생성되고 파일은 그 아래에 복사됩니다.
COPY ./ /hello와 같이 현재 디렉터리를 추가할 때 .dockerignore 파일에 설정한 파일과 디렉터리는 제외됩니다.
COPY로 추가되는 파일은 소유자(UID) 0, 그룹(GID) 0으로 설정되고 권한은 기존 파일의 권한을 따릅니다.

1.1.10  ENTRYPOINT

ENTRYPOINT는 컨테이너가 시작되었을 때 스크립트 혹은 명령을 실행합니다. docker run 명령으로 컨테이너를 생성하거나, docker start 명령으로 정지된 컨테이너를 시작할 때 실행됩니다. ENTRYPOINT Dockerfile에서 단 한번만 사용할 수 있습니다
CMD ENTRYPOINT는 컨테이너가 생성될 때 명령이 실행되는 것은 동일하지만 docker run 명령에서 동작 방식이 다릅니다.
run <이미지> <실행할 파일> 형식인데 이미지 다음에 실행할 파일을 설정할 수 있습니다. docker run 명령에서 실행할 파일을 설정하면 CMD는 무시됩니다.

1.1.11  VOLUME

VOLUME은 디렉터리의 내용을 컨테이너에 저장하지 않고 호스트에 저장하도록 설정합니다. 6.4 Docker 데이터 볼륨 사용하기에서 설명한 내용과 같습니다.

Dockerfile
VOLUME /data
VOLUME ["/data", "/var/log/hello"]
VOLUME <컨테이너 디렉터리> 또는 VOLUME ["컨테이너 디렉터리 1", "컨테이너 디렉터리2"] 형식입니다. /data처럼 바로 경로를 설정할 수도 있고, [/data, /var/log/hello]처럼 배열 형태로 설정할 수도 있습니다. , VOLUME으로는 호스트의 특정 디렉터리와 연결할 수는 없습니다.

데이터 볼륨을 호스트의 특정 디렉터리와 연결하려면 docker run 명령에서 -v 옵션을 사용해야 합니다.

$ sudo docker run -v /root/data:/data example
옵션은 -v <호스트 디렉터리>:<컨테이너 디렉터리> 형식입니다.

1.1.12  USER

USER는 명령을 실행할 사용자 계정을 설정합니다. RUN, CMD, ENTRYPOINT에 적용됩니다.

USER nobody
USER <계정 사용자명> 형식입니다.

USER 뒤에 오는 모든 RUN, CMD, ENTRYPOINT에 적용되며, 중간에 다른 사용자를 설정하여 사용자를 바꿀 수 있습니다.

1.1.13  ONBUILD

ONBUILD는 생성한 이미지를 기반으로 다른 이미지가 생성될 때 명령을 실행(trigger)합니다. 최초에 ONBUILD를 사용한 상태에서는 아무 명령도 실행하지 않습니다. 다음 번에 이미지가 FROM으로 사용될 때 실행할 명령을 예약하는 기능이라 할 수 있습니다.

Dockerfile
ONBUILD RUN touch /hello.txt
ONBUILD ADD world.txt /world.txt
ONBUILD <Dockerfile 명령> <Dockerfile 명령의 매개 변수> 형식입니다. FROM, MAINTAINER, ONBUILD를 제외한 모든 Dockerfile 명령을 사용할 수 있습니다.

ONBUILD는 이미지를 생성한 뒤 해당 이미지를 기반으로 커스터마이징을 할 때 활용할 수 있습니다.

다음과 같이 ONBUILD를 사용하여 RUN touch /hello.txt를 실행하도록 설정합니다.

Dockerfile
FROM ubuntu:latest
ONBUILD RUN touch /hello.txt
docker build 명령으로 example 이미지를 생성한 뒤 docker run 명령으로 컨테이너를 생성합니다. 컨테이너의 Bash 셸이 실행되면 ls 명령으로 /의 파일 목록을 출력합니다.

$ sudo docker build --tag example .
$ sudo docker run -i -t example /bin/bash
root@891ccb6749e9:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
ONBUILD로 설정했기 때문에 example 이미지에는 /hello.txt 파일이 생성되지 않았습니다.

이제 FROM을 사용하여 example 이미지를 기반으로 새 이미지를 생성합니다.

Dockerfile
FROM example
docker build 명령으로 example2 이미지를 생성한 뒤 docker run 명령으로 컨테이너를 생성합니다. 컨테이너의 Bash 셸이 실행되면 ls 명령으로 /의 파일 목록을 출력합니다.

$ sudo docker build --tag example2 .
생략
root@874d3e1fdd6f:/# ls
bin  boot  dev  etc  hello.txt  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
docker build 명령을 실행할 때 # Executing 1 build triggers라고 출력되고 그 아래부터 ONBUILD로 설정한 명령이 실행됩니다. 이제 ONBUILD를 통해 example2 이미지에 /hello.txt 파일이 생성되었습니다.


ONBUILD는 바로 아래 자식 이미지를 생성할 때만 적용되고, 손자 이미지에는 적용되지 않습니다. ONBUILD 설정은 상속되지 않습니다.

참조 - 이재홍(http://pyrasis.com/book/DockerForTheReallyImpatient/Chapter04/02)

댓글 없음:

댓글 쓰기