Connecting

불좀 꺼줄래? 내 Docker좀 보게 PART 5 - Dockerfile 작성하기 본문

Container

불좀 꺼줄래? 내 Docker좀 보게 PART 5 - Dockerfile 작성하기

팬도라 2020. 11. 14. 12:16
반응형

Dockerfile 작성하기

What is Dockerfile ?

Dockerfile은 Docker image를 만들기 위한 설정 파일로, 아래에서 설명할 여러 명령어를 통해 작성하면 image를 만들어서 Docker Hub에 업로드할 수 있다. 따라서 이미지가 어떻게 만들어지고 어떠하나 특성을 가지고 있는지 알고 싶다면 Dockerfile을 해석할 수 있다는 뜻이 된다.

FROM

  • Docker image를 만드는데 필요한 가장 기본인 베이스 이미지를 지정하는 부분이다.

    FROM ubuntu:20.04

LABEL

  • Dockerfile를 작성한 개발자의 정보를 작성한다. 기존 명령어인 MAINTAINER와 동일한 역할을 담당한다.

    • 단, MAINTAINER는 공식적으로 deprecated 되었기 때문에 사용하지 않는다.
    LABEL soengwon "seongwon@edu.hanabt.ac.kr"

ARG

  • Dockerfile을 빌드할 때, 설정할 수 있는 옵션을 지정한다.

    ARG DEBIAN_FRONTEND=noninteractive

WORKDIR

  • 작업 디렉터리를 설정한다. 설정된 디렉터리가 없으면 새로 생성하고, 해당 디렉터리를 기본으로 동작한다.

    WORKDIR /var/www/html

RUN

  • 이미지를 생성할 때 실행할 명령어 혹은 코드를 지정한다. 파일 권한을 변경하거나 패키지를 추가하는 경우에 많이 사용한다.

    RUN apt-get install -y --no-install-recommends apt-utils build-essential

ENV

  • 이미지에서 사용할 환경변수를 지정한다.

    ENV TZ=Asia/Seoul

COPY

  • 이미지를 생성할 때, 외부에서 파일을 이미지로 가져오기 위해 사용한다. 호스트에 설정된 퍼미션과 동일하게 복사한다.

    COPY ./pages /usr/local/apache2/htdocs/

ADD

  • COPY와 비슷하게 파일을 이미지로 가져오기 위해 사용하지만, 압축파일인 경우 압축을 해제하고 파일 퍼미션이 지정되어 있다.

    ADD ./pages /usr/local/apache2/htdocs/

EXPOSE

  • 호스트와 연결할 기본 포트를 지정한다.

    EXPOSE 80

CMD

  • 컨테이너를 시작할 때, 어떻게 실행되어야 하는지 정의한다. Dockerfile에서 한 번만 사용이 가능하다.

    CMD ["echo", "hello"]

ENTRYPOINT

  • CMD와 동일하게 컨테이너를 실행할 때, 어떻게 실행해야 하는지에 대한 정의를 한다. 단, CMD와 같이 사용할 경우 ENTRYPOINT는 실행파일, CMD는 매개변수 역할을 담당한다.

    ENTRYPOINT ["echo"]
    CMD ["hello"]

Dockerfile 이미지 만들기

위에서 학습한 내용을 기반으로 간단하게 Dockerfile를 만들고 실습하도록 한다. 다음과 같은 Dockerfile를 작성한다.

FROM ubuntu:latest

LABEL seongwon "seongwon@edu.hanbat.ac.kr"

ENV TZ=Asia/Seoul

RUN apt-get update && apt-get upgrade -y
RUN echo "HELLO, Dockerfile!?" >> /hello-docker.txt

CMD ["cat", "/hello-docker.txt"]

docker build

다음 명령을 통해서 이미지를 생성한다. -t 옵션을 통해 출력할 이미지 이름을 지정할 수 있으며, -f 옵션을 통해 변경된 Dockerfile의 이름을 지정할 수 있다.

$ docker build -t hello-dockerfile .

Sending build context to Docker daemon  6.153GB
Step 1/6 : FROM ubuntu:latest
 ---> 9140108b62dc
