Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

๋ณต์žกํ•œ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ์™€ CI/CD๊ฐ€ ์กด์žฌํ•˜๋Š” ์š”์ฆ˜์—๋Š” ๊ธฐ๋Šฅ์ด ํ”„๋กœ๋•์…˜์— ๋„์ž…๋˜๊ธฐ ์ „์— ์ปค๋ฐ‹์—์„œ ํ…Œ์ŠคํŠธ ๋ฐ ์ œ๊ณต๊นŒ์ง€ ๊ฐˆ ๊ธธ์ด ๋ฉ€์Šต๋‹ˆ๋‹ค. ์ด์ „์—๋Š” FTP๋ฅผ ํ†ตํ•ด ์ƒˆ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ (์•„๋ฌด๋„ ๋” ์ด์ƒ ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์ฃ ?) "๋ฐฐํฌ" ํ”„๋กœ์„ธ์Šค์— ๋ช‡ ์ดˆ๋ฐ–์— ๊ฑธ๋ฆฌ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ณ‘ํ•ฉ ์š”์ฒญ์„ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณต๋  ๋•Œ๊นŒ์ง€ ์˜ค๋žœ ์‹œ๊ฐ„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋ฏธ๋””์–ด ์›น์‚ฌ์ดํŠธ ์ œ์ž‘ ๋ฐ ์ง€์›์— ์žˆ์–ด ์ข‹์€ ๊ฒฝํ—˜์„ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. TASS, ๋ฒจ, "์ƒˆ ์‹ ๋ฌธ", ๊ณตํ™”๊ตญโ€ฆ ์–ผ๋งˆ ์ „ ์ œํ’ˆ ์›น ์‚ฌ์ดํŠธ๋ฅผ ์ถœ์‹œํ•˜์—ฌ ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์•Œ๋ฆผ. ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ๋น ๋ฅด๊ฒŒ ์ถ”๊ฐ€๋˜๊ณ  ์˜ค๋ž˜๋œ ๋ฒ„๊ทธ๊ฐ€ ์ˆ˜์ •๋˜์—ˆ์ง€๋งŒ ๋Š๋ฆฐ ๋ฐฐํฌ๊ฐ€ ํฐ ๋ฌธ์ œ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

GitLab์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ์ง€๋ฅผ ์ˆ˜์ง‘ํ•˜์—ฌ GitLab Registry์— ํ‘ธ์‹œํ•˜๊ณ  ํ”„๋กœ๋•์…˜์— ์ถœ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชฉ๋ก์—์„œ ๊ฐ€์žฅ ๊ธด ์ผ์€ ์ด๋ฏธ์ง€๋ฅผ ์กฐ๋ฆฝํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ์ ํ™”ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฐ ๋ฐฑ์—”๋“œ ๋นŒ๋“œ์— 14๋ถ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ ์šฐ๋ฆฌ๋Š” ๋” ์ด์ƒ ์ด๋ ‡๊ฒŒ ์‚ด ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ๋ถ„๋ช…ํ•ด์กŒ๊ณ , ์šฐ๋ฆฌ๋Š” ์™œ ์ด๋ฏธ์ง€๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐ ๊ทธ๋ ‡๊ฒŒ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š”์ง€ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ์ž๋ฆฌ์— ์•‰์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ, ์กฐ๋ฆฝ ์‹œ๊ฐ„์„ 30์ดˆ๋กœ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค!

Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Reminder ํ™˜๊ฒฝ์— ์–ฝ๋งค์ด์ง€ ์•Š๊ธฐ ์œ„ํ•ด ๋นˆ Angular ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์กฐ๋ฆฝํ•˜๋Š” ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ng n app

PWA๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”(์šฐ๋ฆฌ๋Š” ์ง„๋ณด์ ์ž…๋‹ˆ๋‹ค):

ng add @angular/pwa --project app

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

FROM node:12.16.2
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

