Profile picture

[๋ฐฐํฌ ๊ฐ€์ด๋“œ] Containerize my apps - ๋‚ด๊ฐ€ ๋งŒ๋“  ์•ฑ(์„œ๋น„์Šค) ์ปจํ…Œ์ด๋„ˆํ™” ํ•˜๊ธฐ

JaehyoJJAng2023๋…„ 11์›” 23์ผ

Container toplogy

image


๐Ÿ“Œ ์‚ฌ์ „ ์ค€๋น„

๋จผ์ € express ์•ฑ์˜ ๊ฒฝ์šฐ redis ์—ฐ๋™์ด ํ•„์š”ํ•˜๋‹ˆ express ์•ฑ์„ ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ธฐ๋™ํ•˜๊ธฐ ์ „์— redis ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋จผ์ € ์ƒ์„ฑ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ๊ฐ„์€ ๊ฒฉ๋ฆฌ๋œ ๋„คํŠธ์›Œํฌ์—์„œ ๋™์ž‘ํ•˜๋‹ˆ ๋ ˆ๋””์Šค ์ปจํ…Œ์ด๋„ˆ์™€ express ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฐ™์€ ๋„คํŠธ์›Œํฌ์— ๋ฌถ์–ด์ค˜์•ผ ํ•œ๋‹ค.


"express-net" ์ด๋ผ๋Š” ๋„์ปค ๋„คํŠธ์›Œํฌ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์ž.

$ docker network create express-net

์ด์ œ ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ์‹œ --network ์˜ต์…˜์„ ์ค˜์„œ ๋‘ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฐ™์€ ๋„คํŠธ์›Œํฌ์— ๋ฌถ์–ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋์ด๋‹ค.


express ์ปจํ…Œ์ด๋„ˆ์˜ ๊ฒฝ์šฐ ์•„๋ž˜ ๋‹จ๊ณ„๋“ค์„ ๋”ฐ๋ผํ•˜๋ฉฐ ์ฒœ์ฒœํžˆ ์ง„ํ–‰ํ•ด๋ณด๋„๋ก ํ•˜๊ณ , ๋จผ์ € redis ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค.

$ docker run -d -it --name redis --network=express-net redis:latest

์ •์ƒ์ ์œผ๋กœ ๋ ˆ๋””์Šค ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๋‹ค๋ฉด ์ด์ œ ์•„๋ž˜ ๋ฐฐํฌ ๋‹จ๊ณ„๋“ค์„ ๋”ฐ๋ผํ•ด๋ณด๋„๋ก ํ•˜์ž.


๐Ÿ’ฟ ๋ฐฐํฌ

ํ”„๋กœ์ ํŠธ ํด๋” ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

$ tree -L 2 .
.
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ app
โ”‚   โ”œโ”€โ”€ app.ts
โ”‚   โ”œโ”€โ”€ index.test.ts
โ”‚   โ””โ”€โ”€ index.ts
โ”œโ”€โ”€ dockerignore
โ”œโ”€โ”€ github_team_workflows
โ”‚   โ”œโ”€โ”€ deploy.yaml
โ”‚   โ””โ”€โ”€ test.yaml
โ”œโ”€โ”€ jest.config.js
โ”œโ”€โ”€ package-lock.json
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ scripts
โ”‚   โ”œโ”€โ”€ kill-app.sh
โ”‚   โ””โ”€โ”€ start-app.sh
โ””โ”€โ”€ tsconfig.json

Dockerfile ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋ถ€ํ„ฐ ์บ์‹œ ํ™œ์šฉ, ๋ฉ€ํ‹ฐ ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ ๋“ฑ์„ ์ ์šฉํ•˜๋ฉด์„œ Dockerfile์„ ๋‹จ๊ณ„ ๋ณ„๋กœ ๊ฐœ์„ ํ•ด ๋‚˜๊ฐˆ ๊ฒƒ์ด๋‹ค.

์•„๋ž˜ ๋‚ด์šฉ๋“ค์„ ์ฒœ์ฒœํžˆ ๋”ฐ๋ผํ•ด๋„๋ก ํ•˜์ž.


โ€ข App ์ด๋ฏธ์ง€ ์ƒ์„ฑ

์ด์ „์— ๋งŒ๋“  [Deploy] ๊ฐ€์ƒ์„œ๋ฒ„(Virtual Machine)์— node API ๋ฐฐํฌํ•˜๊ธฐ - AWS Lightsail express ์•ฑ์„ ๋„์ปค ์ด๋ฏธ์ง€๋กœ ๋งŒ๋“ค์–ด ๋ณผ ๊ฒƒ์ด๋‹ค.


