본문 바로가기
Docker

Dockerfile은 무엇일까?

by 진꿈청 2024. 3. 2.

우리가 만든 우리의 애플리케이션을 이미지로 만든다고 가정해보자.

  1. 비어있는 도커 OS 이미지 생성
  2. Git clone을 통해 해당 소스코드를 OS(우분투) 이미지 내로 복사
  3. 소스코드 담겨있는 우분투 이미지를 컨테이너에서 이미지화해서 배포

개발을 하고 배포를 하는 과정은 한 번만 이루어지는 것이 아닌 계속해서 이루어지게 된다.

그렇다면 위의 과정은 매우 반복적인 작업이다. 따라서, 이를 하나를 묶을 수 있는 작업이 필요하다.

이것을 도커 파일이 작업을 대신 해주게 된다.

도커 파일

Dockerfile의 정확한 정의는 다음이다.

하나의 완성된 이미지를 구성하기 위해서 있어야 할 패키지, 의존성, 소스코드, 스크립트들을

하나의 file로 기록하여 도커가 읽고 이를 실행시켜 이미지화 시킬 명령 파일.

Dockerfile은 위의 과정을 빌드(Build) 과정이라 하며 이런 빌드를 위한 명령어가 바로 빌드 명령어이다.

해당 빌드 명령어를 이용해 우리는 도커 파일구성한다.

도커라이징 Dockerizing

도커라이징은 도커화를 시킨다는 것을 의미한다.

그 말은 즉, Dockerfile을 만들고 도커 이미지화 시키는 과정을 말한다.

Dockerfile build 명령어

도커 파일의 빌드 명령어의 특징

  • 한 줄에는 하나의 명령어만 올 수 있다.
  • 명령어의 구조는 명령어 + 옵션의 구조로 명령어가 오게 된다.
  • 소문자 표기도 가능하나 일반적으로 대문자 표기를 우선으로 한다.

Dockerfile 명령어 종류

명령어는 다음과 같은 명령어가 존재한다.

  • From
  • MAINTAINER
  • RUN
  • ADD
  • WORKDIR
  • EXPOSE
  • CMD

FROM

FROM 명령어는 base Image를 지정한다.

주로 Ubuntu나 CentOS와 같은 OS를 지정하는데, 해당 도커 이미지는 기본적으로 어떤 이미지가 Base가 될 것인지를 명시해줄 수 있다.

FROM ubuntu:latest

MAINTAINER

MAINTAINER 명령어는 이미지를 생성한 사람의 정보를 설정한다.

형식은 자유 형식인데 보통 이미지나 닉네임을 입력한다.

크게 없어도 문제가 되지 않는 명령어이다.

MAINTAINER RECORD, developer <test@gmail.com>

그러나, MAINTAINER는 Deprecated 되었다고 한다.

따라서, LABEL 명령어를 사용한다.

LABEL

LABEL 명령어는 MAINTAINER과 같이 이미지에 METADATA를 추가해주는데, Key-Value로 이루어진다.

LABEL email="example@gmail.com"
LABEL name="example"
LABEL version="1.0"
LABEL description="My Spring Application?"

그리고 Dockerfile은 하나 이상의 LABEL을 가질 수 있다.

Image의 LABEL 확인하기

docker image inspect --format = ' ' my-image-name

RUN

RUN 명령어는 해당 도커 컨테이너 내의 package를 설치한다던지 이미지 내부에서 실행할 명령어를 명시하는 명령어이다.

리액트를 도커라이징 한다면 처음으로 npm install을 수행해야 react-script와 다른 패키지를 npm으로 install 하게 된다.

RUN 사용 예

RUN ["apt-get", "install", "-y", "nginx"]

COPY

COPY 명령어는 호스트OS에서 이미지 안으로 복사가 가능하다.

즉, 호스트OS에서 이미지로 단순히 복사만을 처리할 때 COPY를 사용.

COPY test.sh /root/copy/test.sh

ADD

ADD 명령어는 파일이나 디렉토리를 호스트에서 Docker Image로 복사할 때 사용된다.

만약 ADD 하려는 디렉토리가 image에 존재하지 않으면 docker가 자동으로 생성되고 복사를 수행한다고 한다.
또한, ADD의 경우 원격 파일 다운로드 또는 압축 해제 등과 같은 기능을 갖고 있다고 한다.

ADD file /dir/dir/dir/file

ENV, ARG

ENV와 ARG는 비슷해 보이지만 다른 명령어이다.

ENV: Dockerfile 또는 컨테이너 안에서 환경 변수로 사용이 가능하다.
ARG: Dockerfile에서만 사용이 가능하다.

ENV

# ENV [key] [value]
ENV myName nirsa
ENV myAddress nirsa.tistory.com

# ENV [key]=[value]  ## 한번에 여러개의 값을 설정할 때 사용
ENV myName=nirsa \
    myAddress=nirsa.tistory.com

ARG

# [key]=[value]
ARG myName=nirsa
ARG myAddress=nirsa.tistory.com

WORKDIR

WORKDIR은 RUN이나 CMD, ENTRYPOINT와 같은 명령어를 수행할 디렉토리를 나타낸다.

Bash에서 cd 명령어를 입력하는 것과 같다.

WORKDIR /var/www

EXPOSE

EXPOSE 명령어는 컨테이너를 외부에 노출할 포트를 지정할 때 사용된다.

해당 컨테이너를 8917 포트로 노출하고 싶다면 다음과 같이 지정하면 된다.

