Dockerfile 명령어 정리

2022. 6. 10. 16:02CM/docker

반응형

봐도 봐도 잘 까먹는 Dockerfile 명령어..정리 해보았습니다.

Dockerfile 포맷


#주석

명령어(INSTRUCTION)  인자(arguments)

ex) 

#dockerfile format ex

FROM ubuntu:latest


FROM 명령어 

FROM <image>

FROM <image>:<tag>

하나의 Docker image는 base 이미지부터 시작해서 기존 이미지 위에 새로운 이미지를 중첩해서 여러 단계의 이미지 층(layer)을 쌓아가며 만들어 집니다.

FROM 명령어는 이 base image를 지정해주기 위해서 사용되고 보통 Dockerfile 내에서 최상단에 위치 합니다.
base image는 일반적으로 Docker Hub 등 공개 이미지인 경우가 많음.

ex)

FROM node:12

FROM python:3.8-alpine

FROM mdock.daumkakao.io/eclipse-temurin:17-alpine as jre-build

 


RUN 명령어

RUN ["<커맨드>", "<파라미터1>", "<파라미터2>"]
RUN <전체 커맨드>

RUN 명령어는 마치 Shell에서 커맨드를 실행하는 것처럼 이미지 빌드 과정에서 필요한 cmd를 실행하기 위해 사용 됩니다.

보통 이미지 안에 특정 소프트웨어를 설치하기 위해 많이 사용 됩니다.

  • curl 도구 설치
    • RUN apk add curl
  • npm 패키지 설치
    • RUN npm install --silent
  • bin utils
    • RUN apk add binutils

 


WORKDIR 명령어

WORKDIR 명령어는 Shell의 cd 명령어처럼 컨테이너상에서 작업 디렉토리로 전환을 위해서 사용 됩니다.

WORKDIR 명령어로 작업 디렉토리를 전환하면 그 이후에 사용하는 모든 RUN, CMD, ENTYPOINT, COPY, ADD 명령어들은 해당 디렉토리를 기준으로 실행 됩니다.

 

WORKDIR <이동할 경로>

ex) /kaas/app로 작업 디렉토리 전환

WORKDIR /kaas/app

 


ENV 명령어

ENV <키> <값>

ENV <키>=<값>

ENV 명령어는 환경 변수를 설정하기 위해서 사용 됩니다.
ENV 명령어로 설정 된 환경 변수는 이미지 빌드 시에도 사용 됨은 물론이고, 해당 컨테이너에서 돌아가는 application도 접근할 수 있습니다.

  • 자바 환경변수 설정
    • ENV JAVA_HOME=/opt/java/openjdk
    • ENV PATH "${JAVA_HOME}/bin:${PATH}"

 


COPY/ADD 명령어

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

COPY 명령어는 HOST 컴퓨터에 있는 디렉토리나 파일을 Docker image의 filte system으로 복사하기 위해서 사용 됩니다.
절대경로와 상대경로 모두 지원하며, 상대경로를 사용할 때는 위에서 설명한 WORKDIR 명령어로 작업 디렉토리를 어디로 해놨는지 체크 해야 합니다.

  • /javaruntime dir의 파일을 $JAVA_HOME 디렉토리로 복사 합니다.
    • COPY --from=jre-build /javaruntime $JAVA_HOME

ADD 명령어는 좀 더 파워풀한 COPY 명령어라고 생각할 수 있습니다.
ADD 명령어는 일반 파일 뿐만 아니라 압축파일이나 네트워크상의 파일도 사용할 수 있습니다.
이렇게 특수한 파일을 다루는게 아니라면 COPY 명령어를 사용하는것을 권장 합니다.

 


ARG 명령어

ARG <이름>

ARG <이름>=<기본 값>

ARG 명령문은 docker build 커맨드로 이미지를 빌드시, --build-arg 옵션을 통해 넘길 수 있는 인자를 정의하기 위해 사용 됩니다.

예를 들어 다음과 같이 ARG 명령어로  JAR_PATH를 인자로 선언해주면

# Retrieve jar from local jar
ARG JAR_PATH