base ์ด๋ฏธ์ง€์˜ ๊ฒฝ์šฐ node.js ์—์„œ ๊ณต์‹์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋…ธ๋“œ๊ธฐ๋ฐ˜ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ• ๊ฑฐ๋‹ค.
(node:latest - Dockerhub)


ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ๊ฒฝ๋กœ์— Dockerfile์„ ์ƒ์„ฑํ•œ ํ›„ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜๋„๋ก ํ•˜์ž.

FROM node:18

COPY ./ ./

RUN npm install -D
RUN npm run build

CMD [ "npm", "run", "start"]

์ด์ œ ์œ„ Dockerfile์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•ด๋ณด์ž.

$ docker build --tag yshrim12/express -f Dockerfile .

์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€๋ฅผ ํ™•์ธํ•ด๋ณด์ž.

$ docker images yshrim12/express
REPOSITORY         TAG       IMAGE ID       CREATED              SIZE
yshrim12/express   latest    52c6374c7939   About a minute ago   1.18GB

์ข…์†์„ฑ ์„ค์น˜ ๋ฐ ๋นŒ๋“œ ๊ณผ์ •์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด ์šฉ๋Ÿ‰(1.18GB)์ด ์ƒ๋‹นํžˆ ํฌ๊ฒŒ ๋‚˜์˜จ๋‹ค.
์•„๋ž˜ ๋‹จ๊ณ„๋ฅผ ์ง€๋‚˜๋‹ค๋ณด๋ฉด ์šฉ๋Ÿ‰ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๋‚˜์˜ค๋‹ˆ ๊ณ„์† ๋”ฐ๋ผํ•ด๋ณด์ž.


express ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•ด๋ณด์ž!

$ docker run -d -it --name express -p 4000:4000 --network=express-net yshrim12/express

express ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ์™€ ๋กœ๊ทธ๋ฅผ ์กฐํšŒํ•ด๋ณด์ž.

$ docker ps
CONTAINER ID   IMAGE              COMMAND                   CREATED          STATUS          PORTS                                       NAMES
a9573eaad2d4   yshrim12/express   "docker-entrypoint.sโ€ฆ"   41 seconds ago   Up 40 seconds   0.0.0.0:4000->4000/tcp, :::4000->4000/tcp   express

$ docker logs express
> express@1.0.0 start
> node build/index.js

trying to start server
App listening at port 4000

์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋จ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.


โ€ข .env ๋ถ„๋ฆฌ

์œ„์—์„œ ์ž‘์„ฑํ•œ Dockerfile์—๋Š” ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ํ•˜๋‚˜ ์žˆ๋‹ค.

๋ฐ”๋กœ Dockerfile์˜ COPY ./ ./ ์ด ๋ถ€๋ถ„์ธ๋ฐ, .env ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํฌํ•จํ•œ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ๊ฒฝ๋กœ์— ์žˆ๋Š” ๋ชจ๋“  ํŒŒ์ผ์ด express ์ปจํ…Œ์ด๋„ˆ๋กœ ์˜ฎ๊ฒจ์ง„๋‹ค๋Š” ์ ์ด๋‹ค.

๋งŒ์•ฝ .env ํŒŒ์ผ์ด ํฌํ•จ๋œ ์ด๋ฏธ์ง€๋ฅผ Docker hub๋‚˜ ๋‹ค๋ฅธ regisry ์ €์žฅ์†Œ์— ํผ๋ธ”๋ฆญ์œผ๋กœ ๋ฐฐํฌ๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด ๋ณด์•ˆ์— ๋ฏผ๊ฐํ•œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋‚ด์šฉ๋“ค์ด ๋ชจ๋‘ ๋…ธ์ถœ๋˜๋Š” ๊ฒƒ์ด๋‹ค.


์ด๋Ÿฌํ•œ ์ ์„ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ๋ฐ”๋กœ .dockerignore ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. git์—๋Š” `.gitignore`๊ฐ€ ์žˆ๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋„์ปค์—๋„ `.dockerignore`๊ฐ€ ์กด์žฌํ•œ๋‹ค.

ํ˜„์žฌ .gitignore์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋””๋ ‰ํ† ๋ฆฌ ๋ฐ ํŒŒ์ผ๋“ค์ด ํฌํ•จ๋˜์–ด์žˆ๋‹ค.

$ cat .gitignore
.env
node_modules/
build/
.DS_STORE/
app_log/

.dockerignore์—๋„ ์ปจํ…Œ์ด๋„ˆ์— ํฌํ•จ๋˜์ง€ ์•Š์„ ํŒŒ์ผ ๋ฐ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

$ cat .dockerignore
.git/
.gitignore
Dockerfile
.env.sample
.env
.github/
github_team_workflows/

์ด์ œ .dockerignore๋ฅผ ์ถ”๊ฐ€ํ–ˆ์œผ๋‹ˆ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์‹œ ๋นŒ๋“œํ•œ ํ›„ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž!

