🎇Docker를 이용하여 express를 background 에서 실행해보기
목표 : 기존 터미널에서 실행하던 express 서버를 docker image를 만들어 컨테이너를 생성 한 후 background에서 실행시키기!
1. 🚲 Docker image 만들기
docker image를 만들기 위한 Dockerfile 을 프로젝트의 root 폴더에 생성해줍니다.
Dockerfile 포멧
하나의 Dockerfile은 기본적으로 다음과 같은 구조를 가진 여러 개의 명령문으로 구성되어 있습니다.
#주석(Comment)
명령어(INSTRUCTION) 인자(arguments)
각 명령문은 명령어로 시작하고 여러 개의 인자가 따라올 수 있으며, 해당 명령문에 대한 주석도 달 수 있습니다.
인자와 구분이 쉽도록 명령어는 모두 영문 대문자로 써주는 것이 관례입니다.
FROM node:16
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --silent
COPY . .
ARG port
EXPOSE ${port}
ENTRYPOINT ["node"]
CMD ["index.js" ]
생성한 Dockerfile 안에 위의 내용을 작성해줍니다.
✔ 이때 파일 이름을 Dockerfile이 아니라 다른 이름으로 해도 괜찮지만, 그렇게 할 시 설정할 때 추가적으로 바꾼 이름으로 설정을 추가해줘야 하므로 편하게 default 이름인 Dockerfile로 생성하였습니다.
이때 위의 작성한 내용들이 의미하는 바를 하나씩 정리해보겠습니다.
FROM 명령어
FROM
: 어떤 이미지를 사용해서 빌드할 것인지를 정의하는 것 [ 코드를 작성할 때 node의 최신 버전인 16
을 사용했기 때문에 node:16
으로 설정해주었습니다.
FROM 명령문
FROM <이미지>
FROM <이미지>:<태그>
하나의 Docker Image
는 base image
부터 시작해서 기존 이미지위에 새로운 이미지를 중첩해서 여러 단계의 이미지 층(layer)을 쌓아가며 만들어집니다.FROM
명령문은 이 base image
를 지정해주기 위해서 사용되는데, 보통 Dockerfile
내에서 최상단에 위치합니다. base image
는 일반적으로 Docker Hub
와 같은 Docker repository
에 올려놓은 잘 알려진 공개 이미지인 경우가 많습니다.
예시 : NodeJS 16
를 base
이미지로 사용
FROM node:16
WORKDIR 명령문
WORKDIR
: 이미지 안에 애플리케이션 코드를 넣기 위한 디렉터리를 생성하는 명령어로 이 디렉터리가 애플리케이션의 작업 디렉터리가 됩니다.WORKDIR
명령문
WORKDIR <이동할 경로>
WORKDIR
명령문은 shell
의 cd
명령문처럼 컨테이너 상에서 작업 디텍토리로 전환을 위해서 사용됩니다.WORKDIR
명령문으로 작업 디렉터리를 전환하면 그 이후에 등장하는 모든 RUN, CMD, ENTRYPOINT, COPY, ADD
명령문은 해당 디렉터리를 기준으로 실행됩니다.
/usr/app
으로 작업 디렉터리 전환
WORKDIR /usr/app
COPY, ADD 명령문
COPY or ADD
:COPY
명령문은 호스트 컴퓨터에 있는 디렉터리나 파일을Docker image
의 파일 시스템으로 복사하기 위해서 사용됩니다.
절대 경로와 상대 경로를 모두 지원하며, 상대 경로를 사용할 때는 이 전에 등장하는WORKDIR
명령문으로 작업 디렉터리를 어디로 전환을 해놨는지 고려해야 합니다.
# COPY 명령문
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
ADD
명령문은 좀 더 파워풀한 COPY
명령문이라고 생각할 수 있습니다.ADD
명령문은 일반 파일 뿐만 아니라 압축 파일이나 네트워크 상의 파일도 사용할 수 있습니다.
이렇게 특수한 파일을 다루는 게 아니라면 COPY
명령문을 사용하는 것이 권장됩니다.
package.json
파일만 복사
COPY package.json ./
이미지를 빌드한 디렉터리의 모든 파일을 컨테이너의 app/ directory
로 복사
WORKDIR app/ COPY . .
package.json
과 package-lock.json
을 모두 복사하기 위해 와일드카드 사용
COPY package*.json ./
RUN 명령문
RUN
RUN
명령문은 마치shell
에서 커맨드를 실행하는 것 처럼 이미지 빌드 과정에서 필요한 커맨드를 실행하기 위해서 사용됩니다.shell
을 통해 거의 못하는 작업이 없는 것 처럼RUN
명령문으로 할 수 있는 작업은 무궁무진하지만 보통 이미지 안에 특정 소트트웨어를 설치하기 위해서 많이 사용됩니다.- npm 패키지 설치
RUN ["<커맨드>", "<파라미터1>", "<파라미터2>"] RUN <전체 커맨드>
RUN npm install --silent
- curl 도구 설치
RUN apk add curl
- pip 패키지 설치
RUN pip install -r requirements.txt
EXPOSE 명령문
EXPOSE
EXPOSE
명령문은 네트워크 상에서 컨테이너로 들어오는트래픽(traffic)
을리스닝(listening)
하는포트
와프로토콜
를 지정하기 위해서 사용됩니다.프로토콜
은TCP
와UDP
중 선택할 수 있는데 지정하지 않으면TCP
가 기본값으로 사용됩니다.
EXPOSE <포트>
EXPOSE <포트>/<프로토콜>
❗ 여기서 주의할 점은 EXPOSE
명령문으로 지정된 포트
는해당 컨테이너의 내부
에서만 유효하며, 호스트(host)
컴퓨터에서는 이 포트를 바로 접근을 할 수 있는 것은 아니라는 겁니다.
호스트 컴퓨터로부터 해당 포트로의 접근을 허용하려면, docker run
커맨드를-p
옵션을 통해 호스트 컴퓨터의 특정 포트
를 포워딩(forwarding)
시켜줘야 합니다.
ENTRYPOINT 명령문
ENTRYPOINT
:ENTRYPOINT
명령문은 이미지를 컨테이너로 띄울 때 항상 실행되야 하는 커맨드를 지정할 때 사용합니다.ENTRYPOINT
명령문은Docker image
를 마치 하나의 실행 파일처럼 사용할 때 유용합니다.
왜냐하면 컨테이너가 뜰 때ENTRYPOINT
명령문으로 지정된 커맨드가 실행되고, 이 커맨드로 실행된 프로세스가 죽을 때, 컨테이너로 따라서 종료되기 때문입니다.
ENTRYPOINT ["<커맨드>", "<파라미터1>", "<파라미터2>"]
ENTRYPOINT <전체 커맨드>
npm start
스크립트 실행ENTRYPOINT ["npm", "start"]
Django
서버 실행ENTRYPOINT ["python", "manage.py", "runserver"]
CMD 명령문
CMD
:CMD
명령문은 해당 이미지를 컨테이너로 띄울 때 디폴트로 실행할 커맨드나,ENTRYPOINT
명령문으로 지정된 커맨드에 디폴트로 넘길 파라미터를 지정할 때 사용합니다.CMD
명령문은 많은 경우,ENTRYPOINT
명령문과 함께 사용하게 되는데, ENTRYPOINT 명령문으로는 커맨드를 지정하고,CMD
명령문으로 디폴트 파리미터를 지정해주면 매우 유연하게 이미지를 실행할 수 있게 됩니다.
CMD ["<커맨드>","<파라미터1>","<파라미터2>"]
CMD ["<파라미터1>","<파라미터2>"]
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
ENV 명령문
ENV
ENV
명령문은 환경 변수를 설정하기 위해서 사용합니다.ENV
명령문으로 설정된 환경 변수는 이미지 빌드 시에도 사용됨은 물론이고, 해당 컨테이너에서 돌아가는 애플리케이션도 접근할 수 있습니다.ENV <키> <값> ENV <키>=<값>
NODE_ENV
환경 변수를production
으로 설정ENV NODE_ENV production
ARG 명령문
ARG
:ARG
명령문은docker build
커맨드로 이미지를 빌드 시,--build-arg
옵션을 통해 넘길 수 있는 인자를 정의하기 위해 사용합니다.ARG <이름> ARG <이름>=<기본 값>
예를 들어, Dockerfile
에 다음과 같이 ARG
명령문으로 port
를 인자로 선언해주면,
ARG port
다음과 같이 docker build
커맨드에 --build-arg
옵션에 port
값을 넘길 수가 있습니다.
$ docker build --build-arg port=8080 .
설정된 인자 값은 다음과 같이 ${인자명}
형태로 읽어서 사용할 수 있습니다.
CMD start.sh -h 127.0.0.1 -p ${port}
2. 🚓 .dockerignore 파일 만들기
Docker image
를 빌드할 때 제외 시키고 싶은 파일이 있다면, .dockerignore
파일에 추가해주면 됩니다.
.dockerignore
.git
.md
위처럼 설정을 해주면 Docker
는 프로젝트 최상위 디렉터리에 위치하고 있는 markdown
파일들을 무사하게 되므로, RUN
과 CMD, COPY
와 같은 명령문이 해당 파일을 사용할 수 없게 됩니다.
실사용 : Docker
이미지에 로컬 모듈과 디버깅 로그를 복사하는 것을 막아서 이미지 내에서 설치한 모듈을 덮어쓰지 않게 하기 위해 .dockerignore
파일을 만들어 줍니다.
node_modules
npm-debug.log
만든 후 위의 내용을 추가해줍니다.
3. 🛵 Docker 실행해보기
위 처럼 docker 명령어를 통해 실행해 줄 시 아래처럼 로그에 작성했던 명령문들이 실행되며 진행되는 것을 볼 수 있다!
'Study > 이것저것' 카테고리의 다른 글
[Error] Node 에서 환경 변수를 읽어오지 못하는 오류 (0) | 2022.03.16 |
---|---|
[ Postman ] 포스트맨 사용해보기! (0) | 2021.12.30 |