Dockerfile Reference 1장

Image credit: docker.com

Dockerfile Reference 1장

1. Usage

docker build 커맨드는 Dockerfile과 context로부터 이미지를 생성한다.
build의 context에는 file의 구체적인 위치(PATH나 URL)가 있어야 한다. PATH는 로컬 파일시스템에 위치한 디렉토리 일 것이고, URL은 git repository가 될 것이다.
Context는 재귀적으로 처리된다. 따라서 PATH에는 하위 디렉토리가 포함되며, URL에는 저장소와 하위 모듈이 포함된다.

$ docker build .
Sending build context to Docker daemon  6.51 MB
...

빌드는 CLI가 아니라, Docker daemon에 의해서 실행된다. 빌드 절차에서 맨 처음으로 행해지는 것은 전체 context를 Docker daemon에 전송하는 것이다.
그리고 Dockerfile을 작성하는 방법에서 언급한 바대로 디렉토리에는 Dockerfile을 빌드하는 데 필요한 최소한의 파일만 유지해주는 것이 좋다.

주의할 점 : PATH를 입력할 때 ROOT 디렉토리를 사용하지말자. 이는 Docker daemon에 당신의 하드에 있는 내용 전체를 전송하게될 것이다.

관례상 Dockerfile은 Context의 root에 있다. docker build 명령어에 -f 플래그를 사용하여 파일 시스템 어딘가에 있는 Dockerfile을 가리킬 수 있다.

$ docker build -f /path/to/a/Dockerfile .

빌드가 성공하면 새 이미지를 저장할 저장소와 태그를 지정할 수 있다.

$ docker build -t shykes/myapp .
$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .

각 명령은 독립적으로 실행되므로 RUN cd /tmp는 다음 명령어에 영향을 미치지 않는다.
가능하다면 Docker는 캐시를 사용하여 docker build 단계를 가속화한다. 캐시 사용 메세지는 콘솔로 출력된다.

예시

$ docker build -t svendowideit/ambassador .
Sending build context to Docker daemon 15.36 kB
Step 1 : FROM alpine:3.2
 ---> 31f630c65071
Step 2 : MAINTAINER SvenDowideit@home.org.au
 ---> Using cache
 ---> 2a1c91448f5f
Step 3 : RUN apk update &&      apk add socat &&        rm -r /var/cache/
 ---> Using cache
 ---> 21ed6e7fbb73
Step 4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
 ---> Using cache
 ---> 7ea8aef582cc
Successfully built 7ea8aef582cc

2. Format

Dockerfile의 포맷은 다음과 같다.

# Comment
INSTRUCTION arguments

명령어는 대소문자를 구분하지 않지만, 대문자로 쓰게 되면 아규먼트와 쉽게 구분할 수 있다. (그러니까 가급적 대문자를 쓰자.)
Docker는 Dockerfile에 정렬된 순서대로 명령어를 실행한다. 생성하려는 이미지의 기본 이미지를 알 수 있도록 첫 명령어는 FROM 이어야만 한다.
Docker는 #로 시작하는 행을 주석으로 처리하며, #이 중간에 위치할 경우에는 인수로 처리된다.

# Comment
RUN echo 'we are running some # of cool things'

3. Parser directives

Parser 지시문은 선택 사항이며, Dockerfile의 다음 명령행을 처리하는 방법에 영향을 준다. Parser 지시문은 빌드에 레이어를 추가하지 않으며, 빌드 단계에 표시되지도 않는다.
Parser 지시문은 # directive=value 형태로 작성된다. 단일 지시문은 한 번만 사용할 수 있다.

주석이나 빈 줄 또는 빌더 명령행이 처리되고나면 Docker는 더 이상 Parser 지시문을 찾지 않는다. 대신 Parser 지시문 형식으로 작성된 모든 것들을 주석으로 처리하고, Parser 지시문인지 확인하지 않는다.
따라서 모든 Parser 지시문은 Dockerfile 맨 위에 위치해야한다.

Parser 지시문은 대소문자를 구분하지 않지만, 관례상 소문자를 사용하며, Parser 지시문 다음에 빈 줄을 포함한다. 행을 연결하는 문자(백슬래시)는 Parser 지시문에서 지원되지 않는다.

  • 백슬래시때문에 유효하지 않은 경우
# direc \  
tive=value  
  • 중복 게재로 인해 유효하지 않은 경우
# directive=value1  
# directive=value2  

FROM ImageName  
  • 빌더 명령행 이후에 게재하여 유효하지 않은 경우