Dockerfile์€ ์ผ๋ จ์˜ ์ง€์นจ์ž…๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•จ์œผ๋กœ์จ Docker๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํŒŒ์ผ ์‹œ์Šคํ…œ์— ์ €์žฅํ•˜๊ณ  ์ด๋ฅผ ์ด์ „ ์‹œ์Šคํ…œ์— ์˜ค๋ฒ„๋ ˆ์ดํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ํŒ€์€ ์ž์ฒด ๋ ˆ์ด์–ด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์™„์„ฑ๋œ ์ด๋ฏธ์ง€๋Š” ๋ ˆ์ด์–ด๋“ค์ด ํ•ฉ์ณ์ง„ ๊ฒฐ๊ณผ๋ฌผ์ž…๋‹ˆ๋‹ค.

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

  1. ์ด์ „ ์‹คํ–‰์ด ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ์ด๋ฏธ์ง€๋ฅผ ๋กœ์ปฌ์—์„œ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
    docker rmi $(docker images -q)
  2. ์šฐ๋ฆฌ๋Š” ์ฒ˜์Œ์œผ๋กœ ๋นŒ๋“œ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
    time docker build -t app .
  3. src/index.html ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์ž‘์—…์„ ๋ชจ๋ฐฉํ•ฉ๋‹ˆ๋‹ค.
  4. ๋นŒ๋“œ๋ฅผ ๋‘ ๋ฒˆ์งธ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    time docker build -t app .

์ด๋ฏธ์ง€ ๋นŒ๋“œ ํ™˜๊ฒฝ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ์ฐธ์กฐ) ๋นŒ๋“œ๊ฐ€ ์‹œ์ž‘๋  ๋•Œ Docker์— ์ด๋ฏธ ๋งŽ์€ ์บ์‹œ๊ฐ€ ํƒ‘์žฌ๋˜์–ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ์ž„๋ฌด๋Š” ๋นŒ๋“œ๊ฐ€ ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ์ง„ํ–‰๋˜๋„๋ก ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์บ์‹œ ์—†์ด ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์ฒ˜์Œ ํ•œ ๋ฒˆ๋งŒ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฏ€๋กœ ์ฒซ ๋ฒˆ์งธ ์‹คํ–‰์ด ์–ผ๋งˆ๋‚˜ ๋Š๋ฆฐ์ง€๋Š” ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ์—์„œ๋Š” ์บ์‹œ๊ฐ€ ์ด๋ฏธ ์˜ˆ์—ด๋˜๊ณ  ์ผ€์ดํฌ๋ฅผ ๊ตฌ์šธ ์ค€๋น„๊ฐ€ ๋œ ๋‘ ๋ฒˆ์งธ ๋นŒ๋“œ ์‹คํ–‰์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ถ€ ํŒ์€ ์ฒซ ๋ฒˆ์งธ ๋นŒ๋“œ์—๋„ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

์œ„์—์„œ ์„ค๋ช…ํ•œ Dockerfile์„ ํ”„๋กœ์ ํŠธ ํด๋”์— ๋„ฃ๊ณ  ๋นŒ๋“œ๋ฅผ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฝ๊ธฐ ์‰ฝ๋„๋ก ๋ชจ๋“  ๋ชฉ๋ก์ด ์š”์•ฝ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

$ time docker build -t app .
Sending build context to Docker daemon 409MB
Step 1/5 : FROM node:12.16.2
Status: Downloaded newer image for node:12.16.2
Step 2/5 : WORKDIR /app
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:20:09.664Z - Hash: fffa0fddaa3425c55dd3 - Time: 37581ms
Successfully built c8c279335f46
Successfully tagged app:latest

real 5m4.541s
user 0m0.000s
sys 0m0.000s

src/index.html์˜ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

$ time docker build -t app .
Sending build context to Docker daemon 409MB
Step 1/5 : FROM node:12.16.2
Step 2/5 : WORKDIR /app
 ---> Using cache
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:26:26.587Z - Hash: fffa0fddaa3425c55dd3 - Time: 37902ms
Successfully built 79f335df92d3
Successfully tagged app:latest

real 3m33.262s
user 0m0.000s
sys 0m0.000s

์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์„ธ์š”. docker images:

REPOSITORY   TAG      IMAGE ID       CREATED              SIZE
app          latest   79f335df92d3   About a minute ago   1.74GB

