Script - Dockerfile

Script - Dockerfile

Dockerfile은 도커 이미지를 만들기 위해 필요한 기본 명령들을 지정하기 위한 Script이다.

이러한 명령들로 이미지가 만들어지고, 이미지가 실행되면 Dockerfile에 명시해둔 명령들이 실행된 채로 컨테이너가 되기 때문에 배포에 상당히 유리한 전략임을 알 수 있다.

그래서 이러한 Dockerfile을 사용하기 위해 Docker 공식 문서를 보며 DockerfileInstruction(이하 명령 or 명령어)을 이해해보자.

Dockerfile

Docker-Dockerfiles

도커는 Dockerfile의 명령에 따라 이미지를 자동으로 빌드할 수 있다.

docker build를 사용하면 여러 명령 줄 명령을 연속적으로 실행하는 자동화된 빌드를 만들 수 있다.

지금부터 Dockerfile에서 사용할 수 있는 명령들을 살펴보자.

사용법

Dockerfile에 설정된 내용에 따라 이미지를 생성한다.

여러가지 명령어를 토대로 기본 이미지에서 개발 환경을 셋팅한 이미지를 생성할 수 있다.

docker build 명령어는 DockerfileContext로부터 이미지를 만들어낸다.

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을 위치시키고 빌드에 필요한 파일만 추가하는 것을 권장하고 있다.

DockerfileBuild 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부터 지원하며 빌드를 실행하기 위한 새로운 백엔드 지원 도구이다.

3분 10초부터

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 명령만 존재할 수 있다.

ARGDockerfileFROM에서 사용되는 인수를 선언할 수 있다.

가장 앞에 #이 오면 주석이고, 다른 곳에서는 인수로 취급된다.

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

위에서 #은 주석이며 echo 이후에 오는 #argument이다.

Parser Directives

Parser DirectivesDockerfile의 다음 줄 처리되는 명령에 영향을 줄 수 있는 옵션이다.

Parser Directives는 일반적으로 # directive = value와 같은 특수한 유형의 주석으로 작성된다.

또한 Parser Directives는 빌드에 레이어를 추가하지않으며, 빌드 단계에 표시되지 않는다.

빈줄이나 빌더 명령어가 실행되면 도커는 더 이상 Parser Directives를 찾지 않는다.

그러므로 모든 Parser DirectivesDockerfile의 최상단에 위치시키는 것이 일반적이다.

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 DirectiveDockerfile에 포함되어지 여부와 관계없이 줄 끝을 제외하고 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

여기서 defbye가 아닌 hello를 반환한다.

하지만 ghibye를 반환한다.

.dockerignore file

도커 CLI는 도커 데몬으로 context를 전송하기 이전 .dockerignore 이름을 가진 파일이 context의 루트 디렉토리에 있는지 찾는다.

만약 이 파일이 존재한다면 CLI는 패턴과 일치하는 파일 및 디렉토리를 제외하도록 context를 수정한다.

이것은 데몬에 불필요한 거대하고 예민한 파일과 폴더를 보내고 잠재적으로 그것들을 ADDCOPY를 사용해서 이미지에 추가하는 것을 방지하는데 도움을 준다.

# 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은 특히 공용 저장소로부터 이미지를 가져와서 시작하는 것을 쉽게 만들어준다.

  • ARGFROM 이전에 위치할 수 있는 유일한 명령어다.

  • 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가 수행하는 것을 알 수 있다.

그러면 이 둘은 ENTRYPOINTCMD 언제 사용해야하나?

그전에 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 명령에서도 사용되지 않더라도 생성되어진다.

WORKDIRDockerfile에서 여러 번 사용되어질 수 있다.

만약 상대경로로 주어진다면 이전 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/

https://judo0179.tistory.com/27

https://m.blog.naver.com/PostView.nhn?blogId=kbh3983&logNo=221130490612&proxyReferer=https%3A%2F%2Fwww.google.com%2F

https://stackoverflow.com/questions/21553353/what-is-the-difference-between-cmd-and-entrypoint-in-a-dockerfile



© 2022. by minkuk

Powered by minkuk