Docker

[Docker] Dockerfile reference - Format, Parser Directives

patrick-star 2023. 8. 21. 22:07
728x90

출처

Docker는 Dockerfile이라는 설명서를 읽어서 이미지를 자동으로 빌드할 수 있다. 즉, 도커는 이미지를 만들기 위한 파일이다. Dockerfile은 이미지를 조립할 수 있는 모든 커맨드들을 갖고 있는 텍스트 문서다. 이번 페이지에서는 Dockerfile에서 사용할 수 있는 커맨드들을 살펴볼 것이다.

Format

# 주석
명령어 인자
INSTRUCTION arguments

명령어 : 대소문자를 가리지 않지만 인자(argument)와 구분하기 위해 주로 `대문자`를 사용한다. 
  • FROM 명령
    도커는 Dockerfile에 적혀있는 순서대로 명령(instruction)들을 실행한다. 이때 무조건 FROM 명령을 가장 먼저 실행해야 한다.
    FROM 명령은 parser, directives, comments, 전역 ARG가 될 수도 있다. 각각에 대해서는 아래에서 다룬다.

FROM 명령은 빌드할 때 사용하는 Parent image를 지정한다.

ex)

FROM ubuntu:latest # ubuntu 최신 버전을 base 이미지로 사용

단, Dockerfile의 FROM 줄에서 사용되는 인수를 선언하는 하나 이상의 ARG 명령FROM 명령 앞에 있을 수 있다.

Parser Directives

Parser Directives

1) 선택 사항이고 Dockerfile에서 후속 라인이 처리되는 방식에 영향을 미친다.
2) build에 있어 계층(layer)를 더하지 않아서 build 단계로써 화면에 출력되지 않는다.

  • 작성 형식
  • # directive=value

주석, 빈 공간, builder 명령어가 parser directive 이전에 이미 처리된 적이 있다면 Docker는 더 이상 parser directive를 살펴보지 않는다. 대신에 Docker는 parser directive로 입력한 내용을 전부 주석으로 여기면서 유효한 parser directive로 취급하지 않는다.
그래서 parser directive반드시 Dockerfile의 맨 위에 있어야 한다.

Parser directive의 convention

1) 대소문자를 구분하지는 않지만 일반적으로는 소문자를 사용
2) parser directive를 입력하고 나면 뒤이어 빈 줄(empty line)을 추가함
3) Line continuation을 지원하지 않음 (백슬래시()를 이용해서 줄을 바꾸더라도 한 줄로 취급하는 기능)

  • 유효한 입력
  • # directive=value FROM ImageName
  • 유효하지 않은 입력
    1) line continuation 지원하지 않음
# direc \\

tive=value

2) parser directive를 2번 사용함


# directive=value1

# directive=value2

FROM ImageName

3) Builder 명령어 이후에 사용함


FROM ImageName

# directive=value

4) 주석 이후에 사용함


# About my dockerfile

# directive=value

FROM ImageName

5) 정의되지 않은 parser directive를 사용해서 1번째 줄은 주석으로 처리되면서 4)의 이유로 유효하지 않음


# unknowndirective=value

# knowndirective=value

6) 단 하나의 공백도 허용하지 않음. 무조건 유효한 입력 형식(# directive=value)으로 작성해야 함


#directive=value

# directive =value

# directive= value

# directive = value

# dIrEcTiVe=value

Docker에서는 2개parser directive를 지원한다.

  • syntax : BuildKit backend에서만 사용할 수 있다. 자세한 내용은 참고문서를 확인하자.
  • escape
    parser directive인 escape에 올 수 있는 value는 \(백슬래시) 또는 `(백틱) 밖에 없다.
# escape=\\
또는
# escape=\`

escape 지시자(directive)는 Dockerfile에서 escape 문자로 어떤 걸 사용할지 지정한다. default로는 \로 지정된다.

cf) escape 문자(character)란? - 출처


\\n : 줄바꿈  
\\t : 가로 탭  
\\ : 백슬래시  
' : 작은 따옴표  
" : 큰 따옴표  
? : 물음표

위와 같이 백슬래시와 특정 문자를 결합한 것으로  
이를 통해 특정 기능을 제공하거나 실행 문자 집합을 나타낼 수 있다.

Dockerfile에서는 이 기능에 더해서 line continuation 기능까지 수행한다.

cf) Dockerfile에 escape 파서 지시자가 포함되더라도 마지막 줄에 위치하지 않은 RUN 명령에서는 escaping이 실행되지 않는다.

escape 문자를 `(백틱)으로 설정하면 Windows에서 유용하다. Windows에서는 \는 디렉토리 구분자로 사용하기 때문이다.

ex) 아래와 같이 Dockerfile을 작성했다고 하자.


FROM microsoft/nanoserver  
COPY testfile.txt c:\\  
RUN dir c:\\

2번째 줄을 보면 escape 문자\(백슬래시)이기 때문에 2번째 백슬래시(\)가 새로운 줄을 위한 escape 문자로 해석된다.
3번째 줄을 보면 escape 문자\(백슬래시)이기 때문에 마찬가지로 line continutation을 위해 사용된 걸로 해석된다.

따라서, 빌드 결과를 보면 아래와 같다.


PS E:\\myproject> docker build -t cmd .

Sending build context to Docker daemon 3.072 kB  
Step 1/2 : FROM microsoft/nanoserver  
\---> 22738ff49c6d  
Step 2/2 : COPY testfile.txt c:\\RUN dir c: ⇒ 이 부분을 통해 백슬래시가 제대로 인식되지 않았다는 걸 확인할 수 있다.  
GetFileAttributesEx c:RUN: The system cannot find the file specified.  
PS E:\\myproject>

이런 상황을 해결하기 위해서 디렉토리 구분자를 /(슬래시)로 변경하는 방법이 있겠으나
이는 Windows 환경에서 익숙하지 않은 문법이고 에러가 발생할 가능성이 있다.

그래서 escape 파서 directive를 `(백틱)으로 설정하면 해결된다.

ex)


# escape=\`

FROM microsoft/nanoserver  
COPY testfile.txt c:  
RUN dir c:\\

결과


PS E:\\myproject> docker build -t succeeds --no-cache=true .

Sending build context to Docker daemon 3.072 kB  
Step 1/3 : FROM microsoft/nanoserver  
\---> 22738ff49c6d  
Step 2/3 : COPY testfile.txt c:\\ ⇒ 백슬래시가 제대로 인식된 걸 확인할 수 있다.  
\---> 96655de338de  
Removing intermediate container 4db9acbb1682  
Step 3/3 : RUN dir c:  
\---> Running in a2c157f842f5  
Volume in drive C has no label.  
Volume Serial Number is 7E6D-E0F7

Directory of c:\\

10/05/2016 05:04 PM 1,894 License.txt  
10/05/2016 02:22 PM

Program Files  
10/05/2016 02:14 PM

Program Files (x86)  
10/28/2016 11:18 AM 62 testfile.txt  
10/28/2016 11:20 AM

Users  
10/28/2016 11:20 AM

Windows  
2 File(s) 1,956 bytes  
4 Dir(s) 21,259,096,064 bytes free  
\---> 01c7f3bef04f  
Removing intermediate container a2c157f842f5  
Successfully built 01c7f3bef04f  
PS E:\\myproject>