티스토리 뷰
이번에는 node + express 를 사용하여 간단한 서버를 docker로 실행해보려고 한다.
폴더 구조는 다음과 같다.
─ sample01
├─ src
│ └─ app.js
├─ .dockerignore
├─ Dockerfile
└─ package.json
app.js
const express = require('express'); const PORT = 8080; const app = express(); app.get('/', (req, res) => { res.send('Hello world\n'); }); app.listen(PORT, ()=>{ console.log(`Running on http://localhost:${PORT}`); }); |
package.json
{ "name": "sample02", "version": "1.0.0", "description": "Simple Node Server", "main": "src/app.js", "scripts": { "start": "node ./src/app.js" }, "author": "", "license": "ISC", "dependencies": { "express": "^4.16.4" } } |
우선 npm start 로 app.js를 실행하고 브라우저에서 http://localhost:8080/ 로 접속하여 Hello world를 확인한다.
위의 코드가 로컬에서 정상적으로 동작하는 것을 확인하였으니, 이제 docker로 실행해보도록 하자.
Dockerfile
FROM node:10 WORKDIR /app COPY package*.json /app/ RUN npm install COPY . /app EXPOSE 8080 CMD ["npm", "start"] |
.dockerignore
node_modules npm-debug.log |
Dockerfile을 보면 npm install 을 위해, package.json과 package-lock.json을 먼저 copy 하고 npm install 하는 것을 볼 수 있을 것이다.
npm install을 위해서 COPY package*.json /app/ 와 COPY . /app을 따로 분리한 이유는 docker image를 만드는 시간을 조금 더 최적화하기 위해서이다.
Docker의 경우 image를 생성할 때 layer라는 개념을 사용하고 있고, 이를 이용해서 docker image 생성에 대한 최적화를 할 수 있다.
간단히 설명하면 docker image를 생성할 때, Dockerfile의 명령어는 각각 수행하면서 새로운 layer를 생성하게 된다. 그리고 다음번에 동일한 Dockerfile을 이용하여 image를 생성하는 경우, 해당 명령어가 이전에 생성된 layer(캐싱되어 있음)를 그대로 사용하기도 하고, 새로 layer를 생성하기도 한다. docker build 명령을 사용하다 보면 아래와 같은 결과를 종종 보게 될 것이다.
Step 3/7 : COPY package*.json /app/ ---> Using cache ---> 5e565ab1e30b Step 6/7 : EXPOSE 8080 ---> Running in 4f0ff1d63d4f Removing intermediate container 4f0ff1d63d4f ---> 0185a951f9c2 |
Using cache / Running in xxxxx 이런 결과를 보면 해당 명령어가 새로 실행된 건지, 이전에 캐싱된 layer를 사용하는 건지 알 수 있다.
이렇게 글만 읽으면 무슨 개념인지 와 닿지 않을 수 있으니, 위에 만든 Dockerfile에서 어떻게 동작을 하는 건지 살펴보면서 이해를 해보자.
만약에 Dockerfile을 다음과 같이 작성하게 되면
COPY . /app RUN npm install |
package.json 파일이 수정되는 경우뿐 아니라, app.js 파일이 수정되는 경우에도 npm install 이 매번 동작을 하게 된다.
반면에 아래와 같이 작성을 하게 되면
COPY package*.json /app/ RUN npm install COPY . /app |
npm install은 package.json 파일이 수정되는 경우에만 동작을 하고, app.js 파일이 수정되는 경우에는 동작을 하지 않게 된다.
물론 생성된 image의 결과는 동일할 것이다. 하지만 js 파일의 코드를 수정하고 결과를 확인하기 위해서 docker를 실행하는 경우 매번 npm install 을 다시 수행하게 되면 전체적인 개발 시간에 미치는 영향은 훨씬 클 것이다.
'EXPOSE 8080' 은 docker container에서 외부로 노출되는 Port를 지정한다. (app.js 에서 8080 포트를 연결하였다.)
아래와 같이 docker image를 생성하고
❯ docker build --tag=sample02 . ❯ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE sample02 latest c0ef951d3c6a 46 seconds ago 902MB |
docker container를 실행해보자
❯ docker run --name=node_server -p 4440:8080 sample02 > sample02@1.0.0 start /app > node ./src/app.js Running on http://localhost:8080 |
docker를 실행할 때 -p 4440:8080 이라는 옵션을 사용하여 4440 포트를 container의 8080 포트랑 연결을 하였다.
브라우저에서 4440 포트로 접속하면 아래와 같이 정상 동작하는 것을 확인할 수 있다.
docker를 실행할 때 -d 옵션을 사용하면 background에서 실행시킬 수 있다.
❯ docker run --name=node_server -p 4440:8080 -d sample02 564b3f3e55a4a6c9f0e7e77bc411226dbc003f538ead04f44e9c747de04002ed ❯ docker container ls -all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 564b3f3e55a4 sample02 "npm start" 4 seconds ago Up 3 seconds 0.0.0.0:4440->8080/tcp node_server |
이렇게 -d 옵션으로 실행하는 경우 다음과 같이 로그를 확인할 수 있다.
❯ docker logs node_server > sample02@1.0.0 start /app > node ./src/app.js Running on http://localhost:8080 |
container에 접속하려면 다음 명령어로 접속을 할 수 있다.
❯ docker exec -it node_server /bin/bash root@564b3f3e55a4:/app# |
이번에는 정말 간단한 node 서버를 container로 실행해보았다.
다음에는 container를 실행하기 위한 옵션들은 어떤 것이 있는지 살펴보려고 한다.
'Development' 카테고리의 다른 글
[PostgreSQL] upsert(insert .. conflict on ..) 구문 사용하기 (2) | 2019.08.25 |
---|---|
node, babel7, eslint, prettier 설정하기(2019.6.9) with Webstorm (2) | 2019.06.09 |
Docker 실습하기 02편 - hello docker 출력하기 (0) | 2019.04.27 |
Docker 실습하기 01편 (0) | 2019.04.25 |
LG 올데이그램에 Linux Mint 설치하기 - Part 2 (0) | 2018.10.10 |
- Total
- Today
- Yesterday
- 개리비숍
- 한빛비즈
- 책리뷰
- 송희구
- 재테크
- docker
- PostgreSQL
- 서삼독
- ebs다큐프라임
- 가나출판사
- 유발하라리
- 투자
- graphql
- 퇴근길인문학수업
- sethgodin
- 오건영
- 알에이치코리아
- 백상경제연구원
- 경제
- 사경인
- 강형욱
- 더숲
- 토니로빈스
- 블랙피쉬
- aws 자격증
- graphql-java
- 독서
- 자기개발
- 메이트북스
- 인류3부작
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |