[docker] docker로 회사 개발 서버 구축하기 03 - Dockerfile Image build

KIM Jongwan·2024년 11월 13일
0
post-thumbnail

앞서 docker의 기본적인 사용 방법에 대하여 알아보았습니다. 이 과정에서 필요로 하는 container를 생성하기 위해 docker hub에 있는 image를 docker host pc로 pull하여 실행해보았습니다. 만약 사내에서 운영중인 어떤 서비스를 image로 만들 수 있다면, 갑작스럽게 트래픽이 증가하거나 운영 환경에 변화가 이루어졌을 때 이 image를 활용하여 새로운 환경에서 빠르게 서비스를 다시 시작할 수 있을 것입니다.

Dockerfile

Dockerfile이란?

Dockerfile은 docker image를 빌드하기 위하여 필요한 명령어가 작성 스크립트 파일입니다.
Dockerfile은 프로젝트의 root 디렉토리에 위치하게됩니다.

이미지를 빌드하기 위해서 docker build ... 명령어를 실행하게 되면, Dockerfile에 작성되어있는 내용을 토대로 image가 생성하게 되며 생성된 image로 container를 생성할 수 있습니다.

Dockerfile 작성법

앞서 docker 사용법을 익히며 생성했던 nginx(ubuntu:22.04) container image build를 위한 Dockerfile을 작성해보겠습니다.

## Ubuntu 22.04 image
FROM ubuntu:22.04
MAINTAINER jw.kim <jongbell4@gmail.com>

ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Seoul

## apt update && install tzdata, nginx
RUN apt-get update && apt-get install -y tzdata

RUN apt-get install -y nginx

## ADD index.html /var/www/html/index.html
COPY index.html /var/www/html/index.html


EXPOSE 80/tcp

CMD service nginx start && tail -f /dev/null

Dockerfile 명령어

기본적으로 Dockerfile에 작성된 내용은 위에서 아래로 순차적으로 실행됩니다. 앞서 작성한 내용을 토대로 각 명령어의 사용법을 알아보겠습니다.

  • FROM: 생성할 이미지의 베이스 이미지를 명시합니다.
    베이스 이미지로 ubuntu:22.04를 사용하는 새로운 이미지를 생성할 경우 FROM ubuntu:22.04 와 같이 작성할 수 있습니다.

  • MAINTAINER: 생성할 이미지의 저자를 명시하기 위해 사용합니다.
    MAINTAINER {name} <{email}> 과 같은 형식으로 작성합니다.(생략 가능)

  • ARG: 이미지를 빌드 타임에 사용될 변수를 설정합니다.
    우리가 작성한 Dockerfile은 컨테이너를 생성할 때에 패키지 매니저를 활용하여 nginx를 설치하게됩니다. 이때 신규 패키지 설치에 대한 사용자의 동의 여부 확인 절차(Do you want to continue? [Y/n])가 진행되지만 자동으로 생성되는 컨테이너에서 사용자 입력을 받을 수 없습니다. DEBIAN_FRONTEND=noninteractive 설정은 이러한 사용자의 동의 여부 확인 과정을 생략하여 진행할 수 있게해줍니다.

  • ENV: 컨테이너의 환경 변수를 설정합니다. ENV 명령어에 명시된 변수는 생성된 컨테이너에서 사용할 때 ARG로 명시된 변수보다 우선합니다.

## Dockerfile
FROM ubuntu:22.04
ARG TEST_ARGS
ENV TEST_ARGS=${TEST_ARGS:hello}
RUN echo $TEST_ARGS

## host 
docker build --build-arg TEST_ARGS=docker . ## 이미지 생성시 ARG TEST_ARGS 변수에 'docker' 값을 할당합니다.
docker run .....
hello ## 실제 생성된 컨테이너에서는 ENV 명령어로 할당된 'hello'가 출력됩니다.