FROM ImageName  
# directive=value  
  • 주석 뒤에 작성되서, Parser 지시문이 아닌 주석으로 처리되는 경우
# About my dockerfile  
FROM ImageName  
# directive=value  
  • 다음과 같은 경우 unknown parser는 인식되지 않기 때문에 주석으로 처리된다. 또한 known parser는 주석 뒤에 작성되어 주석으로 처리된다.
# unknowndirective=value  
# knowndirective=value  
  • 줄 바꿈을 하지않은 공백은 Parser 지시문에서 사용할 수 있다. 따라서 다음 줄은 모두 동일하게 취급된다.
#directive=value  
# directive =value  
#	directive= value  
# directive = value  
#	  dIrEcTiVe=value  

아래와 같은 Parser 지시문이 지원된다.

  • escape

4. escape

# escape=\ (backslash)  

Or

# escape=` (backtick)  

escape 지시문은 Dockerfile에서 사용할 escape 문자를 설정한다. 만일 지정하지 않았다면 기본 escape 문자는 백슬래시이다.
escape 문자는 개행을 escape 하는 데에도 사용된다. 이런 용도로 사용될 때에는 Dockerfile 명령어가 여러 줄에 걸쳐있을 수 있다.
Windows 운영체제에서는 백슬래시가 파일구분자이기때문에 escape 문자를 ` (backtick)으로 설정하는 것이 유용하다.

FROM windowsservercore  
COPY testfile.txt c:\\  
RUN dir c:\  

Results in:

PS C:\John> docker build -t cmd .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM windowsservercore
 ---> dbfee88ee9fd
Step 2 : COPY testfile.txt c:RUN dir c:
GetFileAttributesEx c:RUN: The system cannot find the file specified.
PS C:\John>

# escape=`

FROM windowsservercore
COPY testfile.txt c:\
RUN dir c:\

Results in:

PS C:\John> docker build -t succeeds --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM windowsservercore
 ---> dbfee88ee9fd
Step 2 : COPY testfile.txt c:\
 ---> 99ceb62e90df
Removing intermediate container 62afbe726221
Step 3 : RUN dir c:\
 ---> Running in a5ff53ad6323
 Volume in drive C has no label.
 Volume Serial Number is 1440-27FA

 Directory of c:\

03/25/2016  05:28 AM    <DIR>          inetpub
03/25/2016  04:22 AM    <DIR>          PerfLogs
04/22/2016  10:59 PM    <DIR>          Program Files
03/25/2016  04:22 AM    <DIR>          Program Files (x86)
04/18/2016  09:26 AM                 4 testfile.txt
04/22/2016  10:59 PM    <DIR>          Users
04/22/2016  10:59 PM    <DIR>          Windows
               1 File(s)              4 bytes
               6 Dir(s)  21,252,689,920 bytes free
 ---> 2569aa19abef
Removing intermediate container a5ff53ad6323
Successfully built 2569aa19abef
PS C:\John>

5. Environment replacement

ENV문으로 선언된 환경 변수는 Dockerfile의 특정 명령에서 인수로 사용될 수 있다.
환경변수는 $variable_name 또는 ${variable_name} 을 사용하여 Dockerfile에 작성된다.

  • ${variable : -word}는 변수가 설정되면 결과가 그 값이됨을 나타낸다. 변수가 설정되지 않으면 단어가 결과가 된다.
  • ${variable : + word}는 변수가 설정되면 단어가 결과임을 나타내고, 그렇지 않으면 결과가 빈 문자열임을 나타낸다.
    word는 모든 환경 변수를 포함하여 모든 문자열이 가능하다.

예시

FROM busybox
ENV foo /bar
WORKDIR ${foo}   # WORKDIR /bar
ADD . $foo       # ADD . /bar
COPY \$foo /quux # COPY $foo /quux

다음과 같은 Dockerfile의 명령어 리스트에서 환경변수가 지원된다.

  • ADD
  • COPY
  • ENV
  • EXPOSE
  • LABEL
  • USER
  • WORKDIR
  • VOLUME
  • STOPSIGNAL
  • ONBUILD (위에 있는 명령어 리스트중 하나와 결합되는 경우)

예시

ENV abc=hello
ENV abc=bye def=$abc
ENV ghi=$abc

위의 결과로 def는 hello 값을 가지고, ghi는 bye 값을 갖는다.

위 글은 Docker 공식사이트에서 제공하는 문서기준으로 작성되었습니다.

comments powered by Disqus