Step 2/6 : LABEL seongwon "seongwon@edu.hanbat.ac.kr"
 ---> Using cache
 ---> 8a9a196890da
Step 3/6 : ENV TZ=Asia/Seoul
 ---> Using cache
 ---> 349e95d740ad
Step 4/6 : RUN apt-get update && apt-get upgrade -y
 ---> Using cache
 ---> 4e978ede2375
Step 5/6 : RUN echo "HELLO, Dockerfile!?" >> /hello-docker.txt
 ---> Running in 552ba7ce92b2
Removing intermediate container 552ba7ce92b2
 ---> dd0d83a50fed
Step 6/6 : CMD ["cat", "/hello-docker.txt"]
 ---> Running in bebc9163ad0f
Removing intermediate container bebc9163ad0f
 ---> a51fc98ccab7
Successfully built a51fc98ccab7
Successfully tagged hello-dockerfile:latest
$ docker run hello-dockerfile
HELLO, Dockerfile!?

docker tag

tag 옵션을 통해 이미지의 이름과 버전을 지정할 수 있다. Docker Hub에 이미지를 업로드하기 위해서는 반드시 tag 옵션을 통해 ID를 작성해 주어야 하며, 사설 레파지토리를 사용하는 경우에는 레파지토리 주소 등의 정보도 추가로 작성해야 한다.

$ docker tag hello-dockerfile jusk2/hello-dockerfile
$ docker tag hello-dockerfile jusk2/hello-dockerfile:v1.0

$ docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
jusk2/hello-dockerfile   latest              a51fc98ccab7        6 minutes ago       102MB
jusk2/hello-dockerfile   v1.0                a51fc98ccab7        6 minutes ago       102MB
hello-dockerfile         latest              a51fc98ccab7        6 minutes ago       102MB

tag에 버전을 지정하지 않은 경우에는 자동으로 latest가 붙는 것을 확인할 수 있으며, 이미지 이름만 다르고 참조하는 IMAGE ID는 동일한 것을 확인할 수 있다.

docker push

Docker Hub에 우리가 만든 첫 번째 Docker 이미지를 업로드한다. 이때 반드시 Docker Hub에 로그인이 되어 있어야 한다.

$ docker push hello-dockerfile
The push refers to repository [docker.io/library/hello-dockerfile]
9b938c0f6241: Preparing
0f28eeeea31b: Preparing
782f5f011dda: Preparing
90ac32a0d9ab: Preparing
d42a4fdf4b2a: Preparing
denied: requested access to the resource is denied

위와 같이 태그를 지정하지 않은 상태로 업로드하는 경우 업로드 절차가 거부되는 것을 확인할 수 있다. 따라서 tag를 지정한 이미지로 업로드를 시도한다.

$ docker push jusk2/hello-dockerfile
The push refers to repository [docker.io/jusk2/hello-dockerfile]
9b938c0f6241: Pushed
0f28eeeea31b: Pushed
d42a4fdf4b2a: Pushed
latest: digest: sha256:07e2f3ad3ff1d0ff9b3e9a0bc482bcabcf68b2786cbb47f0947229f070b74d24 size: 1362

$ docker push jusk2/hello-dockerfile:v1.0
The push refers to repository [docker.io/jusk2/hello-dockerfile]
9b938c0f6241: Layer already exists
0f28eeeea31b: Layer already exists
782f5f011dda: Layer already exists
90ac32a0d9ab: Layer already exists
d42a4fdf4b2a: Layer already exists
v1.0: digest: sha256:07e2f3ad3ff1d0ff9b3e9a0bc482bcabcf68b2786cbb47f0947229f070b74d24 size: 1362

업로드가 완료되고 Docker Hub의 레파지토리 항목을 살펴보면 방금 우리가 업로드한 이미지 리스트를 확인할 수 있다.

이제 다른 사람도 우리가 만든 이미지를 실행할 수 있으며, 추후 레파지토리를 삭제하고 싶다면 Settings -> Delete Repository 항목을 클릭하여 삭제한다.

Comments