명령어 | 용도 |
---|---|
FROM | base 이미지 설정 |
WORKDIR | 작업 디렉터리 설정 |
RUN | 이미지 빌드 시 커맨드 실행 |
ENTRYPOINT | 이미지 실행 시 항상 실행되야 하는 커맨드 설정 |
CMD | 이미지 실행 시 디폴트 커맨드 또는 파라미터 설정 |
EXPOSE | 컨테이너가 리스닝할 포트 및 프로토콜 설정 |
COPY/ADD | 이미지의 파일 시스템으로 파일 또는 디렉터리 복사 |
ENV | 환경 변수 설정 |
ARG | 빌드 시 넘어올 수 있는 인자 설정 |
# 주석(Comment)
명령어(INSTRUCTION) 인자(arguments)
FROM <이미지>
FROM <이미지>:<태그>
EX)
Ubuntu 최신 버전을 base 이미지로 사용
FROM ubuntu:latest
NodeJS 12를 base 이미지로 사용
FROM node:12
Python 3.8 (alpine 리눅스 기반)을 base 이미지로 사용
FROM python:3.8-alpine
하나의 Docker 이미지는 base 이미지부터 시작해서 기존 이미지위에 새로운 이미지를 중첩해서 여러 단계의 이미지 층(layer)을 쌓아가며 만들어집니다.
FROM
명령문은 이 base 이미지를 지정해주기 위해서 사용되는데, 보통 Dockerfile 내에서 최상단에 위치합니다.
base 이미지는 일반적으로 Docker Hub와 같은 Docker repository에 올려놓은 잘 알려진 공개 이미지인 경우가 많습니다.
WORKDIR <이동할 경로>
WORKDIR /usr/app
WORKDIR
명령문은 쉘(shell)의 cd
명령문처럼 컨테이너 상에서 작업 디텍토리로 전환을 위해서 사용됩니다. WORKDIR
명령문으로 작업 디렉터리를 전환하면 그 이후에 등장하는 모든 RUN
, CMD
, ENTRYPOINT
, COPY
, ADD
명령문은 해당 디렉터리를 기준으로 실행됩니다.RUN ["<커맨드>", "<파라미터1>", "<파라미터2>"]
RUN <전체 커맨드>
EX)
curl
도구 설치RUN apk add curl
npm
패키지 설치RUN npm install --silent
pip
패키지 설치RUN pip install -r requirements.txt
ENTRYPOINT ["<커맨드>", "<파라미터1>", "<파라미터2>"]
ENTRYPOINT <전체 커맨드>
EX)
npm start
스크립트 실행ENTRYPOINT ["npm", "start"]
Django
서버 실행ENTRYPOINT ["python", "manage.py", "runserver"]
ENTRYPOINT
명령문은 이미지를 컨테이너로 띄울 때 항상 실행되야 하는 커맨드를 지정할 때 사용합니다. ENTRYPOINT
명령문은 Docker 이미지를 마치 하나의 실행 파일처럼 사용할 때 유용합니다. 왜냐하면 컨테이너가 뜰 때 ENTRYPOINT
명령문으로 지정된 커맨드가 실행되고, 이 커맨드로 실행된 프로세스가 죽을 때, 컨테이너로 따라서 종료되기 때문입니다.CMD ["<커맨드>","<파라미터1>","<파라미터2>"]
CMD ["<파라미터1>","<파라미터2>"]
CMD <전체 커맨드>
CMD
명령문은 해당 이미지를 컨테이너로 띄울 때 디폴트로 실행할 커맨드나, ENTRYPOINT
명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용합니다.
CMD
명령문은 많은 경우, ENTRYPOINT
명령문과 함께 사용하게 되는데, ENTRYPOINT
명령문으로는 커맨드를 지정하고, CMD
명령문으로 디폴트 파리미터를 지정해주면 매우 유연하게 이미지를 실행할 수 있게 됩니다.
예를 들어, node
커맨드로 디폴트로는 index.js
를 실행하되, docker run
커맨드에 인자가 있는 경우, 해당 인자를 실행하고 싶은 경우, 다음과 같이 Dockerfile을 작성합니다.
ENTRYPOINT ["node"] CMD ["index.js"]
docker run
커맨드의 인자 유무에 따라 node
커맨드로 다른 파일이 실행되게 할 수 있습니다.
node index.js
실행$ docker run test
node main.js
실행$ docker run test main.js
CMD
명령문과 RUN
명령문이 햇갈릴 수가 있는데, RUN
명령문은 이미지 빌드 시 항상 실행되며, 한 Dockerfile에 여러 개의 RUN
명령문을 선언할 수 있습니다. docker run
커맨드에 인자를 넘길 경우 상실하게 됩니다.: 예를 들어, 다음과 같이 Dockerfile 파일에 Hi
를 출력하는 CMD
명령문이 있을 때,
CMD ["echo", "Hi"]
인자 없이 이미지를 실행하면 Hi
가 출력되지만, 인자로 대신 실행될 커맨드를 넘기면 해당 인자가 출력되는 것을 알 수 있습니다.
$ docker run test Hi $ docker run test echo Bye Bye
EXPOSE <포트>
EXPOSE <포트>/<프로토콜>
EXPOSE
명령문은 네트워크 상에서 컨테이너로 들어오는 트래픽(traffic)을 리스닝(listening)하는 포트와 프로토콜를 지정하기 위해서 사용됩니다.
프로토콜은 TCP와 UDP 중 선택할 수 있는데 지정하지 않으면 TCP가 기본값으로 사용됩니다.
여기서 주의할 점은 EXPOSE
명령문으로 지정된 포트는 해당 컨테이너의 내부에서만 유효하며, 호스트(host) 컴퓨터에서는 이 포트를 바로 접근을 할 수 있는 것은 아니라는 겁니다.
호스트 컴퓨터로부터 해당 포트로의 접근을 허용하려면, docker run
커맨드를 -p
옵션을 통해 호스트 컴퓨터의 특정 포트를 포워딩(forwarding)시켜줘야 합니다.
EX)
80/TCP
포트로 리스닝EXPOSE 80
9999/UDP
포트로 리스닝EXPOSE 9999/udp
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
COPY
명령문은 호스트 컴퓨터에 있는 디렉터리나 파일을 Docker 이미지의 파일 시스템으로 복사하기 위해서 사용됩니다. WORKDIR
명령문으로 작업 디렉터리를 어디로 전환을 해놨는지 고려해야 합니다.EX)
package.json
파일만 복사COPY package.json package.json
이미지를 빌드한 디렉터리의 모든 파일을 컨테이너의
app/
디렉터리로 복사WORKDIR app/ COPY . .
ADD
명령문은 좀 더 파워풀한 COPY
명령문이라고 생각할 수 있습니다. ADD
명령문은 일반 파일 뿐만 아니라 압축 파일이나 네트워크 상의 파일도 사용할 수 있습니다.COPY
명령문을 사용하는 것이 권장됩니다.ENV <키> <값>
ENV <키>=<값>
ENV
명령문은 환경 변수를 설정하기 위해서 사용합니다. ENV
명령문으로 설정된 환경 변수는 이미지 빌드 시에도 사용됨은 물론이고, 해당 컨테이너에서 돌아가는 애플리케이션도 접근할 수 있습니다.EX)
NODE_ENV
환경 변수를production
으로 설정ENV NODE_ENV production
ARG <이름>
ARG <이름>=<기본 값>
ARG
명령문은 docker build
커맨드로 이미지를 빌드 시, --build-arg
옵션을 통해 넘길 수 있는 인자를 정의하기 위해 사용합니다.예를 들어, Dockerfile에 다음과 같이 ARG 명령문으로 port를 인자로 선언해주면,
ARG port
다음과 같이
docker build
커맨드에--build-arg
옵션에port
값을 넘길 수가 있습니다.$ docker build --build-arg port=8080 .
인자의 디폴트값을 지정해주면,
--build-arg
옵션으로 해당 인자가 넘어오지 않았을 때 사용됩니다.ARG port=8080
설정된 인자 값은 다음과 같이
${인자명}
형태로 읽어서 사용할 수 있습니다.CMD start.sh -h 127.0.0.1 -p ${port}
ENV
와 달리ARG
로 설정한 값은 이미지가 빌드되는 동안에만 유효하오니 주의 바랍니다.
.dockerignore
파일에 추가해주면 됩니다.예를 들어,
.git
디렉터리와 마크다운(markdown) 파일을 모두 제외 시키고 싶다면 다음과 같이.dockerignore
파일을 작성해주면 됩니다..git *.md
이렇게 설정을 해주면 Docker는 프로젝트 최상위 디렉터리에 위치하고 있는 markdown 파일들을 무사하게 되므로,
RUN
과CMD
,COPY
와 같은 명령문이 해당 파일을 사용할 수 없게 됩니다.