$ docker build --tag yshrim12/express .
$ docker run -d -it --name express -p 4000:4000 --network=express-net yshrim12/express

๊ทธ๋Ÿฐ๋ฐ express ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ œ๋Œ€๋กœ ์‹คํ–‰๋˜์ง€๊ฐ€ ์•Š๋Š”๋‹ค!

$ docker logs express
> express@1.0.0 start
> node build/index.js

/build/index.js:44
    throw new Error("PORT is required");
    ^

Error: PORT is required
    at Object.<anonymous> (/build/index.js:44:11)
    at Module._compile (node:internal/modules/cjs/loader:1356:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1414:10)
    at Module.load (node:internal/modules/cjs/loader:1197:32)
    at Module._load (node:internal/modules/cjs/loader:1013:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12)
    at node:internal/main/run_main_module:28:49

Node.js v18.19.0

PORT ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ๋นˆ ๊ฐ’์œผ๋กœ ๋„˜์–ด๊ฐ„ ๊ฒƒ ๊ฐ™๋‹ค. ์ด์œ ๊ฐ€ ๋ญ˜๊นŒ?


๐Ÿ”บ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

์–ด์ฐŒ๋ณด๋ฉด ๋‹น์—ฐํ•œ ์• ๊ธฐ์ด๋‹ค. .dockerignore์— ๋“ฑ๋ก๋œ ํŒŒ์ผ ๋ฐ ํด๋”๋Š” ์ปจํ…Œ์ด๋„ˆ ๋นŒ๋“œ ๊ณผ์ •์— ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ ๋ง์ธ ์ฆ‰์Šจ, .env ํŒŒ์ผ ๋˜ํ•œ ์ปจํ…Œ์ด๋„ˆ์— ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ! ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ์—์„œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ฝ์–ด๋“ค์ผ ์ˆ˜ ์—†๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค.

๋„์ปค์—๋Š” --env-file ์ด๋ผ๋Š” ์˜ต์…˜์ด ์กด์žฌํ•œ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ์„ --env-file๋กœ ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๊ฒŒ๋˜๋Š” ๊ฑฐ๋‹ค.

--env-file๋กœ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ๋“ฑ๋กํ•  ๊ฒฝ์šฐ ์ปจํ…Œ์ด๋„ˆ์—๋Š” ํ•ด๋‹น ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๊ฐ€์ง€๊ณ  ์ปจํ…Œ์ด๋„ˆ์— ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ๋“ฑ๋ก๋˜๊ฒŒ ๋œ๋‹ค.


๋จผ์ €, ๊ธฐ์กด ์˜ค๋ฅ˜๊ฐ€ ๋‚œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์—†์• ๋ฒ„๋ฆฌ์ž.

$ docker rm express

๊ทธ๋Ÿฐ ๋‹ค์Œ์— ๋‹ค์‹œ --env-file ์˜ต์…˜์„ ์ ์šฉํ•˜์—ฌ ๋‹ค์‹œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž.

$ docker run -d -it --name express --env-file=.env --network=express-net -p 4000:4000 yshrim12/express

express ์ปจํ…Œ์ด๋„ˆ ๋กœ๊ทธ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด๋ณด์ž.

$ docker logs express
> express@1.0.0 start
> node build/index.js

trying to start server
App listening at port 4000

์ด์ œ๋Š” ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค!


โ€ข ๋„์ปค ์บ์‹œ ํ™œ์šฉ

๋นŒ๋“œ ๊ณผ์ •์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ ๋งค์šฐ ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

๋„์ปค๋Š” ์ด๋ฏธ์ง€ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค์—์„œ ์บ์‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๋†’์ด๊ณ  ๋นŒ๋“œ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค. ์บ์‹ฑ์€ ์ด์ „ ๋นŒ๋“œ์—์„œ ์ƒ์„ฑ๋œ ์‚ฐ์ถœ๋ฌผ์„ ์žฌ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ค‘๋ณต ์ž‘์—…์„ ํ”ผํ•˜๊ณ , ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†๋Š” ๋ถ€๋ถ„์€ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๋„๋ก ๋„์™€์ค€๋‹ค.