EXPOSE 8917    

그러면 docker run -p과의 차이점에 대해 궁금할 수 있다.
docker run -dit -p 5005:5005 ubuntu 이런식으로 작성했을 때 호스트:8917 -> 컨테이너:8917번 포트로 연동이 된다.
하지만, EXPOSE의 경우는 docker run -P 옵션을 사용하면 EXPOSE로 지정했던 포트로 연동이 되지만 호스트에서는 랜덤으로 포트가 할당된다.

CMD

CMD 명령어는 도커 컨테이너가 시작할 때 실행할 커맨드를 지정할 수 있다.

RUN과 기능이 비슷한데, RUN은 이미지를 빌드할 때 실행하는데, CMD 명령어는 container가 시작될 때 실행한다.

CMD ["nginx", "-g", "daemon off;"]

ENTRYPOINT

ENTRYPOINT는 CMD 명령어와 거의 동일. 하지만, CMD에서는 인자값이 대체될 수 있지만, ENTRYPOINT는 불가능.

ENTRYPOINT ["java", "-jar", "/app.jar"]

CMD와 ENTRYPOINT의 공통점과 차이점

공통점

  • 둘 다 컨테이너 시작시 실행할 명령어를 지정해준다.
  • 컨테이너를 시작하려면 둘 중에 하나는 지정해주어야 한다.
  • 여러 CMD와 여러 ENTRYPOINT는 모두 실행되지 않고 맨 마지막 CMD, ENTRYPOINT만 실행된다.

차이점

  • ENTRYPOINT 명령어는 오버라이딩이 어렵고 CMD 명령어는 오버라이딩이 쉽다.
  • docker run시에 다른 실행 명령어가 있으면 CMD 명령어에 쓴 내용은 무시된다. 반면에 ÈNTRYPOINT 명령어는 무시되지 않고 docker run에 붙여준 실행 명령어를 인자로 받아서 컨테이너를 실행한다.
  • CMD 명령어는 docker run 명령 내에 명시된 매개변수가 있는 경우 Daemon에서 무시된다.
  • ENTRYPOINT 명령어는 무시되지 않고 대신 명령의 인수로 취급하여 매개변수로 추가된다.

CMD 명령어 사용 예시

FROM centos:7
CMD ["echo", "Hello, Darwin"]
docker build -f CMD_PRACTICE -t hello:cmd .
docker run hello:cmd
Hello, Darwin
docker run hello:cmd echo world
world
  • CMD 명령어를 사용하는 가장 좋은 방법은 사용자가 CLI에 인자를 입력하지 않을 때 실행할 기본 프로그램 지정이다.
  • 사용자는 docker run 명령어 실행시 인자를 사용ㅇ한다면 Docerfile 내의 지정된 지침을 재정의한다.

ENTRYPOINT 명령어 사용 예시

FROM centos:7
ENTRYPOINT ["echo", "Hello, Darwin"]
docker build -f ENTRYPOINT_PRACTICE -t hello:entrypoint .
docker run hello:entrypoint
Hello, Darwin
docker run hello:entrypoint world
Hello, Darwin world
  • ENTRYPOINT 명령어는 컨테이너가 시작될 때 필수적으로 특정 명령을 실행해야 하는 경우에 적합.

ENTRYPOINT와 CMD 함께 사용

  • 두 개를 혼합하는 가장 보편적인 사용 사례는 컨테이너 시작 작업 자동화.
  • CMD를 사용하여 매개 변수를 정의하고 ENTRYPOINT 명령을 사용하여 실행 파일 정의
FROM centos:7
ENTRYPOINT ["echo", "Hello,"]
CMD ["Darwin"]
docker build -f ENTRYPOINT_PRACTICE -t hello:entrypoint .
docker run hello:together
Hello, Darwin # 매개변수 없이 컨테이너를 실행하면 CMD에 지정한 인자 사용
docker run hello:together world
Hello, world # 매개변수 넘겨주면 CMD 기본값은 오버라이딩되어 무시됨


참고 블로그

 

https://nirsa.tistory.com/69

 

[Docker CE] dockerfile 명령어 정리 (3) (COPY, ADD, ENV, ARG, WORKDIR)

1편 (RUN, CMD, ENTRYPOINT) : https://nirsa.tistory.com/66?category=868315 2편 (ONBUILD, STOPSIGNAL, HEALTHCHECK) : https://nirsa.tistory.com/68?category=868315 4편 (USER, LABEL, EXPOSE, VOLUME) : https://nirsa.tistory.com/70?category=868315 들어가기

nirsa.tistory.com

https://velog.io/@inhalin/ENTRYPOINT-CMD-%EC%B0%A8%EC%9D%B4

 

ENTRYPOINT, CMD 차이

레퍼런스 > > - https://www.bmc.com/blogs/docker-cmd-vs-entrypoint/ > - https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact 둘 다 컨테이너 시작시 실행할 명령어를 지정해준다. 컨테이너를

velog.io

https://wonit.tistory.com/341

 

[Docker] Dockerfile 은 무엇일까? (1) - 도커파일이 뭐고 자주 쓰이는 명령어에 대해 알아보자.

해당 글은 2부작으로 이루어져 있습니다. Dockerfile 은 무엇일까? (1)- 도커 파일이 뭐고 어떤 명령어가 있는지 알아보자. 에서는 기본적으로 도커 파일이 무엇이고 왜 사용하며 어떤 명령어가 있는

wonit.tistory.com