본문 바로가기
Docker

Docker - dockerfile 작성을 위한 주요 명령

by DGK 2021. 12. 16.

 

도커 입문 수업을 듣고 중요한 내용을 정리했습니다.
개인 공부 후 자료를 남기기 위한 목적이므로 내용 상에 오류가 있을 수 있습니다.

 

dockerfile 작성을 위한 주요 명령

dockerfile을 작성하기 위한 주요 명령을 학습하고자 한다.

 

dockerfile이란?

docker image를 작성할 수 있는 기능으로 dockerfile 문법을 통해 image 생성을 위한 스크립트를 작성할 수 있다.

이러한 스크립트를 기반으로 사용자만의 docker image를 만들 수 있다.

 

 

dockerfile 기본 문법

dockerfile은 기본적으로 텍스트 파일 형식이며, dockerfile의 문법 구조는 명령과 인자로 이루어져 있다.

참고로, dockerfile의 명령은 대문자로 작성한다. (소문자로 작성해도 상관없지만, 명령과 인자를 구분하기 위함)

 

*예시

명령 인자

 

 

dockerfile 주요 명령

*dockerfile의 주요 명령 및 설명

 

   - FROM

  • 베이스(base) image를 지정하는 명령 (ex. FROM httpd:alpine)

   - LABEL

  • 버전 정보 및 작성자 등의 image 설명을 작성하기 위한 명령 (ex. LABEL version="1.0.0")

   - CMD

  • docker container가 시작할 때, 실행되는 쉘 명령을 지정하는 명령

   - RUN

  • 쉘 명령을 실행하는 명령 (단, RUN 명령은 image 작성 시 실행됨 : 일종의 새로운 image layer를 만드는 역할)

   - ENTRYPOINT

  • docker container가 시작할 때, 실행되는

   - EXPOSE

  • docker container 외부에 오픈할 포트를 설정하는 명령 (ex. EXPORT 8080)

   - ENV

  • docker container 내부에서 사용할 환경 변수를 지정하는 명령 (ex. ENV PATH/usr/bin:$PATH)

   - WORKDIR

  • docker container의 작업 디렉토리를 설정하는 명령

   - COPY

  • 파일 또는 디렉토리를 docker container에 복사하는 명령 (ADD와 달리 URL은 지정할 수 없으며, 압축 파일을 자동으로 풀어주지 않음 : ex. COPY test.sh/root/test.sh)

   - ADD 

  • 파일과 디렉토리 또는 특정 URL의 데이터를 docker image에 추가하는 명령 (ADD 명령은 COPY 명령과 유사하며, COPY 명령이 ADD 명령보다 명시적이므로 주로 COPY 명령을 사용함 : ADD 명령은 참고용)

   - SHELL

  • 쉘 프로그램을 지정하는 명령 (CMD 명령으로 대체 가능하므로 참고로만 알아둘 것)

   - ARG

  • dockerfile 내에서 필요한 변수를 설정하는 명령 (docker image와 container에서 사용하는 환경 변수를 설정하는 ENV 명령과 달리, ARG 명령은 dockerfile 스크립트 작성을 위해 필요한 변수를 설정하는 명령임)

   - USER

  • docker image 및 container에서 작업하는 사용자 ID를 지정하는 명령 (ex. USER kim)

   - ONBUILD

  • 생성한 docker image를 기반으로, 새로운 image를 생성할 때 실행되는 명령을 지정하는 명령

   - VOLUME

  • docker image를 위한 볼륨을 생성하는 명령

   - #

  • dockerfile에서도 주석을 사용할 수 있음 (#를 사용하면 해당 라인은 주석이 됨)

 

 

*dockerfile 주요 명령의 예시

 

  • FROM
FROM alpine

 

*결과 :

 

 

해당 명령은 베이스 image를 지정하는 명령이다. (반드시 Dockerfile에 작성해야 함)

 

 

  • docker build 옵션 Dockerfile 경로
docker build --tag myimage .

 

*결과 :

 

해당 명령은 dockerfile로 docker image를 생성하는 스크립트에서 작성(사용)되는 명령이다.

즉, 앞서 베이스로 지정한 alpine image를 기반으로 사용자만의 docker image를 작성하는 명령이다.

참고로, --tag 옵션을 사용하면 작성하고자 하는 image의 이름을 설정할 수 있다.

 

 

docker build --tag myimage:1.1 .

 

*결과 :

 

위의 명령처럼 이미지명 뒤에 :태그를 붙이면, 해당 버전의 image를 작성할 수 있다.

 

 

docker build --tag myimage2 -f Dockerfile2 ./

 

*결과 :

 

위의 명령처럼 -f 옵션을 사용하면, image를 build하는 파일명을 지정할 수 있다.

참고로, -f 옵션을 사용하지 않고 image를 build하면 디폴트 설정으로 Dockerfile 파일명으로 된 파일에 image가 빌드(build)된다.

 

 

docker build --tag myimage3 -f Dockerfile2 --pull=true

 

*결과 :

 

위의 명령처럼 --pull 옵션을 사용하면, image를 생성할 때 마다 새로운(최신의) 베이스 image를 다운받는다. 

즉, DockerHub에서 베이스 image를 수시로 업데이트하고 이를 기반으로 새로운 이미지를 생성할 때 사용하는 옵션이다.

 

 

*참고(1)

'docker build 옵션 Dockerfile 경로' 명령에서 Dockerfile 경로를 .으로 쓰는 이유는 현재 폴더에 Dockerfile이 있음을 명시하기 위함이다. (일반적으로 " . "은 현재 폴더를 나타냄)

 

또한, 보다 명시적으로 표기하기 위해 " . " 대신 " ./ "로 쓰는 것을 권장한다. 

 

*참고(2)

build 명령의 주요 옵션

 

   -t 또는 --tag

  • 새롭게 생성하려는 docker image의 이름을 설정하는 명령 (참고로 이미지명 뒤에 ":태그"를 붙일 수 있으며, 태그가 없을 경우 디폴트 설정으로 latest 태그가 붙여짐)

   -f

  • docker image를 빌드(build)할 경우, 이미지를 빌드할 파일을 지정할 수 있는 명령 (해당 옵션을 사용하지 않으면 디폴트 설정으로 Dockerfile의 파일명을 가진 파일에 이미지가 빌드됨)

   --pull

  • docker image를 생성할 때 마다 새로운 버전의 베이스 image를 다운받도록 설정하는 명령 (일반적으로 FROM 명령으로 지정된 베이스 이미지는 한 번 다운로드 받으면 이미지 생성마다 새롭게 베이스 이미지를 다운받지 않고 기존의 다운로드 받은 이미지를 사용함)

 

 

  • LABEL
FROM alpine

LABEL maintainer ="dgk@gmail.com"
LABEL version ="1.0.0"
LABEL description ="docker image test"

 

*결과 :

 

LABEL 명령은 <key> = <value> 형식으로 메타 데이터를 넣을 수 있는 명령이다.

일반적으로 저자, 버전, 설명, 작성일자 등의 데이터를 넣는다.

 

 

  • COPY
FROM alpine

LABEL maintainer ="dgk@gmail.com"
LABEL version ="1.0.0"
LABEL description ="docker image test"

COPY ./파일명 /usr/local/apache2/htdocs

 

*결과 :

 

위의 명령은 Dockerfile이 존재하는 파일의 하위 폴더명과 생성하는 image의 폴더경로를 적어서 실행시킨다.

즉, Dockerfile의 하위 폴더인 " ./파일명 " 의 내용을 새롭게 생성하는 image의 특정 폴더에 그대로 복사할 때 사용하는 명령이다. 

단, Dockerfile이 위치한 폴더를 기준으로 상대경로를 써줘야 한다.

 

 

*참고

docker inspect 이미지명

docker inspect myweb2

 

*결과 :

 

해당 명령은 베이스 image를 통해, 직접 Dockerfile로 작성한 image를 조사하는 명령이다.

 

 

  • CMD

CMD 명령은 다음의 세 가지 형태로 명령을 작성할 수 있다.

 

CMD ["executable", "parameter1", "parameter2", ... ]

 

CMD ["parameter1", "parameter2", ... ]

 

CMD <command> <parameter1> <parameter2>

 

docker에서 추천하는 방식은 명령어와 인자를 리스트처럼 작성하는 형태이다.

(반드시 쌍따옴표로 써야함 : 홑따옴표 사용불가) 

 

참고로, 두 번째 방식은 ENTRYPOINT 명령어에 인자를 리스트처럼 작성하여 넘겨주는 형태이다.

(명령어는 ENTRYPOINT에 기재하고 인자들만 해당 명령어로 넘겨주는 형태)

 

*주의

하나의 Dockerfile에서 오직 한 가지의 CMD만 설정되며, 만약 CMD 설정이 여러 개일 경우에는 맨 마지막에 설정된 CMD만 적용된다.

 

 

CMD ["/bin/sh", "-c", "htttpd-foreground"]

 

*결과 :

CMD 명령

 

docker build --tag myweb3 ./

 

docker inspect myweb3

 

 

  • ENTRYPOINT

ENTRYPOINT는 주로 반드시 실행해야 하는 명령을 기입할 때 사용하는 명령으로, ENTRYPOINT는 docker run 명령과 함께 넣는 CMD 명령으로 덮어씌워지지 않는다. 

 

참고로, docker run 명령에 함께 넣는 CMD 명령은 ENTRYPOINT에 작성된 명령의 인자로 들어가게 된다.

따라서, ENTRYPOINT에는 docker container를 생성할 때 반드시 실행되어야 하는 명령을 넣어주고 해당 명령 뒤에 필요한 인자는 docker run 명령과 함께 CMD 명령으로 넣어주는 방식을 사용하기도 한다.

 

*예제(1)

ENTRYPOINT ["bin/sh"]

 

docker build --tag myweb .

 

docker run -dit -p 9999:80 --name httpdweb myweb3

 

docker inspect httpdweb

 

*예제(2)

ENTRYPOINT ["/bin/echo", "hello"]

 

docker build --tag myweb4 ./

 

docker run -dit -p 9999:80 --name httpdweb myweb4 /bin/sh hi

 

docker inspect httpdweb

 

이처럼, ENTRYPOINT로 입력한 명령 뒤에 hello, /bin/sh, hi라는 3개의 인자가 붙는 것을 확인할 수 있다.

즉, ENTRYPOINT 명령(echo) 뒤에 docker run 명령으로 넣어지는 CMD 명령이 인자로 붙는 것을 알 수 있다.

참고로, hello는 ENTRYPOINT 명령과 함께 할당된 인자이며, /bin/sh와 hi는 run 명령을 통해 넣어지는 CMD 명령으로 할당되는 인자이다.

 

 

  • RUN(docker run 명령과 다름)

RUN 명령은 image를 생성할 때, 일종의 layer를 만들 수 있는 명령으로 보통은 베이스 image에 새로운 프로그램(패키지)을 설치하여 새로운 image를 만들 때 주로 사용된다.

 

 

*(예제)

ubuntu 18.04 버전(base image)에 apache2(프로그램)을 설치하고 자신만의 웹 페이지를 복사(COPY)한 후 웹 서버를 구동하는 경우

 

vi Dockerfile-apache

 

참고로, apache2의 디폴트 웹 서버 설정은 /var/www/html/ 폴더의 웹 페이지를 보여준다.

 

 

  • EXPOSE

EXPOSE 명령은 docker container의 특정 포트를 외부에 오픈하는 명령이다.

기본적으로 dokcer run 명령의 -p 옵션과 비슷한 기능을 하는 명령이다.

 

*참고

   - docker run -p 옵션

  • docker run -p 옵션은 docker container의 특정 포트를 외부에 오픈하고 해당 포트를 호스트 PC의 특정 포트와 연결시켜주는 옵션이다.

   - EXPOSE 명령

  • EXPOSE 명령은 docker container 생성 시, 특정 포트를 외부에 오픈하는 것만 설정하는 명령이다.
  • 따라서, EXPOSE 명령을 넣는다고 해서 호스트 PC에서 해당 컨테이너 포트에 접속할 수 있는 것은 아니다. (-p 옵션과의 차이점)
  • EXPOSE 명령은 주로 특정 container의 외부 포트를 만들어서, 다른 container가 해당 포트로 접속할 수 있도록 하는데 사용된다. (docker-compose를 사용할 때 주로 활용되기도 함) 

 

*예제

EXPOSE 80

 

docker build --tag myweb -f Dockerfile-apache ./

 

docker inspect myweb

 

이처럼, 해당 컨테이너를 조사하면 ExposedPort가 80번으로 열린 것을 확인할 수 있다.

 

*추가내용

docker run -P -d myweb

 

참고로, docker container를 실행할 때 "-P" 옵션(대문자)를 사용하면 EXPOSE 명령으로 오픈된 포트에 호스트 PC의 랜덤 포트가 연결된다. (ex. 0.0.0.0:49153 -> 80/tcp)

 

 

  • ENV

ENV 명령은 docker container 내의 환경변수를 설정하는 명령이다.

해당 명령으로 설정한 환경변수는 RUN, CMD, ENTRYPOINT 명령에도 적용된다.

 

*예제

vi Dockerfile-mysql

 

ENV 명령으로 mysql 슈퍼관리자인 root ID에 대한 password를 설정하고 dbname에 원하는 데이터베이스의 이름을 설정할 수 있다.

 

 

  • WORKDIR

WORKDIR 명령은 RUN, CMD, ENTRYPOINT 명령이 실행될 디렉토리를 설정하는 명령이다.

즉, 위의 명령들이 실행될 경로를 미리 설정해주는 것이다.

 

 

*예제

vi Dockerfile-workdir

 

docker build --tag mywork -f Dockerfile-workdir ./

 

docker run -d --name mytest mywork

 

위의 결과처럼 'docker logs mytest' 명령을 통해 CMD 명령이 실행된 결과를 볼 수 있다.

(index.html을 보여주는 명령)

 

즉, WORKDIR 명령은 해당 CMD 명령(cat)이 실행되는 디렉토리(/usr/local/apache2/htdocs)를 설정해주는 명령이다.

 

 

참고내용

*가끔 사용하는 docker 명령

 

  • docker logs (CONTAINER ID or 컨테이너명)
docker logs apacheweb

 

*결과 :

docker build --tag myweb3 ./

 

docker logs apacheweb

 

해당 명령을 사용하면, docker container의 에러 또는 출력 결과를 확인할 수 있다.

 

 

  • docker kill (CONTAINER ID or 컨테이너명)
docker kill apacheweb

 

*결과 :

docker kill apacheweb

 

해당 명령은 docker container를 즉시 중지시키는 명령이다.

즉, "docker stop 컨테이너명"의 명령은 docker container를 즉시 중단하지 않고 현재 실행중인 단계까지 기다린 후에 중지시킨다.

반면에 "docker kill 컨테이너명"의 명령은 docker container를 즉시 중단시킨다.

 

 

*CMD 명령 변경하기

 

기존의 Dockerfile CMD 명령

CMD ["/bin/sh", "-c", "httpd-foreground"]

 

변경된 Dockerfile CMD 명령

CMD ["/bin/sh"]

 

변경된 Dockerfile CMD 명령으로 새로운 image 생성

docker build --tag myweb ./

 

새롭게 생성한 image 조사(inspect)하기

 

이처럼 Dockerfile CMD 명령을 변경하면, Dockerfile로 새롭게 만드는 image는 변경된 CMD 명령이 적용된다.

 

 

*CMD 명령 덮어씌우기

 

기존의 Dockerfile CMD 명령

CMD ["/bin/sh"]

 

docker 명령으로 Dockerfile CMD 명령 덮어씌우기

docker run -dit -p 9999:80 --name httpdweb myweb2 /bin/sh -c httpd-foreground

 

새롭게 생성한 docker container 조사(inspect)하기

docker inspect httpdweb

 

새롭게 덮어씌워진 CMD 명령 확인하기

CMD ["/bin/sh", "-c", "httpd-foreground"]

 

 

댓글