Script - Dockerfile
Script - Dockerfile
Dockerfile은 도커 이미지를 만들기 위해 필요한 기본 명령들을 지정하기 위한 Script이다.
이러한 명령들로 이미지가 만들어지고, 이미지가 실행되면 Dockerfile
에 명시해둔 명령들이 실행된 채로 컨테이너가 되기 때문에 배포에 상당히 유리한 전략임을 알 수 있다.
그래서 이러한 Dockerfile을 사용하기 위해 Docker
공식 문서를 보며 Dockerfile의 Instruction
(이하 명령 or 명령어)을 이해해보자.
Dockerfile
도커는 Dockerfile
의 명령에 따라 이미지를 자동으로 빌드할 수 있다.
docker build
를 사용하면 여러 명령 줄 명령을 연속적으로 실행하는 자동화된 빌드를 만들 수 있다.
지금부터 Dockerfile
에서 사용할 수 있는 명령들을 살펴보자.
사용법
Dockerfile
에 설정된 내용에 따라 이미지를 생성한다.
여러가지 명령어를 토대로 기본 이미지에서 개발 환경을 셋팅한 이미지를 생성할 수 있다.
docker build
명령어는 Dockerfile
과 Context
로부터 이미지를 만들어낸다.
Context
는 구체적인 PATH
or URL
에있는 파일의 집합이다.
즉, 쉽게 이야기해서 현재 작업 디렉토리나 저장소 주소를 Build Context
라고 부른다.
PATH
는 로컬 파일 시스템에서 디렉토리를 의미하며, URL
은 깃 레포지토리 주소를 의미한다.
Context
는 재귀적으로 호출되어지는데, PATH
는 하위 디렉토리가 포함되며 URL
에는 저장소 및 해당 하위 모듈이 포함된다.
$ docker build .
Sending build context to Docker daemon 6.51 MB
...
이 빌드는 도커 데몬에서 실행된다. 빌드가 시작되고 가장 처음 시작되는 작업은 전체 Context
를 데몬으로 보내는 것이다.
공식문서에 따르면 대부분의 경우에서는 빈 디렉토리를 Context
로 시작하고 그 디렉토리에 Dockerfile
을 위치시키고 빌드에 필요한 파일만 추가하는 것을 권장하고 있다.
Dockerfile
은 Build Context
에서 파일을 사용하기 위해 COPY
와 같은 구체적인 명렁어들을 제공해준다.
그리고 빌드 성능을 높이기 위해 Context Directory
에 .dockerignore
을 추가함으로써 파일이나 폴더를 제외할 수 있다고 한다.
일반적으로 도커파일은 Context
의 루트에 위치되어진다.
-f
태그를 사용하면 docker build
할 때 Dockerfile
의 명시적인 위치를 지정해주는 것이 가능하다고 한다.
docker build -f /path/to/a/Dockerfile .
또한 -t
태그를 사용하여 빌드가 성공하면 새로운 이미지를 저장할 저장소와 태그를 지정할 수 있다.
$ docker build -t shykes/myapp .
빌드 후 여러 저장소에 이미지를 태그하려면 -t
를 여러번 파라미터로 줘서 빌드할 수 있다.
docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
도커 데몬은 Dockerfile
에 명령어를 실행하기 전에 Dockerfile
의 예비 검증을 수행하고 만약 구문이 잘못되었다면 에러를 반환한다.
$ docker build -t test/myapp .
Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD
도커 데몬은 Dockerfile
의 명령어를 하나 하나 실행하고 필요한 경우 각 명령의 결과를 이미지에 반영한다.
중요한 점은 각 명령들은 독립적으로 수행하면서 새로운 이미지를 만들어내기 때문에 Run cd /tmp
같은 명령들이 다음 명령에 영향을 미치지 않는다.
또한 가능하다면 도커는 중간 이미지를 캐싱해놓고 재사용하여 docker build
프로세스의 성능을 크게 가속화한다.
빌드 캐쉬는 로컬 상위 체인이 있는 이미지에만 사용된다.
BuildKit
BuildKit은 도커 버전 18.09부터 지원하며 빌드를 실행하기 위한 새로운 백엔드 지원 도구이다.
Buildkit이 작동되는 것을 직접 보고 싶다면 위의 유튜브로 가서 확인해보도록 하자.
사용법은 아주 간단한데, 환경변수로 다음과 같이 설정함으로써 BuildKit을 사용할 수 있다.
// 아마 1이 ON, 0이 OFF 뭐 그런건가보다.
export DOCKER_BUILDKIT=1
BuildKit을 사용하면서 얻을 수 있는 이점은 다음과 같다.
사용하지않는 빌드 단계 건너뛰기
독립적인 빌드 단계를 병렬적으로 빌드
Build Context
에서 변경된 파일만 점진적으로 반영Build Context
에 사용하지 않는 파일 전송 감지 및 건너 뛰기많은 새로운 기능과 함께 외부 도커파일 구현 사용
잔여 API로 인한 사이드 이펙트 방지
자동 정리를 위해 빌드 캐시 우선순위 지정
Format
도커 명령어의 포멧은 다음과 같다.
INSTRUCTION arguments
명령은 대소문자를 구분하지는 않는다.
그러나 일반적으로는 명령은 대문자로 하는 것이 국룰
이라고 한다.
도커는 Dockerfile
의 명령어를 순차적으로 수행한다.
그리고 Dockerfile
은 반드시 FROM
명령어와 함께 시작되어야만 한다.
FROM
명령어는 부모 이미지를 지정한다.
FROM
앞에는 하나 또는 그 이상의 ARG
명령만 존재할 수 있다.
ARG
는 Dockerfile
의 FROM
에서 사용되는 인수를 선언할 수 있다.
가장 앞에 #
이 오면 주석이고, 다른 곳에서는 인수로 취급된다.
# Comment
RUN echo 'we are running some # of cool things'
위에서 #
은 주석이며 echo 이후에 오는 #
은 argument
이다.
Parser Directives
Parser Directives
는 Dockerfile
의 다음 줄 처리되는 명령에 영향을 줄 수 있는 옵션이다.
Parser Directives
는 일반적으로 # directive = value
와 같은 특수한 유형의 주석으로 작성된다.
또한 Parser Directives
는 빌드에 레이어를 추가하지않으며, 빌드 단계에 표시되지 않는다.
빈줄이나 빌더 명령어가 실행되면 도커는 더 이상 Parser Directives
를 찾지 않는다.
그러므로 모든 Parser Directives
는 Dockerfile
의 최상단에 위치시키는 것이 일반적이다.
Parser Directives
는 대소문자를 구분하지는 않지만, 일반적으로는 소문자로 작성되는 컨벤션을 갖고 있다.
또한 컨벤션으로 줄 바꿈을 하지 않으면 올바르지 않은 문법이라고 한다.
다음은 올바르지않은 Parser Directives
의 예시다.
# direc \
tive=value
줄바꿈이 안되서 올바르지않은 문법이다.
# directive=value1
# directive=value2
FROM ImageName
역시나 줄바꿈이 안되고 연속적으로 Parser Directives
가 선언되었다.
FROM ImageName
# directive=value
FROM
이 이미 수행됐기 때문에 주석으로 처리된다.
# About my dockerfile
# directive=value
FROM ImageName
주석 다음에 왔기 때문에 Parser Directives
가 아닌 주석으로 처리된다.
# unknowndirective=value
# knowndirective=value
알려지지 않은 Parser Directives
는 일반적으로 주석처리된다.
주석처리된 이후에 등장한 Parser Directives
역시 주석으로 처리된다.
#directive=value
# directive =value
# directive= value
# directive = value
# dIrEcTiVe=value
Syntax
# syntax=[remote image reference]
# syntax=docker/dockerfile
# syntax=docker/dockerfile:1.0
# syntax=docker.io/docker/dockerfile:1
# syntax=docker/dockerfile:1.0.0-experimental
# syntax=example.com/user/repo:tag@sha256:abcdef...
이 기능은 Buildkit이 사용될때만 활성화된다.
syntax 구문은 현재 도커파일에서 빌드하기 위해 사용되는 도커 파일 빌더의 위치를 정의한다.
BuildKit은 도커 이미지로 배포된 외부 빌더의 구현을 사용하는 것을 원활하게 사용할 수 있다.
Official releases
도커는 도커허브의 docker/dockerfile 저장소에 Dockerfile
을 빌드하는데 사용할 수 있는 공식 버전의 이미지를 배포한다.
새로운 이미지가 Release가 된 두가지 채널이 있다.
한 채널은 Stable
이고, 한 채널은 Experimental
한 경우다.
Stable
채널은 semantic 버져닝을 따른다. 예를들면,
docker/dockerfile:1.0.0 - only allow immutable version 1.0.0
docker/dockerfile:1.0 - allow versions 1.0.*
docker/dockerfile:1 - allow versions 1..
docker/dockerfile:latest - latest release on stable channel
Experimental
채널은 Release 시점의 Stable
채널로의 메이저와 마이너 컴포넌트를 갖는 점진적인 버저닝을 사용한다.
예를들어,
docker/dockerfile:1.0.1-experimental - only allow immutable version 1.0.1-experimental
docker/dockerfile:1.0-experimental - latest experimental releases after 1.0
docker/dockerfile:experimental - latest release on experimental channel
필요에 가장 적합한 채널을 선택해야한다.
만약 단지 버그픽스를 원한다면 (핫픽스) docker/dockerfile:1.0
을 사용해야한다.
만약 실험적 기능을 활용하고자 한다면, Experimental
채널을 사용하는 편이 좋을 것이다.
만약 Experimental
채널을 사용한다면 최신 버전과 이전 버전이 호환되지 않을 수 있기 때문에 변경 불가능한 다른 정식버전을 사용하는 것을 추천한다.
escape
# escape=\ (backslash)
or
# escape=` (backtick)
escape
구문은 Dockerfile
에서 escape 문자를 사용하기 위한 문자를 설정한다.
따로 설정하지않으면 Default escape 문자는 \
이다.
escape
문자는 줄의 문자를 escape하고 새로운 줄로 escape하는데 사용되어진다.
이는 Dockerfile
명령어가 여러 줄로 확장하는 것을 허락한다.
escape Parser Directive
가 Dockerfile
에 포함되어지 여부와 관계없이 줄 끝을 제외하고 escape
는 RUN 명령에서 수행되지 않는다.
FROM microsoft/nanoserver
COPY testfile.txt c:\\
RUN dir c:\
위 명령에서 COPY와 RUN은 함께 실행된다.
Environment Replacement
환경 변수는 또한 Dockerfile
에 의해 해석되어지는 변수로써 특정 명령에서 사용될 수 있다.
변수형 구문을 문자 그대로 명령문에 포함시키 위해 escape
또한 처리된다.
환경 변수는 Dockerfile
내에서 $variable_name
또는 ${variable_name}
으로 선언되어진다.
이 둘은 동등하게 취급되며 중괄호 구문은 일반적으로 ${foo}_bar
와 같이 공백이 없는 변수 이름을 해결하는데 사용된다.
{variable_name}
구문은 몇가지 표준 bash modifiers
를 제공한다.
${variable:-word}
는 만약variable
이 설정됐다면 그 결과는 값이 될 것이다. 만약 변수가 설정되지 않으면word
가 결과가 될 것이다.${variable:+word}
는 만약variable
이 설정되었다면word
가 결과가 될 것이다. 그렇지 않으면 결과는 빈 문자열이 될 것이다.
모든 경우에서 word
는 추가 환경변수를 포함하여 모든 문자열이 될 수 있다.
escape는 변수 앞에 \
를 붙이는 것으로 가능하다.
FROM busybox
ENV foo /bar
WORKDIR ${foo} # WORKDIR /bar
ADD . $foo # ADD . /bar
COPY \$foo /quux # COPY $foo /quux
환경 변수는 다음 명령어 목록에서 지원된다.
ADD
COPY
ENV
EXPOSE
FROM
LABEL
STOPSIGNAL
USER
VOLUME
WORKDIR
환경 변수 대체는 전체 명령어에서 각 변수에 대해 동일한 값을 사용한다.
예를들어,
ENV abc=hello
ENV abc=bye def=$abc
ENV ghi=$abc
여기서 def
는 bye가 아닌 hello를 반환한다.
하지만 ghi
는 bye를 반환한다.
.dockerignore file
도커 CLI는 도커 데몬으로 context를 전송하기 이전 .dockerignore
이름을 가진 파일이 context의 루트 디렉토리에 있는지 찾는다.
만약 이 파일이 존재한다면 CLI는 패턴과 일치하는 파일 및 디렉토리를 제외하도록 context를 수정한다.
이것은 데몬에 불필요한 거대하고 예민한 파일과 폴더를 보내고 잠재적으로 그것들을 ADD
와 COPY
를 사용해서 이미지에 추가하는 것을 방지하는데 도움을 준다.
# comment
*/temp*
*/*/temp*
temp?
#
은 주석이며 첫행은 무시된다.
이후 두번째 줄은 현재 루트에 존재하는 모든 디렉토리에 temp를 prefix로 갖는 파일과 디렉토리를 모두 제외시킨다.
가령 /somedir/temporary.txt같은 파일이나 /somedir/temp같은 디렉토리가 그 예이다.
temp?에서 ?는 한 문자를 나타내는데 가령 /tempa 라던지 /tempb 같은 것들이 해당된다.
*.md
!README.md
!는 해당 파일을 제외하지 않겠다는 것을 의미한다.
즉 모든 .md 파일을 무시하지만 README.md 만큼은 살려두라는 의미이다.
FROM
FROM [--platform=<platform>] <image> [AS <name>]
or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
FROM
명령어는 새 빌드 단계를 초기화하고 후속 명령어에 대한 기본 이미지를 설정한다.
위와 같이 valid한 Dockerfile
은 반드시 FROM
명령어로 시작한다.
FROM
은 특히 공용 저장소로부터 이미지를 가져와서 시작하는 것을 쉽게 만들어준다.
ARG
는FROM
이전에 위치할 수 있는 유일한 명령어다.FROM
은 하나의Dockerfile
내부에 여러 이미지를 생성하거나 다른 것에 의존적인 하나의 빌드 단계를 사용하기 위해 여러번 나타날 수 있다. 각FROM
명령어는 이전 명령어들에 의해 만들어진 어떠한 상태도 지운다.
ARG와 FROM의 상호작용 이해
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD /code/run-app
FROM extras:${CODE_VERSION}
CMD /code/run-extras
FROM
명령은 첫번째 FROM
이전에 발생한 모든 ARG
명령에 의해 선언된 변수를 지원한다.
첫번째 FROM
이후 어떤 명령에도 ARG
명령으로 생성된 변수를 사용할 수 없다.
만약 FROM
이전에 만든 변수를 재사용 하고 싶다면 아래와 같이 가능하다.
ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version
RUN
RUN
은 두가지 형태를 갖는다.
RUN
는 쉘에서 실행된다. RUN [“executable”, “param1”, “param2”]
RUN
명령은 현재 이미지 위에 새로운 레이어에서 어떠한 명령어든 실행한다. 그리고 결과를 커밋한다.
커밋된 결과 이미지는 Dockerfile
의 다음 단계에서 사용되어진다.
백슬래시를 사용해서 다음과 같은 두 명령을 연속해서 실행할 수 있다.
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
이는 아래의 한줄과 동일하다.
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
CMD
CMD 명령은 세가지 형태를 가진다.
CMD [“executable”,”param1”,”param2”]
CMD [“param1”,”param2”]
CMD command param1 param2
Dockerfile
에서 하나의 CMD
명령만이 존재할 수 있다.
만약 둘 이상의 CMD
명령을 나열한다면 마지막 하나만 실행된다.
CMD
의 주요한 목적은 실행중인 컨테이너에 defaults
를 제공하는 것이다.
이러한 defaults
들은 실행을 포함할 수 있다. 또는 실행을 생략할 수 있다.
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL
명령은 이미지에 메타데이터를 더하는 명령어이다.
LABLE
은 key-value의 페어이다. LABEL
변수 안에 공백을 포함하기 위해서 따옴표와 백슬래시를 사용하라.
아래는 사용 예시이다.
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
이미지는 하나 이상의 라벨을 가질 수 있다. 또한 한 줄에 여러개의 라인을 명시할수 있다.
아래는 예시이다.
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
기본 또는 상위 이미지(FROM 행의 이미지)에 포함된 LABEL
이미지에 의해 상속되어진다.
만약 라벨이 이미 다른 값으로 존재한다면 가장 최근에 추가된 값이 이전에 셋팅된 값에 오버라이딩 되어진다.
EXPOSE
EXPOSE <port> [<port>/<protocol>...]
EXPOSE
명령은 도커에게 컨테이너가 런타임에 지정된 포트에서 수신을 대기한다는 것을 알려준다.
그래서 TCP나 UDP에서 리슨되는 포트가 어디인지 명시할 수 있다.
그리고 만약 프로토콜을 명시하지않으면 기본 값은 TCP이다.
EXPOSE
명령은 실제로 포트를 열지는 않는다.
이미지를 빌드하는 사람과 컨테이너를 실행하는 사람 사이에 공개 할 포트에 대한 일종의 문서로 동작한다.
실질적으로 컨테이너가 동작할 때 하나 또는 그 이상의 포트를 퍼블리시 하기 위해서 -p
플래그를 docker run
을 할 때 사용하는 것을 권장한다.
또는 -P
플래그는 모든 포트들을 노출시킨다.
예를 들어 EXPOSE
TCP라고 가정한다. 만약 UDP를 사용하고 싶다면
EXPOSE 80/udp
이 경우 docker run
과 함께 P
를 사용하면 포트는 TCP에 대해 한번, UDP에 대해 한번 노출된다.
docker run -p 80:80/tcp -p 80:80/udp ...
ENV
ENV <key> <value>
ENV <key>=<value> ...
ENV
명령은 key,value의 쌍으로 이루어진 환경 변수를 설정한다.
이 값은 빌드 단계의 모든 후속 명령어에 존재하고 인라인으로 교체할 수 있다.
ENV
는 두가지 형태를 갖는다.
첫 번째 형태 : ENV <key> <value>
, 하나의 변수만을 선언할 때 사용
예시,
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
두 번째 형태 : ENV <key>=<value> ...
, 여러 환경 변수를 선언할 때 사용
예시,
ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy
ENV
로 설정된 환경 변수는 컨테이너가 실행될 때까지 지속된다.
ADD
ADD는 두가지 형태를 갖는다.
ADD [–chown=
: ] ` ... ` ADD [–chown=
: ] `[" ",... " "]`
ADD
명령은 <src>
로부터 새로운 파일이나 디렉토리, 원격 file URL을 복사하여 <dest>
경로에 이미지의 파일 시스템에 추가한다.
여러 <src>
를 지정할 수 있지만 파일 또는 디렉토리 인 경우 해당 경로는 Build Context
의 소스를 기준으로 해석된다.
ADD hom* /mydir/ # hom으로 시작하는 모든 파일들을 더한다.
ADD hom?.txt /mydir/ # ?는 단일 문자열로 치환된다. 예를들면 "home.txt" 같은
COPY
COPY 두 가지 형태를 갖는다.
COPY [–chown=
: ] ` ... ` COPY [–chown=
: ] `[" ",... " "]`
COPY
명령은 <src>
로 부터 파일이나 디렉토리를 복사한다. 그리고 <dest>
경로의 컨테이너 파일시스템에 그것들을 추가한다.
ADD VS COPY
사용법은 ADD와 유사하다.
참고로 ADD가 COPY보다 먼저 개발되었다.
ADD는 파일을 호스트에서 컨테이너로 복사하는 기능 뿐만 아니라 추가기능이 존재한다.
추가 기능이란 ADD에서 복사 뿐만 아니라 url를 입력하면 다운로드해서 컨테이너에 추가하는 기능이 존재한다.
원격 file URL을 넣어주면 가능한데, 만약 압축파일일 경우 압축을 해제해서 넘겨주는데 압축 파일만을 넘겨주고 싶은 경우가 있다면 문제가 될 수 있다. (jar?) 그래서 COPY 명령어를 추가했는데, 하위호환성을 위해 남겨두었다고 한다.
가급적이면 명확하게 COPY를 쓰는 것이 좋겠다.
ENTRYPOINT
ENTRYPOINT [“executable”, “param1”, “param2”]
ENTRYPOINT command param1 param2
ENTRYPOINT
를 사용하면 실행 명령과 함께 실행될 컨테이너를 설정하는 것을 허락해준다.
에를 들어 다음과 같이 기본 설정으로 nginx를 시작하고 포트 80에서 수신한다고 하자.
docker run -i -t --rm -p 80:80 nginx
docker run <image>
에 대한 CLI argument는 ENTRYPOINT
양식의 모든 원소 뒤에 추가되어진다. 그리고 CMD를 사용하여 지정된 모든 요소를 대체한다.
이를 통해 argument를 entry point로 넘길 수 있다.
docker run <image> -d
에서 -d는 entrypoint
로 넘길 수 있다.
docker run --entrypoint
를 사용해서 ENTRYPOINT
명령을 오버라이딩할 수 있다.
직접 예시를 보면 이해가 빠르다.
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
ENTRYPOINT
의 역할은 도커가 실행될 때 top -b 를 수행하라는 의미를 갖는다.
이때 다음과 같은 명령어로 도커를 실행해보자.
docker run -it --rm --name test test
그래서 다음과 같은 명령어를 갖게 된다.
$ docker exec -it test ps al
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
4 0 1 0 20 0 36488 3160 - Ss+ pts/0 0:00 top -b -c
4 0 16 0 20 0 25948 1492 - Rs+ pts/1 0:00 ps a
해당 도커가 시작할 때 tob -b -c 명령이 실행되는 것을 볼 수 있다.
tob -b는 ENTRYPOINT가, -c는 CMD가 수행하는 것을 알 수 있다.
그러면 이 둘은 ENTRYPOINT
와 CMD
언제 사용해야하나?
그전에 ENTRYPOINT
를 사용하여 실질적으로 얻을 수 있는 이점에 대해 생각해보자.
가령 redis 이미지를 실행할 때 매번 같은 방법으로 접근한다고 해보자.
docker run redisimg redis -H something -u toto get key
만약 이때 Dockerfile 내부에 다음과 같은 ENTRYPOINT
가 존재한다면
ENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
아래와 같이 간단하게 사용할 수 있을 것이다.
docker run redisimg get key .
CMD의 경우 명령에서 덮어쓸 수 있지만 ENTRYPOINT는 명령 행에서 겹쳐쓰지 않고, 모든 명령행 인수가 ENTRYPOINT 매개변수 뒤에 추가된다.
즉, Argument를 통해 변경할 수 있는 명령은 CMD로, 시작할 때 고정적으로 수행되어야하며 Argument로 덮어씌워질 수 없는 경우라면 ENTRYPOINT
를 사용하는 것이 낫겠다.
USER
USER <user>[:<group>] or
USER <UID>[:<GID>]
USER
명령은 이미지를 실행할 때 Dockerfile
에서 RUN
,CMD
,ENTRYPOINT
명령어를 실행할 때 사용할 사용자 이름이나 사용자 그룹을 설정한다.
WORKDIR
WORKDIR /path/to/workdir
WORKDIR
명령은 Dockerfile
에 명시된 모든 RUN
, CMD
, ENTRYPOINT
, COPY
, ADD
명령어들에 대한 작업 디렉토리를 설정한다.
만약 WORKDIR
이 존재하지 않는다면 비록 어떠한 후속 Dockerfile
명령에서도 사용되지 않더라도 생성되어진다.
WORKDIR
은 Dockerfile
에서 여러 번 사용되어질 수 있다.
만약 상대경로로 주어진다면 이전 WORKDIR
명령어의 경로를 기준으로 한다. 예를들면 다음과 같다.
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
여기서 출력은 /a/b/c
가 될 것이다.
WORKDIR
명령어는 ENV
를 사용하여 이전에 설정한 환경변수를 설정할 수 있다.
Dockerfile
에 명시적으로 설정된 환경변수만 사용할 수 있다.
예를 들면,
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
이 Dockerfile
에서 마지막 pwd
명령의 출력 결과는 /path/$DIRNAME
이 될 것이다.
ARG
ARG <name>[=<default value>]
ARG
명령은 유저가 --build-arg <varname>=<value>
플래그를 사용해서 docker build
커맨드와 함께 빌더에게 빌드 타임에 넘겨줄 수 있는 변수를 정의한다.
만약 Dockerfile
에 정의되지 않은 build argument를 지정하려고 한다면 빌드는 warning
을 출력한다.
[Warning] One or more build-args [foo] were not consumed.
Dockerfile
은 하나 이상의 ARG
명령을 포함할 것이다.
예를들어 다음과 같다.
FROM busybox
ARG user1
ARG buildno
...
Reference
https://docs.docker.com/engine/reference/builder/