๋นŒ๋“œํ•˜๊ธฐ ์ „์— docker๋Š” ํ˜„์žฌ ์ปจํ…์ŠคํŠธ์˜ ๋ชจ๋“  ํŒŒ์ผ์„ ๊ฐ€์ ธ์™€ ๋ฐ๋ชฌ์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. Sending build context to Docker daemon 409MB. ๋นŒ๋“œ ์ปจํ…์ŠคํŠธ๋Š” ๋นŒ๋“œ ๋ช…๋ น์˜ ๋งˆ์ง€๋ง‰ ์ธ์ˆ˜๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ ์ด๊ฒƒ์€ ํ˜„์žฌ ๋””๋ ‰ํ„ฐ๋ฆฌ์ธ "."์ด๋ฉฐ Docker๋Š” ์ด ํด๋”์— ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ๋“œ๋ž˜๊ทธํ•ฉ๋‹ˆ๋‹ค. 409MB๋Š” ๋งŽ์€ ์–‘์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งฅ๋ฝ ์ค„์ด๊ธฐ

์ปจํ…์ŠคํŠธ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•œ ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ์— ํ•„์š”ํ•œ ๋ชจ๋“  ํŒŒ์ผ์„ ๋ณ„๋„์˜ ํด๋”์— ๋„ฃ๊ณ  docker ์ปจํ…์ŠคํŠธ๊ฐ€ ์ด ํด๋”๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ•ญ์ƒ ํŽธ๋ฆฌํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์˜ˆ์™ธ๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ปจํ…์ŠคํŠธ์— ๋Œ์–ด์„œ๋Š” ์•ˆ ๋˜๋Š” ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ํ”„๋กœ์ ํŠธ์— .dockerignore ํŒŒ์ผ์„ ๋„ฃ๊ณ  ๋นŒ๋“œ์— ํ•„์š”ํ•˜์ง€ ์•Š์€ ํ•ญ๋ชฉ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

.git
/node_modules

๋นŒ๋“œ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜์„ธ์š”.

$ time docker build -t app .
Sending build context to Docker daemon 607.2kB
Step 1/5 : FROM node:12.16.2
Step 2/5 : WORKDIR /app
 ---> Using cache
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:33:54.338Z - Hash: fffa0fddaa3425c55dd3 - Time: 37313ms
Successfully built 4942f010792a
Successfully tagged app:latest

real 1m47.763s
user 0m0.000s
sys 0m0.000s

607.2KB๋Š” 409MB๋ณด๋‹ค ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ 1.74GB์—์„œ 1.38GB๋กœ ์ค„์˜€์Šต๋‹ˆ๋‹ค.

REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
app          latest   4942f010792a   3 minutes ago   1.38GB

์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ๋” ์ค„์—ฌ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์•ŒํŒŒ์ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค

์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ ˆ์•ฝํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์ž‘์€ ์ƒ์œ„ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ด๋ฏธ์ง€๋Š” ์šฐ๋ฆฌ์˜ ์ด๋ฏธ์ง€๊ฐ€ ์ค€๋น„๋˜๋Š” ๊ธฐ๋ฐ˜์ด ๋˜๋Š” ์ด๋ฏธ์ง€์ž…๋‹ˆ๋‹ค. ๋งจ ์•„๋ž˜ ๋ ˆ์ด์–ด๋Š” ๋ช…๋ น์œผ๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. FROM Dockerfile์—์„œ. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ์—๋Š” ์ด๋ฏธ nodejs๊ฐ€ ์„ค์น˜๋œ Ubuntu ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌด๊ฒŒ๋„ ๋‚˜๊ฐ€๊ณ ...

$ docker images -a | grep node
node 12.16.2 406aa3abbc6c 17 minutes ago 916MB

... ๊ฑฐ์˜ ๊ธฐ๊ฐ€๋ฐ”์ดํŠธ์ž…๋‹ˆ๋‹ค. Alpine Linux ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณผ๋ฅจ์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ŒํŒŒ์ธ(Alpine)์€ ์•„์ฃผ ์ž‘์€ ๋ฆฌ๋ˆ…์Šค์ž…๋‹ˆ๋‹ค. alpine ๊ธฐ๋ฐ˜ nodejs์šฉ docker ์ด๋ฏธ์ง€์˜ ๋ฌด๊ฒŒ๋Š” 88.5MB์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ง‘์˜ ์ƒ์ƒํ•œ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ”๊ฟ” ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

์šฐ๋ฆฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ช‡ ๊ฐ€์ง€ ํ•ญ๋ชฉ์„ ์„ค์น˜ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ, Angular๋Š” Python ์—†์ด๋Š” ๋นŒ๋“œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ฬ…(ยฐ_o)/ฬ…

๊ทธ๋Ÿฌ๋‚˜ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 150MB๋กœ ๋–จ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
app          latest   aa031edc315a   22 minutes ago   761MB