리눅스 컨테이너를 생성하였을 때 기본적인 Timezone은 UTC로 설정됩니다. (타임존 확인 명령어 timedatectl) 컨테이너를 생성할 때에 타임존을 서울로 변경하고 싶을 경우 ENV TZ=Asia/Seoul를 추가합니다.

  • RUN: 컨테이너가 생성된 후 실행할 명령어들을 명시합니다.
    앞서 ubuntu:22.04 이미지를 베이스로 생성된 컨테이너에 추가적으로 패키지 매니저 업데이트, Timezone관련 패키지, nginx를 설치하기 위해 ENV 명령어의 다음으로 RUN apt-get update && apt-get install -y tzdata, RUN apt-get install -y nginx을 추가합니다.

  • ADDCOPY: 생성된 컨테이너에 추가하거나 host pc로부터 복사할 파일을 명시합니다. ADD 명령어는 복사 대상이 압축 파일일 경우 auto-extraction 되며 wget 명령어로 원격지의 파일을 복사할 수도 있습니다.
    COPY 명령어는 host pc에 존재하는 파일을 컨테이너에 복사합니다. host pc의 Dockerfile과 동일한 경로의 index.html 파일을 컨테이너의 nginx index.html파일로 사용하고자 할 때 COPY index.html /var/www/html/index.html를 추가합니다.

  • EXPOSE: 생성되는 컨테이너에 외부 노출 port를 명시한다. 다만 EXPOSE 명령어는 명시된 port로의 실제 접근 허용 작업을 의미하는 것이 아닌 작업자간 컨텍스트 공유를 위하여 작성됩니다.

  • CMD: Dockerfile 이미지가 실행될 때 default 실행 명령어를 명시해줍니다. docker run 과 함께 전달되는 추가적인 실행 명령어가 존재하지 않을 경우 CMD에 작성된 default 명령어가 실행됩니다. (docker run과 함께 전달되는 실행 명령어가 있을 경우 CMD는 무시됨)


Docker image build && container run

이제 작성한 Dockerfile로 실제 image를 build하고 컨테이너를 생성해보겠습니다.

## Dockerfile을 작성하기 전 ubuntu-image 이름의 별도 디렉토리를 생성하였습니다.
/ubuntu-image$ ll
total 16
drwxr-xr-x  2 host-user host-user 4096 Nov 13 18:02 ./
drwxr-xr-x 10 host-user host-user 4096 Nov 25 14:42 ../
-rw-rw-r--  1 host-user host-user  368 Sep 20 17:22 Dockerfile
-rw-rw-r--  1 host-user host-user   47 Sep 20 16:33 index.html

## 설치되어있는 이미지 목록을 검색합니다.
/ubuntu-image$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
ubuntu               22.04     97271d29cb79   2 months ago    77.9MB

## Dockerfile에 명시되어있는 이미지를 빌드해보겠습니다.
/ubuntu-image$ docker build -t ubuntu-nginx .
+] Building 148.8s (9/9) FINISHED                                                      docker:default
 => [internal] load build definition from Dockerfile                                              0.0s
 
 .....
 
 /ubuntu-image$ docker images
 REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
ubuntu               22.04     97271d29cb79   2 months ago    77.9MB
ubuntu-nginx         latest    4fb8338192c3   3 minutes ago   ..

tag명으로 명시한 ubuntu-nginx 이름의 이미지가 build 되었습니다.

이제 이 이미지로 새로운 container를 생성하면 생성된 container는 ubuntu:22.04 OS를 기반으로 80번 포트에 nginx가 구동된 상태여야합니다. 또한 Host OS의 80포트로 요청 시 생성된 container의 nginx로 요청이 전달되고 응답하는 것을 확인할 수 있어야합니다.


container 생성과 http 요청 테스트

## ubuntu-nginx 이미지로 container-unginx를 생성하고 Host의 80port를 연결해주겠습니다.
$ docker run --itd --name container-unginx -p 80:80 ubuntu-nginx
3d0ea10abe8389d7030696f9a89240c23972d15a687809aa58e4db145cb65939
$ docker ps -a
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                                                                  NAMES
3d0ea10abe83   ubuntu-nginx             "/bin/sh -c 'service…"   14 seconds ago   Up 14 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp                                                      container-unginx

## docker container는 고유의 IP주소를 할당 받습니다. docker inspect 명령어로 container의 IP정보를 확인할 수 있습니다.
$ docker inspect container-unginx | grep IP

.....
"IPAddress": "172.17.0.10",
.....

$ crul http://172.17.0.10
<h1> hello this is ubuntu-nginx image container-unginx</h1>
profile
3년차 백앤드 개발자입니다.

0개의 댓글