분량은 걱정 안해도 되것다.
FROM adoptopenjdk / xxxx
RUN mkdir -p /xxx
COPY build/libs/*.jar /xxx
WORKDIR /xxxx
ARG SPRING_PROFILES_ACTIVE
ENV SPRING_PROFILES_ACTIVE=$SPRING_PROFILES_ACTIVE
ENTRYPOINT ["java", "-jar"]
일단 규격은 봤는데 구성은 아직도 감이 안 잡혔으니... 학습할건 태산이군.
---------------------------------------------------
Dockerfile 포멧
하나의 Dockerfile은 기본적으로 다음과 같은 구조를 가진 여러 개의 명령문으로 구성되어 있습니다.
# 주석(Comment) 명령어(INSTRUCTION) 인자(arguments)
각 명령문은 명령어로 시작하고 여러 개의 인자가 따라올 수 있으며, 해당 명령문에 대한 주석도 달 수 있습니다. 인자와 구분이 쉽도록 명령어는 모두 영문 대문자로 써주는 것이 관례입니다.
FROM 명령문
FROM <이미지> FROM <이미지>:<태그>
하나의 Docker 이미지는 base 이미지부터 시작해서 기존 이미지위에 새로운 이미지를 중첩해서 여러 단계의 이미지 층(layer)을 쌓아가며 만들어집니다.
FROM 명령문은 이 base 이미지를 지정해주기 위해서 사용되는데, 보통 Dockerfile 내에서 최상단에 위치합니다. base 이미지는 일반적으로 Docker Hub와 같은 Docker repository에 올려놓은 잘 알려진 공개 이미지인 경우가 많습니다.
- Ubuntu 최신 버전을 base 이미지로 사용
FROM ubuntu:latest
- NodeJS 12를 base 이미지로 사용
FROM node:12
- Python 3.8 (alpine 리눅스 기반)을 base 이미지로 사용
FROM python:3.8-alpine
WORKDIR 명령문
WORKDIR 명령문은 쉘(shell)의 cd 명령문처럼 컨테이너 상에서 작업 디텍토리로 전환을 위해서 사용됩니다. WORKDIR 명령문으로 작업 디렉터리를 전환하면 그 이후에 등장하는 모든 RUN, CMD, ENTRYPOINT, COPY, ADD 명령문은 해당 디렉터리를 기준으로 실행됩니다.
WORKDIR <이동할 경로>
- /usr/app으로 작업 디렉터리 전환
WORKDIR /usr/app
RUN 명령문
RUN ["<커맨드>", "<파라미터1>", "<파라미터2>"] RUN <전체 커맨드>
RUN 명령문은 마치 쉘(shell)에서 커맨드를 실행하는 것 처럼 이미지 빌드 과정에서 필요한 커맨드를 실행하기 위해서 사용됩니다. 쉘(shell)을 통해 거의 못하는 작업이 없는 것 처럼 RUN 명령문으로 할 수 있는 작업은 무궁무진하지만 보통 이미지 안에 특정 소트트웨어를 설치하기 위해서 많이 사용됩니다.
- curl 도구 설치
RUN apk add curl
- npm 패키지 설치
RUN npm install --silent
- pip 패키지 설치
RUN pip install -r requirements.txt
ENTRYPOINT 명령문
ENTRYPOINT ["<커맨드>", "<파라미터1>", "<파라미터2>"] ENTRYPOINT <전체 커맨드>
ENTRYPOINT 명령문은 이미지를 컨테이너로 띄울 때 항상 실행되야 하는 커맨드를 지정할 때 사용합니다. ENTRYPOINT 명령문은 Docker 이미지를 마치 하나의 실행 파일처럼 사용할 때 유용합니다. 왜냐하면 컨테이너가 뜰 때 ENTRYPOINT 명령문으로 지정된 커맨드가 실행되고, 이 커맨드로 실행된 프로세스가 죽을 때, 컨테이너로 따라서 종료되기 때문입니다.
- npm start 스크립트 실행
ENTRYPOINT ["npm", "start"]
- Django 서버 실행
ENTRYPOINT ["python", "manage.py", "runserver"]
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"]
그러면 다음과 같이 docker run 커맨드의 인자 유무에 따라 node 커맨드로 다른 파일이 실행되게 할 수 있습니다.
- node index.js 실행
$ docker run test
- node main.js 실행
$ docker run test main.js
CMD 명령문과 RUN 명령문이 햇갈릴 수가 있는데, RUN 명령문은 이미지 빌드 시 항상 실행되며, 한 Dockerfile에 여러 개의 RUN 명령문을 선언할 수 있습니다. 반면에, CMD 명령문은 이미지를 continaer로 띄울 때 딱 한 번 실행 기회를 가지게 되며, 이 기회마저도 docker run 커맨드에 인자를 넘길 경우 상실하게 됩니다.
예를 들어, 다음과 같이 Dockerfile 파일에 Hi를 출력하는 CMD 명령문이 있을 때,
CMD ["echo", "Hi"]
인자 없이 이미지를 실행하면 Hi가 출력되지만, 인자로 대신 실행될 커맨드를 넘기면 해당 인자가 출력되는 것을 알 수 있습니다.
$ docker run test Hi $ docker run test echo Bye Bye
EXPOSE 명령문
EXPOSE <포트> EXPOSE <포트>/<프로토콜>
EXPOSE 명령문은 네트워크 상에서 컨테이너로 들어오는 트래픽(traffic)을 리스닝(listening)하는 포트와 프로토콜를 지정하기 위해서 사용됩니다. 프로토콜은 TCP와 UDP 중 선택할 수 있는데 지정하지 않으면 TCP가 기본값으로 사용됩니다.
여기서 주의할 점은 EXPOSE 명령문으로 지정된 포트는 해당 컨테이너의 내부에서만 유효하며, 호스트(host) 컴퓨터에서는 이 포트를 바로 접근을 할 수 있는 것은 아니라는 겁니다. 호스트 컴퓨터로부터 해당 포트로의 접근을 허용하려면, docker run 커맨드를 -p 옵션을 통해 호스트 컴퓨터의 특정 포트를 포워딩(forwarding)시켜줘야 합니다.
- 80/TCP 포트로 리스닝
EXPOSE 80
- 9999/UDP 포트로 리스닝
EXPOSE 9999/udp
COPY/ADD 명령문
COPY <src>... <dest> COPY ["<src>",... "<dest>"]
COPY 명령문은 호스트 컴퓨터에 있는 디렉터리나 파일을 Docker 이미지의 파일 시스템으로 복사하기 위해서 사용됩니다. 절대 경로와 상대 경로를 모두 지원하며, 상대 경로를 사용할 때는 이 전에 등장하는 WORKDIR 명령문으로 작업 디렉터리를 어디로 전환을 해놨는지 고려해야 합니다.
- package.json 파일만 복사
COPY package.json package.json
- 이미지를 빌드한 디렉터리의 모든 파일을 컨테이너의 app/ 디렉터리로 복사
WORKDIR app/ COPY . .
ADD 명령문은 좀 더 파워풀한 COPY 명령문이라고 생각할 수 있습니다. ADD 명령문은 일반 파일 뿐만 아니라 압축 파일이나 네트워크 상의 파일도 사용할 수 있습니다. 이렇게 특수한 파일을 다루는 게 아니라면 COPY 명령문을 사용하는 것이 권장됩니다.
ENV 명령문
ENV <키> <값> ENV <키>=<값>
ENV 명령문은 환경 변수를 설정하기 위해서 사용합니다. ENV 명령문으로 설정된 환경 변수는 이미지 빌드 시에도 사용됨은 물론이고, 해당 컨테이너에서 돌아가는 애플리케이션도 접근할 수 있습니다.
- NODE_ENV 환경 변수를 production으로 설정
ENV NODE_ENV production
ARG 명령문
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}
.dockerignore 파일
명령문은 아니지만 .dockerignore 파일도 알아두면 Dockerfile을 작성할 때 유용합니다. Docker 이미지를 빌드할 때 제외 시키고 싶은 파일이 있다면, .dockerignore 파일에 추가해주면 됩니다.
예를 들어, .git 디렉터리와 마크다운(markdown) 파일을 모두 제외 시키고 싶다면 다음과 같이 .dockerignore 파일을 작성해주면 됩니다.
- .dockerignore
.git *.md
이렇게 설정을 해주면 Docker는 프로젝트 최상위 디렉터리에 위치하고 있는 markdown 파일들을 무사하게 되므로, RUN과 CMD, COPY와 같은 명령문이 해당 파일을 사용할 수 없게 됩니다.
정리
지금까지 설명드린 Dockerfile의 명령어를 정리해보면 다음과 같습니다.
명령어용도
FROM | base 이미지 설정 |
WORKDIR | 작업 디렉터리 설정 |
RUN | 이미지 빌드 시 커맨드 실행 |
ENTRYPOINT | 이미지 실행 시 항상 실행되야 하는 커맨드 설정 |
CMD | 이미지 실행 시 디폴트 커맨드 또는 파라미터 설정 |
EXPOSE | 컨테이너가 리스닝할 포트 및 프로토콜 설정 |
COPY/ADD | 이미지의 파일 시스템으로 파일 또는 디렉터리 복사 |
ENV | 환경 변수 설정 |
ARG | 빌드 시 넘어올 수 있는 인자 설정 |
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
'jira, confluence, 도커[패캠챌린지]' 카테고리의 다른 글
패스트캠퍼스 챌린지 25일차: Docker Hub & Docker API - 2 (0) | 2021.09.30 |
---|---|
패스트캠퍼스 챌린지 24일차: Docker Hub & Docker API - 1 (0) | 2021.09.29 |
패스트캠퍼스 챌린지 22일차: 도커 이미지만들기(Dockerfile) 및 실행1(인데 삽질기록이 메인) (0) | 2021.09.27 |
패스트캠퍼스 챌린지 21일차: 도커 설치하기 & 컨테이너 접속하기 (0) | 2021.09.26 |
패스트캠퍼스 챌린지 20일차: bitbucket 사용법[돌려라 번역기] (0) | 2021.09.25 |