์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์„ ์ œ๊ณตํ•œ๋‹ค.

  • ๋น ๋ฅธ ๋นŒ๋“œ ์†๋„: ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์ค‘์— ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๋ถ€๋ถ„์€ ์ด์ „์— ์บ์‹œ๋œ ๋ ˆ์ด์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๋นŒ๋“œํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ „๋ฐ˜์ ์œผ๋กœ ๋นŒ๋“œ ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ๋‹จ์ถ•์‹œ์ผœ์ค๋‹ˆ๋‹ค.
  • ํšจ์œจ์ ์ธ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ: ์ด๋ฏธ์ง€ ๋นŒ๋“œ ๊ณผ์ •์—์„œ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๋ถ€๋ถ„์€ ์žฌ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ๋ถˆํ•„์š”ํ•œ ์ž์› ์†Œ๋น„๋ฅผ ์ค„์—ฌ์ค๋‹ˆ๋‹ค.
  • ์ผ๊ด€์„ฑ ์žˆ๋Š” ํ™˜๊ฒฝ: ์บ์‹ฑ์„ ํ†ตํ•ด ๋™์ผํ•œ Dockerfile์„ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๊ด€๋œ ํ™˜๊ฒฝ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ์ƒˆ๋กœ ๋นŒ๋“œ๋˜๊ณ , ๋‚˜๋จธ์ง€๋Š” ์ด์ „์˜ ๋ ˆ์ด์–ด๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ๋” ์ž‘์€ ์ด๋ฏธ์ง€ ํฌ๊ธฐ: ์ด์ „ ๋ ˆ์ด์–ด๊ฐ€ ์žฌ์‚ฌ์šฉ๋˜๋ฉด์„œ ์ค‘๋ณต์ด ์ค„์–ด๋“ค๊ณ , ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๊ฐ€ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ Dockerfile์—์„œ ๊ฐ ๋ช…๋ น์€ ๊ฐ๊ฐ์˜ ๋ ˆ์ด์–ด๋กœ ์ƒ์„ฑ๋œ๋‹ค. ์ด ๋•Œ๋ฌธ์— Docker๋Š” ๊ฐ ๋‹จ๊ณ„๋ฅผ ์บ์‹œํ•˜๊ณ , ์ด์ „์— ๋นŒ๋“œ๋œ ์บ์‹œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ๋‹ค์‹œ ๋นŒ๋“œํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์บ์‹œ๋Š” ์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ, ๋•Œ๋กœ๋Š” ์บ์‹œ๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋‹ค์‹œ ๋นŒ๋“œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.
(์˜ˆ: ์ข…์†์„ฑ์ด๋‚˜ ์†Œ์Šค ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋“ฑ)


์ข‹์€ Dockerfile์„ ์ž‘์„ฑํ•˜์—ฌ ์บ์‹œ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๋ฉด ๋” ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ์ด๋ฏธ์ง€ ๋นŒ๋“œ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์šฐ๋ฆฌ๋„ ์บ์‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด Dockerfile์„ ๊ฐœ์„ ์‹œ์ผœ๋ณด์ž.

FROM node:18-alpine

COPY ./package*.json ./
RUN npm install -D

COPY ./ ./
RUN npm run build

CMD [ "npm", "run", "start" ]

์œ„ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์‹œ ๋นŒ๋“œํ•ด๋ณด์ž.

$ docker build --tag yshrim12/express -f Dockerfile .
[+] Building 37.8s (10/10) FINISHED                                                       docker:default
 => [internal] load .dockerignore                                                                   0.0s
 => => transferring context: 117B                                                                   0.0s
 => [internal] load build definition from Dockerfile                                                0.0s
 => => transferring dockerfile: 162B                                                                0.0s
 => [internal] load metadata for docker.io/library/node:18-alpine                                   1.5s
 => CACHED [1/5] FROM docker.io/library/node:18-alpine@sha256:4bdb3f3105718f0742bc8d64bb4e36e8f955  0.0s
 => [internal] load build context                                                                   0.0s
 => => transferring context: 481B                                                                   0.0s
 => [2/5] COPY ./package*.json ./                                                                   0.0s
 => [3/5] RUN npm install -D                                                                       30.6s
 => [4/5] COPY ./ ./                                                                                0.0s
 => [5/5] RUN npm run build                                                                         4.4s
 => exporting to image                                                                              1.3s
 => => exporting layers                                                                             1.3s
 => => writing image sha256:9ec2f8e209a06aa85fba42bb92d502037384c40158c116b1dd51985a488c71bb        0.0s
 => => naming to docker.io/yshrim12/express

์ตœ์ดˆ ๋นŒ๋“œ์‹œ 37.8s๊ฐ€ ๊ฑธ๋ฆฐ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


app/app.ts์˜ ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ผ๋ถ€๋ถ„์„ ๋ณ€๊ฒฝํ•ด๋ณด์ž.