다음과 같이 docker build 커맨드에 --build-arg 옵션에 JAR_PATH값을 넘길 수가 있습니다.

$docker build ==build-arg JAR_PATH=블라블라 .

인자에 디폴트 값을 지정해주면 --build-arg 옵션으로 해당 인자가 넘어오지 않았을때 사용 됩니다.
ARG JAR_PATH=/usr/app

설정된 인자 값은 다음과 같이 ${인자명} 형태로 읽어서 사용할 수 있습니다.

ADD ${JAR_PATH} "/app.jar"

ENV와는 달리 ARG로 설정한 값은 이미지가 빌드되는 동안에만 유효 합니다.

 


ENTRYPOINT 명령어 

ENTRYPOINT ["<커맨드>", "<파라미터1>", "<파라미터2>"]

ENTRYPOINT <전체 커맨드>

ENTRYPOINT 명령어는 이미지를 컨테이너로 띄울 때 항상 실행되야 하는 커맨드를 지정할 때 사용합니다.

ENTRYPOINT 명령어는 Docker 이미지를 마치 하나의 실행 파일처럼 사용할 때 유용 합니다.

왜냐하면 컨테이너가 뜰 때 ENTRYPOINT 명령어로 지정된 커맨드가 실행되고, 이 커맨드로 실행된 프로세스가 죽을 때, 컨테이너도 따라서 종료되기 때문 입니다.

  • /app.jar 실행
    • ENTRYPOINT ["java","-jar","/app.jar"]
  • npm start script 실행
    • ENTRYPOINT ["npm", "start"]

 


CMD 명령어

CMD ["<커맨드>","<파라미터1>","<파라미터2>"] CMD ["<파라미터1>","<파라미터2>"] CMD <전체 커맨드>

CMD 명령어는 해당 이미지를 컨테이너로 띄울때 디폴트로 실행할 커맨드ENTRYPOINT 명령어로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용합니다.
CMD 명령어는 보통 ENTRYPOINT 명령어와 함께 사용하게 되는데 ENTRYPOINT 명령어로는 커맨드를 지정하고,
CMD 명령어로는 디폴트 파라미터를 지정해주면 매우 유연하게 이미지를 실행할 수 있게 됩니다.

예를 들어 node 커맨드로 디폴트로 index.js를 실행하고, docker run 커맨드에 인자가 있는 경우, 해당 인자를 실행하고 싶은 경우, 다음과 같이 Dockerfile을 작성 합니다.
ENTRYPOINT ["node"]
CMD ["index.js"] <-- default로 지정

이제 docker run 커맨드의 인자 유무에 따라 node 커맨드로 파일이 실행 됩니다.
 

  • node index.js 실행(default로 지정해준 CMD["index.js]가 수행 
    • docker run test
  • node main.js 실행
    • docker run test main.js

 

CMD와 RUN명령어가 헷갈릴수 있는데 RUN은 이미지 빌드 시 항상 실행 되며, 한 Dockerfile에 여러 개의 RUN 명령어를 선언 할 수 있습니다.

반면에 CMD명령어는 이미지를 container로 띄울 때 단 한번 실행 기회를 가지게 되며, 이 기회 마저도 docker run 커맨드에 인자를 넘길 경우 상실하게 됩니다.

(위 main.js 실행 예시 참고)

 


 

명령어용도

FROM base image를 설정
RUN image build시 커맨드 실행
WORKDIR 작업 디렉토리 설정
ENV 환경 변수 설정
COPY/ADD image의 filesystem으로 파일 또는 디렉토리 복사
ARG build 시 넘어 올수 있는 인자 설정
ENTRYPOINT image 실행 시 항상 실행되야 하는 커맨드 설정
CMD image 실행 시 디폴트 커맨드 또는 파라미터 설정

참고 : https://docs.docker.com/engine/reference/builder/

반응형
LIST

'CM > docker' 카테고리의 다른 글

Dockerfile 명령어 정리  (0) 2022.06.10
docker 빌드로 이미지를 만들어보자!(작성 중)  (0) 2022.01.25
Docker 리서치  (0) 2021.02.03
Docker ?  (0) 2017.06.27
about docker  (0) 2017.04.27