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)
참조 - 이재홍(http://pyrasis.com/book/DockerForTheReallyImpatient/Chapter04/02)
댓글 없음:
댓글 쓰기