... 
app.get("/", (request, response) => {
    response.status(200).send("hello from express, new image");

๋‹ค์‹œ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•ด๋ณด์ž!

$ docker build --tag yshrim12/express -f Dockerfile .
[+] Building 5.2s (10/10) FINISHED                                                        docker:default
 => [internal] load .dockerignore                                                                   0.0s
 => => transferring context: 117B                                                                   0.0s
 => [internal] load build definition from Dockerfile                                                0.0s
 => => transferring dockerfile: 162B                                                                0.0s
 => [internal] load metadata for docker.io/library/node:18-alpine                                   0.7s
 => [1/5] FROM docker.io/library/node:18-alpine@sha256:4bdb3f3105718f0742bc8d64bb4e36e8f955ebbee29  0.0s
 => [internal] load build context                                                                   0.0s
 => => transferring context: 1.17kB                                                                 0.0s
 => CACHED [2/5] COPY ./package*.json ./                                                            0.0s
 => CACHED [3/5] RUN npm install -D                                                                 0.0s
 => [4/5] COPY ./ ./                                                                                0.0s
 => [5/5] RUN npm run build                                                                         4.4s
 => exporting to image                                                                              0.0s
 => => exporting layers                                                                             0.0s
 => => writing image sha256:f17d4f25c30b976c803ba5942e9b0731d3876764a899510b0a1fd7ee1b44fdbd        0.0s
 => => naming to docker.io/yshrim12/express

์บ์‹ฑ ๋•๋ถ„์— 5.2์ดˆ ๋ฐ–์— ๊ฑธ๋ฆฌ์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค!


โ€ข Multi stage build

Dockerfile์˜ ๊ฒฝ์šฐ build์™€ production ์Šคํ…Œ์ด์ง€๋ฅผ ๊ฐ๊ฐ ๋ถ„๋ฆฌํ•˜์—ฌ ๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ๊ฒฝ๋Ÿ‰ํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

์ด์ „ ์ด๋ฏธ์ง€์˜ ๊ฒฝ์šฐ ์˜์กด์„ฑ์œผ๋กœ ์ถ”๊ฐ€๋œ ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜ํ•˜๊ณ , ๋นŒ๋“œ๊ณผ์ •๊นŒ์ง€ ํฌํ•จ๋˜๋‹ค ๋ณด๋‹ˆ ์ƒ๋‹นํžˆ ํฐ ์šฉ๋Ÿ‰์œผ๋กœ ํƒ„์ƒํ•˜๊ฒŒ ๋œ๋‹ค.

๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ ์ด๋ฏธ์ง€์ฒ˜๋Ÿผ ๋นŒ๋“œ์™€ ์‹คํ–‰ ๊ณผ์ •์„ ๋ชจ๋‘ ๋‹ด์•„๋„ ์ƒ๊ด€์€ ์—†์ง€๋งŒ ๋นŒ๋“œ์™€ ์‹คํ–‰์„ ๋‚˜๋ˆ„๋Š” Builder pattern๋„ ์กด์žฌํ•œ๋‹ค.

Builder image์—์„œ๋Š” ์•ฑ ๋นŒ๋“œ์— ํ•„์š”ํ•œ ์˜์กด์„ฑ ์„ค์น˜์™€, ๋นŒ๋“œ ํ›„ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ 
์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” Running image์—์„œ๋Š” Builder image๋กœ๋ถ€ํ„ฐ ๋ฐ”์ด๋„ˆ๋ฆฌ๋งŒ ๋ฐ›์•„์„œ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฉด ๊ฒฐ๊ตญ Build์—๋งŒ ํ•„์š”ํ•œ ๋ถˆํ•„์š”ํ•œ ๋„๊ตฌ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ์ด๋ฏธ์ง€ ๋‚ด ํŒŒ์ผ๋“ค์„ ์ œ์™ธํ•˜๊ณ  ์•„์ฃผ ์ปดํŒฉํŠธํ•œ ์ด๋ฏธ์ง€์—์„œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋งŒ ๊ฐ€์ง€๊ณ  ์•ฑ์„ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ฒŒ๋œ๋‹ค.


์‚ฌ์šฉ๋ฒ•์€ ์•„์ฃผ ๋‹จ์ˆœํ•˜๋‹ค. ํ•œ ํŒŒ์ผ์—์„œ Base ์ด๋ฏธ์ง€๋ฅผ ๋ฐ”๊ฟ” ์‚ฌ์šฉํ•˜๋ฉด ๋งˆ์น˜ 2๊ฐœ ์ด์ƒ์˜ Dockerfile์ด ์žˆ๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋นŒ๋“œ ์ˆ˜ํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค. Builder์—์„œ ๋นŒ๋“œํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ด๋ฏธ์ง€๋กœ ์ „๋‹ฌํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ COPY์˜ --from ์˜ต์…˜์„ ํ†ตํ•ด ์‹คํ–‰ ์ด๋ฏธ์ง€๋กœ ์ „๋‹ฌํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.


๊ธฐ์กด Dockerfile์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์ž. ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€๋„ ๊ธฐ์กด node:18 ์ด๋ฏธ์ง€๊ฐ€ ์•„๋‹Œ ๊ฒฝ๋ นํ™” ์ด๋ฏธ์ง€์ธ node:18-alpine ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

# Build Stage
FROM node:18-alpine AS builder
COPY ./package*.json ./
RUN npm install -D
COPY ./ ./
RUN npm run build

# Production Stage
FROM node:18-alpine AS prod
COPY --from=builder ./build ./build
COPY --from=builder ./package*.json ./
RUN npm install --only=production
CMD [ "npm", "run", "start" ]

์œ„ Dockerfile์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•ด๋ณด์ž.

$ docker build --tag yshrim12/express-light -f Dockerfile .

์ƒˆ ์ด๋ฏธ์ง€(yshrim12/express-light)๋ฅผ ํ™•์ธํ•ด๋ณด์ž.

$ docker images yshrim12/express-light
REPOSITORY               TAG       IMAGE ID       CREATED         SIZE
yshrim12/express-light   latest    72b5b7354731   2 minutes ago   176MB

์šฉ๋Ÿ‰์ด ๋งค์šฐ ๊ฒฝ๋Ÿ‰ํ™” ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค!


์ƒˆ ์ด๋ฏธ์ง€๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž.

$ docker run -d -it --name express -p 4000:4000 --env-file=.env --network=express-net yshrim12/express-light

express ์•ฑ์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€ ์ปจํ…Œ์ด๋„ˆ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ด๋ณด์ž.

$ docker logs express

> express@1.0.0 start
> node build/index.js

trying to start server
App listening at port 4000

โ€ข WORKDIR ์ ์šฉ

ํ˜„์žฌ ์ƒ์„ฑ๋œ express ์ปจํ…Œ์ด๋„ˆ์— ์ ‘๊ทผํ•˜์—ฌ ls -lh / ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž.

$ docker exec express ls -lh /
total 264K
drwxr-xr-x    1 root     root        4.0K Dec  2 01:26 bin
drwxr-xr-x    2 root     root        4.0K Dec  3 08:20 build
drwxr-xr-x    5 root     root         360 Dec  3 08:29 dev
drwxr-xr-x    1 root     root        4.0K Dec  3 08:29 etc
drwxr-xr-x    1 root     root        4.0K Dec  2 01:26 home
drwxr-xr-x    1 root     root        4.0K Dec  2 01:26 lib
drwxr-xr-x    5 root     root        4.0K Nov 30 09:32 media
drwxr-xr-x    2 root     root        4.0K Nov 30 09:32 mnt
drwxr-xr-x   75 root     root       12.0K Dec  3 08:28 node_modules
drwxr-xr-x    1 root     root        4.0K Dec  2 01:26 opt
-rw-rw-r--    1 root     root      181.6K Dec  3 08:28 package-lock.json
-rw-rw-r--    1 root     root         784 Dec  1 11:17 package.json
dr-xr-xr-x  326 root     root           0 Dec  3 08:29 proc
drwx------    1 root     root        4.0K Dec  3 08:34 root
drwxr-xr-x    2 root     root        4.0K Nov 30 09:32 run
drwxr-xr-x    2 root     root        4.0K Nov 30 09:32 sbin
drwxr-xr-x    2 root     root        4.0K Nov 30 09:32 srv
dr-xr-xr-x   13 root     root           0 Dec  3 08:29 sys
drwxrwxrwt    1 root     root        4.0K Dec  2 01:26 tmp
drwxr-xr-x    1 root     root        4.0K Dec  2 01:26 usr
drwxr-xr-x   12 root     root        4.0K Nov 30 09:32 var

/ ๊ฒฝ๋กœ์— node_modules ๋“ฑ ํŒจํ‚ค์ง€ ๋ชจ๋“ˆ ๋ฐ build ํด๋” ๋“ฑ์ด ๋„๋ถ€๋Ÿฌ์ ธ ์žˆ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜๊ฐ€ ์žˆ๋‹ค.


์ €๋ ‡๊ฒŒ ํ•ด๋†“์œผ๋ฉด ๊ฐ€๋…์„ฑ์ด ์•ˆ์ข‹๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํ•˜๊ธฐ ํž˜๋“ค๋ฟ๋”๋Ÿฌ ๋ณผ๋ฅจ ์žก๊ธฐ๋„ ์ƒ๋‹นํžˆ ๋ฒˆ๊ฑฐ๋กœ์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค.
์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ Dockerfile์—์„œ๋Š” WORKDIR ์ด๋ผ๋Š” ์˜ต์…˜์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.


WORKDIR์€ Dockerfile์—์„œ ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ์ด ๋ช…๋ น์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ์œ ์šฉํ•˜๋‹ค.

  • ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ ์„ค์ •: WORKDIR ๋ช…๋ น์€ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋  ๋ช…๋ น์ด๋‚˜ ํŒŒ์ผ ์ž‘์—…์„ ์œ„ํ•œ ๊ธฐ๋ณธ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•  ํ•„์š” ์—†์ด ์ƒ๋Œ€ ๊ฒฝ๋กœ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ๊ฐ€๋…์„ฑ ๋ฐ ์œ ์ง€๋ณด์ˆ˜: Dockerfile์„ ์ž‘์„ฑํ•  ๋•Œ WORKDIR๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ช…๋ น์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์—ฌ์ค๋‹ˆ๋‹ค. ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์„ค์ •ํ•˜๋ฉด ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์—์„œ์˜ ๋ชจ๋“  ์ž‘์—…์ด ๋ช…ํ™•ํ•ด์ง€๋ฏ€๋กœ, Dockerfile์„ ์ดํ•ดํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.
  • ๊ฒฝ๋กœ ์ถฉ๋Œ ๋ฐฉ์ง€: ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ ๊ฒฝ๋กœ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด WORKDIR๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์„ค์ •ํ•จ์œผ๋กœ์จ ๋‹ค๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ์™€์˜ ํ˜ผ๋ž€์„ ์ค„์ด๊ณ  ๋ช…์‹œ์ ์ธ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

WORKDIR์„ ๊ธฐ์กด Dockerfile์— ์ ์šฉํ•ด๋ณด์ž!

# Build Stage
FROM node:18-alpine AS builder
WORKDIR /builder
COPY ./package*.json ./
RUN npm install -D
COPY ./ ./
RUN npm run build

# Production Stage
FROM node:18-alpine AS prod
WORKDIR /prod
COPY --from=builder /builder/build ./build
COPY --from=builder ./builder/package*.json ./
RUN npm install --only=production
CMD [ "npm", "run", "start" ]

์ด๋ฏธ์ง€๋ฅผ ์žฌ๋นŒ๋“œ ํ•˜๋„๋ก ํ•˜์ž.

$ docker build --tag yshrim12/express-light .

์žฌ๋นŒ๋“œ๋œ ์ด๋ฏธ์ง€๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•ด๋ณด์ž.

$ docker run -d -it --name express -p 4000:4000 --env-file=.env --network=express-net yshrim12/express-light

express ์ปจํ…Œ์ด๋„ˆ์— pwd ๋ช…๋ น์„ ๋‚ ๋ ค๋ณด์ž.

$ docker exec express pwd
/prod

ํ˜„์žฌ ๊ฒฝ๋กœ๊ฐ€ /prod์— ์žˆ๋‹ค๊ณ  ๋‚˜์˜จ๋‹ค.
์ด๋Š” Dockerfile์—์„œ prod stage์˜ WORKDIR์ด /prod๋กœ ์„ค์ •ํ•ด๋†จ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


โ€ข Docker volume ์ ์šฉ

์†Œ์Šค์ฝ”๋“œ ์‹ค์‹œ๊ฐ„ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด Docker Volume์„ ์ ์šฉํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.


๋จผ์ € ๊ฐœ๋ฐœ์šฉ Dockerfile์„ ๋งŒ๋“ค์–ด์ฃผ์ž.
(./Dockerfile.dev)

FROM node:18-alpine

WORKDIR /my-app
RUN npm install -g nodemon

COPY ./package*.json ./
RUN npm install -D

COPY ./ ./
RUN npm run build

CMD ["npm", "run", "dev"]

ํ•ด๋‹น Dockerfile์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜์ž.

$ docker build --tag yshrim12/express-dev -f Dockerfile.dev .

volume ์˜ต์…˜์„ ์ ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

$ docker run -d -it --name express-dev -p 4000:4000 \
--env-file=.env --network=express-net \
-v "$(pwd)/app:/my-app/app" \
yshrim12/express-dev

์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ž˜ ์‹คํ–‰๋๋Š”์ง€ ๋กœ๊ทธ๋ฅผ ์‚ดํŽด๋ณด์ž.

$ docker logs express-dev
9:14:41 AM - File change detected. Starting incremental compilation...
[0]
[1] [nodemon] restarting due to changes...
[0]
[0] 9:14:42 AM - Found 0 errors. Watching for file changes.
[1] [nodemon] restarting due to changes...
[1] [nodemon] starting `node build/index.js`
[1] trying to start server
[1] App listening at port 4000

์ด์ œ ๋กœ์ปฌ์—์„œ ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ๊ฐ€ ์ปจํ…Œ์ด๋„ˆ์—์„œ๋„ nodemon์„ ํ†ตํ•ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฐ์ง€๋˜๊ณ  ๋ณ€๊ฒฝ๋˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.

๋จผ์ € ๋กœ์ปฌ์—์„œ app/app.ts ์†Œ์Šค์ฝ”๋“œ ์ผ๋ถ€๋ถ„์„ ์•„๋ž˜์ฒ˜๋Ÿผ ๋ณ€๊ฒฝํ•˜์ž.

...
app.get("/", (request, response) => {
    response.status(200).send("hello from express, Added volume options!");

์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ–ˆ์œผ๋ฉด curl localhost:4000 ๋ช…๋ น์„ ๋‚ ๋ ค ๋ณ€๊ฒฝ๋œ ๊ฐ’์œผ๋กœ ์ถœ๋ ฅ๋˜๋Š”์ง€ ํ™•์ธํ•˜์ž.

$ curl localhost:4000
hello from express, Added volume options!

๐Ÿ’ฅ Docker-Compose๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฐœ๋ฐœํ•˜๊ธฐ

๋งค๋ฒˆ docker run์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋„์šด๋‹ค๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๊ท€์ฐฎ๊ณ  ๋ฒˆ๊ฑฐ๋กœ์šด๊ฐ€?

์ด๋Ÿฐ ์„ค์ •๋“ค์„ Docker Compose๋กœ ์ €์žฅํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‹คํ–‰ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค!

๐Ÿ’ก Docker Compose ๋ฅผ ์ž˜ ์ž‘์„ฑํ•˜๋ ค๋ฉด YAML ๋ฌธ๋ฒ•์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ด€๋ จ ๋‚ด์šฉ์€ ์•„๋ž˜ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•˜์ž.
YAML ์ดํ•ดํ•˜๊ธฐ - WTT Devlog

Docker Compose ๊ด€๋ จ ๋ฌธ๋ฒ•์ด๋‚˜ ๋‚ด์šฉ๋“ค์€ ์•„๋ž˜ ํฌ์ŠคํŒ…๋“ค์„ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•˜์ž.
Docker-Compose - WTT Devlog


ํ˜„์žฌ ํ”„๋กœ์ ํŠธ ๊ฒฝ๋กœ์— docker-compose.yaml ๋ž€ ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์•„๋ž˜ ์„ค์ •๋“ค์„ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜์ž.

version: "3.2"

services:
  express:
    depends_on:
      - "redis"
    build:
      context: .
      dockerfile: Dockerfile.dev
    restart: always
    volumes:
      - type: bind
        source: "./app"
        target: "/my-app/app"
    ports:
      - "4000:4000"
    env_file:
      - ".env"
    environment:
      REDIS_URL: "redis://redis:6379"
      PORT: 4000
    networks:
      - "express-net"
    container_name: express-dev

  redis:
    image: redis:alpine
    restart: always
    volumes:
      - type: volume
        source: "data"
        target: "/data"
    networks:
      - "express-net"
    container_name: redis

volumes:
  data: {}

networks:
  express-net:
    driver: bridge
    external: false

docker-compose.yaml ํŒŒ์ผ ์ž‘์„ฑ์ด ๋ชจ๋‘ ๋๋‚ฌ๋‹ค๋ฉด ์ด์ œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ฐฐํฌํ•ด๋ณด์ž!

$ docker-compose up -d --build

์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋๋Š”์ง€ ํ™•์ธํ•˜์ž.

$ docker-compose ps
NAME          IMAGE             COMMAND                   SERVICE   CREATED              STATUS              PORTS
express-dev   express-express   "docker-entrypoint.sโ€ฆ"   express   About a minute ago   Up About a minute   0.0.0.0:4000->4000/tcp, :::4000->4000/tcp
redis         redis:alpine      "docker-entrypoint.sโ€ฆ"   redis     About a minute ago   Up About a minute   6379/tcp

๋งˆ๋ฌด๋ฆฌ

์ด๋ ‡๊ฒŒ ์ „ํ†ต์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๊ฐ€์ƒ์„œ๋ฒ„์— ๋ฐฐํฌํ•˜๋Š” ๋ฒ•๋ถ€ํ„ฐ ๋„์ปค๋กœ ๋ฐฐํฌํ•˜๋Š” ๋ฒ• ๊นŒ์ง€ ์‚ดํŽด๋ณด์•˜๋‹ค.

์ด์ œ ์ฐจํ›„์— ์ž‘์„ฑ๋  ํฌ์ŠคํŒ…์—์„œ๋Š” AWS ๋ณด์•ˆ ๊ด€๋ จ ๋ฐ ECS, AWS Image Registry , Docker-Compose๋กœ CI, AWS OpenID Connect ๋“ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ™œ์šฉํ•œ ์™„๋ฒฝํ•œ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•ด๋ณผ ๊ฒƒ์ด๋‹ค!


Loading script...

ยฉ 2025, Built with Gatsby