๋” ๋‚˜์•„๊ฐ€ ๋ณด์ž.

๋‹ค๋‹จ๊ณ„ ์กฐ๋ฆฝ

์ด๋ฏธ์ง€์— ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์ œ์ž‘์— ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

$ docker run app ls -lah
total 576K
drwxr-xr-x 1 root root 4.0K Apr 16 19:54 .
drwxr-xr-x 1 root root 4.0K Apr 16 20:00 ..
-rwxr-xr-x 1 root root 19 Apr 17 2020 .dockerignore
-rwxr-xr-x 1 root root 246 Apr 17 2020 .editorconfig
-rwxr-xr-x 1 root root 631 Apr 17 2020 .gitignore
-rwxr-xr-x 1 root root 181 Apr 17 2020 Dockerfile
-rwxr-xr-x 1 root root 1020 Apr 17 2020 README.md
-rwxr-xr-x 1 root root 3.6K Apr 17 2020 angular.json
-rwxr-xr-x 1 root root 429 Apr 17 2020 browserslist
drwxr-xr-x 3 root root 4.0K Apr 16 19:54 dist
drwxr-xr-x 3 root root 4.0K Apr 17 2020 e2e
-rwxr-xr-x 1 root root 1015 Apr 17 2020 karma.conf.js
-rwxr-xr-x 1 root root 620 Apr 17 2020 ngsw-config.json
drwxr-xr-x 1 root root 4.0K Apr 16 19:54 node_modules
-rwxr-xr-x 1 root root 494.9K Apr 17 2020 package-lock.json
-rwxr-xr-x 1 root root 1.3K Apr 17 2020 package.json
drwxr-xr-x 5 root root 4.0K Apr 17 2020 src
-rwxr-xr-x 1 root root 210 Apr 17 2020 tsconfig.app.json
-rwxr-xr-x 1 root root 489 Apr 17 2020 tsconfig.json
-rwxr-xr-x 1 root root 270 Apr 17 2020 tsconfig.spec.json
-rwxr-xr-x 1 root root 1.9K Apr 17 2020 tslint.json

๊ณผ docker run app ls -lah ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ถœ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. app ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์•ˆ์— ์žˆ๋Š” ๋ช…๋ น์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ls -lah, ๊ทธ ํ›„ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ž‘์—…์„ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ํด๋”๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. dist. ์ด ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ๋“  ํŒŒ์ผ์„ ์™ธ๋ถ€์— ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. nodejs์—์„œ ์ผ๋ถ€ HTTP ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋„ค ๊ธ€์ž "y"๋กœ ๊ตฌ์„ฑ๋œ ๋Ÿฌ์‹œ์•„์–ด ๋‹จ์–ด๋ฅผ ์ถ”์ธกํ•ด ๋ณด์„ธ์š”. ์˜ค๋ฅธ์ชฝ! Ynzhynyksy. nginx๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ฐ์–ด์„œ ํด๋”๋ฅผ ๋„ฃ์–ด๋ณด์ž dist ๊ทธ๋ฆฌ๊ณ  ์ž‘์€ ๊ตฌ์„ฑ:

server {
    listen 80 default_server;
    server_name localhost;
    charset utf-8;
    root /app/dist;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

๋‹ค๋‹จ๊ณ„ ๋นŒ๋“œ๋Š” ์ด ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. Dockerfile์„ ๋ณ€๊ฒฝํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

FROM node:12.16.2-alpine3.11 as builder
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

FROM nginx:1.17.10-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/static.conf /etc/nginx/conf.d
COPY --from=builder /app/dist/app .

์ด์ œ ๋‘ ๊ฐ€์ง€ ์ง€์นจ์ด ์žˆ์Šต๋‹ˆ๋‹ค. FROM Dockerfile์—์„œ ๊ฐ๊ฐ์€ ๋‹ค๋ฅธ ๋นŒ๋“œ ๋‹จ๊ณ„๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ฒซ ๋ฒˆ์งธ ์‚ฌ๋žŒ์—๊ฒŒ ์ „ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. builder, ํ•˜์ง€๋งŒ ๋งˆ์ง€๋ง‰ FROM๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์ตœ์ข… ์ด๋ฏธ์ง€๊ฐ€ ์ค€๋น„๋ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋Š” nginx๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ๋‹จ๊ณ„์—์„œ ์–ด์…ˆ๋ธ”๋ฆฌ์˜ ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ์ตœ์ข… ์ด๋ฏธ์ง€์— ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€ ํฌ๊ธฐ๊ฐ€ ํฌ๊ฒŒ ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค.

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
app          latest   2c6c5da07802   29 minutes ago   36MB

์ด๋ฏธ์ง€๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

docker run -p8080:80 app

-p8080:80 ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์˜ ํฌํŠธ 8080์„ nginx๊ฐ€ ์‹คํ–‰๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์˜ ํฌํŠธ 80์œผ๋กœ ์ „๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์—ด๋ ค http://localhost:8080/ ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ์šฐ๋ฆฌ์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋ด…๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!

Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ 1.74GB์—์„œ 36MB๋กœ ์ค„์ด๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ”„๋กœ๋•์…˜์— ์ „๋‹ฌํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด ํฌ๊ฒŒ ๋‹จ์ถ•๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์กฐ๋ฆฝ ์‹œ๊ฐ„์œผ๋กœ ๋Œ์•„๊ฐ€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

$ time docker build -t app .
Sending build context to Docker daemon 608.8kB
Step 1/11 : FROM node:12.16.2-alpine3.11 as builder
Step 2/11 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
 ---> Using cache
Step 3/11 : WORKDIR /app
 ---> Using cache
Step 4/11 : COPY . .
Step 5/11 : RUN npm ci
added 1357 packages in 47.338s
Step 6/11 : RUN npm run build --prod
Date: 2020-04-16T21:16:03.899Z - Hash: fffa0fddaa3425c55dd3 - Time: 39948ms
 ---> 27f1479221e4
Step 7/11 : FROM nginx:stable-alpine
Step 8/11 : WORKDIR /app
 ---> Using cache
Step 9/11 : RUN rm /etc/nginx/conf.d/default.conf
 ---> Using cache
Step 10/11 : COPY nginx/static.conf /etc/nginx/conf.d
 ---> Using cache
Step 11/11 : COPY --from=builder /app/dist/app .
Successfully built d201471c91ad
Successfully tagged app:latest

real 2m17.700s
user 0m0.000s
sys 0m0.000s

๋ ˆ์ด์–ด ์ˆœ์„œ ๋ณ€๊ฒฝ

์ฒ˜์Œ ์„ธ ๋‹จ๊ณ„๋Š” ์บ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(ํžŒํŠธ Using cache). ๋„ค ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” ๋ชจ๋“  ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์ด ๋ณต์‚ฌ๋˜๊ณ  ๋‹ค์„ฏ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” ์ข…์†์„ฑ์ด ์„ค์น˜๋ฉ๋‹ˆ๋‹ค. RUN npm ci - ์ตœ๋Œ€ 47.338์ดˆ. ๋งค์šฐ ๋“œ๋ฌผ๊ฒŒ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ ์ข…์†์„ฑ์„ ๋งค๋ฒˆ ๋‹ค์‹œ ์„ค์น˜ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์™œ ์บ์‹œ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค. ์š”์ ์€ Docker๊ฐ€ ๊ณ„์ธต๋ณ„๋กœ ๋ช…๋ น๊ณผ ๊ด€๋ จ ํŒŒ์ผ์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋„ค ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜๊ณ  ๊ทธ ์ค‘์—๋Š” ๋ฌผ๋ก  ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋„ ์žˆ์œผ๋ฏ€๋กœ Docker๋Š” ์ด ๋ ˆ์ด์–ด๋ฅผ ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜ฌ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ํ›„์† ๋ ˆ์ด์–ด๋„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค! Dockerfile์„ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

FROM node:12.16.2-alpine3.11 as builder
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build --prod

FROM nginx:1.17.10-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/static.conf /etc/nginx/conf.d
COPY --from=builder /app/dist/app .

๋จผ์ € package.json ๋ฐ package-lock.json์ด ๋ณต์‚ฌ๋œ ๋‹ค์Œ ์ข…์†์„ฑ์ด ์„ค์น˜๋˜๊ณ  ๊ทธ ํ›„์—์•ผ ์ „์ฒด ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ:

$ time docker build -t app .
Sending build context to Docker daemon 608.8kB
Step 1/12 : FROM node:12.16.2-alpine3.11 as builder
Step 2/12 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
 ---> Using cache
Step 3/12 : WORKDIR /app
 ---> Using cache
Step 4/12 : COPY package*.json ./
 ---> Using cache
Step 5/12 : RUN npm ci
 ---> Using cache
Step 6/12 : COPY . .
Step 7/12 : RUN npm run build --prod
Date: 2020-04-16T21:29:44.770Z - Hash: fffa0fddaa3425c55dd3 - Time: 38287ms
 ---> 1b9448c73558
Step 8/12 : FROM nginx:stable-alpine
Step 9/12 : WORKDIR /app
 ---> Using cache
Step 10/12 : RUN rm /etc/nginx/conf.d/default.conf
 ---> Using cache
Step 11/12 : COPY nginx/static.conf /etc/nginx/conf.d
 ---> Using cache
Step 12/12 : COPY --from=builder /app/dist/app .
Successfully built a44dd7c217c3
Successfully tagged app:latest

real 0m46.497s
user 0m0.000s
sys 0m0.000s

46๋ถ„์ด ์•„๋‹Œ 3์ดˆ - ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค! ๋ ˆ์ด์–ด์˜ ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ € ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•ญ๋ชฉ์„ ๋ณต์‚ฌํ•œ ๋‹ค์Œ ๊ฑฐ์˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•ญ๋ชฉ, ๋งˆ์ง€๋ง‰์œผ๋กœ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ํ•ญ๋ชฉ์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ CI/CD ์‹œ์Šคํ…œ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์กฐ๋ฆฝํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ช‡ ๋งˆ๋”” ๋ง์”€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

์บ์‹œ์— ์ด์ „ ์ด๋ฏธ์ง€ ์‚ฌ์šฉ

๋นŒ๋“œ์— ์ผ์ข…์˜ SaaS ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋กœ์ปฌ Docker ์บ์‹œ๊ฐ€ ๊นจ๋—ํ•˜๊ณ  ์‹ ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋„์ปค์—๊ฒŒ ๊ตฌ์šด ๋ ˆ์ด์–ด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์žฅ์†Œ๋ฅผ ์ œ๊ณตํ•˜๋ ค๋ฉด ์ด์ „์— ๋นŒ๋“œ๋œ ์ด๋ฏธ์ง€๋ฅผ ๊ทธ์—๊ฒŒ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค.

GitHub Actions์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๋Š” ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค

on:
  push:
    branches:
      - master

name: Test docker build

jobs:
  deploy:
    name: Build
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Login to GitHub Packages
      env:
        TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN

    - name: Build
      run: |
        docker build 
          -t $IMAGE_NAME:$IMAGE_TAG 
          -t $IMAGE_NAME:latest 
          .

    - name: Push image to GitHub Packages
      run: |
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - name: Logout
      run: |
        docker logout docker.pkg.github.com

20๋ถ„ XNUMX์ดˆ ๋งŒ์— ์ด๋ฏธ์ง€๊ฐ€ ์ˆ˜์ง‘๋˜์–ด GitHub ํŒจํ‚ค์ง€์— ํ‘ธ์‹œ๋ฉ๋‹ˆ๋‹ค.

Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

์ด์ œ ์ด์ „์— ๋นŒ๋“œ๋œ ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์บ์‹œ๊ฐ€ ์‚ฌ์šฉ๋˜๋„๋ก ๋นŒ๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

on:
  push:
    branches:
      - master

name: Test docker build

jobs:
  deploy:
    name: Build
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Login to GitHub Packages
      env:
        TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN

    - name: Pull latest images
      run: |
        docker pull $IMAGE_NAME:latest || true
        docker pull $IMAGE_NAME-builder-stage:latest || true

    - name: Images list
      run: |
        docker images

    - name: Build
      run: |
        docker build 
          --target builder 
          --cache-from $IMAGE_NAME-builder-stage:latest 
          -t $IMAGE_NAME-builder-stage 
          .
        docker build 
          --cache-from $IMAGE_NAME-builder-stage:latest 
          --cache-from $IMAGE_NAME:latest 
          -t $IMAGE_NAME:$IMAGE_TAG 
          -t $IMAGE_NAME:latest 
          .

    - name: Push image to GitHub Packages
      run: |
        docker push $IMAGE_NAME-builder-stage:latest
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - name: Logout
      run: |
        docker logout docker.pkg.github.com

๋จผ์ € ๋‘ ๋ช…๋ น์ด ์‹คํ–‰๋˜๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. build. ์‚ฌ์‹ค ๋‹ค๋‹จ๊ณ„ ์–ด์…ˆ๋ธ”๋ฆฌ์—์„œ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€๋Š” ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์˜ ๋ ˆ์ด์–ด ์„ธํŠธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ด์ „ ๋ ˆ์ด์–ด์˜ ๋ ˆ์ด์–ด๋Š” ์ด๋ฏธ์ง€์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด์ „ ๋นŒ๋“œ์˜ ์ตœ์ข… ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ Docker๋Š” nodejs(๋นŒ๋” ๋‹จ๊ณ„)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ธฐ ์œ„ํ•ด ์ค€๋น„๋œ ๋ ˆ์ด์–ด๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ค‘๊ฐ„ ์ด๋ฏธ์ง€๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. $IMAGE_NAME-builder-stage ํ›„์† ๋นŒ๋“œ์—์„œ ์บ์‹œ ์†Œ์Šค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก GitHub ํŒจํ‚ค์ง€์— ํ‘ธ์‹œ๋ฉ๋‹ˆ๋‹ค.

Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

์ด ์กฐ๋ฆฝ ์‹œ๊ฐ„์€ XNUMX๋ถ„ XNUMX์ดˆ๋กœ ๋‹จ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ „ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐ XNUMX๋ถ„์ด ์†Œ์š”๋ฉ๋‹ˆ๋‹ค.

์‚ฌ์ „ ์ด๋ฏธ์ง•

๊นจ๋—ํ•œ Docker ์บ์‹œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์ผ๋ถ€ ๋ ˆ์ด์–ด๋ฅผ ๋‹ค๋ฅธ Dockerfile๋กœ ์ด๋™ํ•˜๊ณ  ๋ณ„๋„๋กœ ๋นŒ๋“œํ•œ ํ›„ Container Registry์— ํ‘ธ์‹œํ•˜๊ณ  ์ƒ์œ„ ํ•ญ๋ชฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” Angular ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฒด nodejs ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์— Dockerfile.node๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++

Docker Hub์—์„œ ๊ณต๊ฐœ ์ด๋ฏธ์ง€๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ํ‘ธ์‹œํ•ฉ๋‹ˆ๋‹ค.

docker build -t exsmund/node-for-angular -f Dockerfile.node .
docker push exsmund/node-for-angular:latest

์ด์ œ ๊ธฐ๋ณธ Dockerfile์—์„œ ์™„์„ฑ๋œ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

FROM exsmund/node-for-angular:latest as builder
...

์ด ์˜ˆ์—์„œ๋Š” ๋นŒ๋“œ ์‹œ๊ฐ„์ด ์ค„์–ด๋“ค์ง€ ์•Š์•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋งŽ๊ณ  ๊ฐ ํ”„๋กœ์ ํŠธ์— ๋™์ผํ•œ ์ข…์†์„ฑ์„ ์„ค์น˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์ „ ๋นŒ๋“œ๋œ ์ด๋ฏธ์ง€๊ฐ€ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Docker ์ด๋ฏธ์ง€ ๊ตฌ์ถ• ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ๋Œ€ 30์ดˆ์ž…๋‹ˆ๋‹ค.

Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰ํ•˜๋ ค๋ฉด ํ”„๋กœ์ ํŠธ์—์„œ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”.

  • ๋งฅ๋ฝ ๊ฐ์†Œ;
  • ์ž‘์€ ๋ถ€๋ชจ ์ด๋ฏธ์ง€ ์‚ฌ์šฉ;
  • ๋‹ค๋‹จ๊ณ„ ์กฐ๋ฆฝ;
  • ์บ์‹œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Dockerfile์˜ ๋ช…๋ น ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  • CI/CD ์‹œ์Šคํ…œ์—์„œ ์บ์‹œ ์„ค์ •
  • ์ด๋ฏธ์ง€์˜ ์˜ˆ๋น„ ์ƒ์„ฑ.

์˜ˆ์ œ๋ฅผ ํ†ตํ•ด Docker์˜ ์ž‘๋™ ๋ฐฉ์‹์ด ๋” ๋ช…ํ™•ํ•ด์ง€๊ณ  ๋ฐฐํฌ๋ฅผ ์ตœ์ ์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ์˜ ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ €์žฅ์†Œ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. https://github.com/devopsprodigy/test-docker-build.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€