Cloud Design 2nd - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki

2๋‹จ๊ณ„ - CI(์ง€์†์  ํ†ตํ•ฉ) ํŒŒ์ดํ”„๋ผ์ธ ์„ค๊ณ„

Important

๋ชฉํ‘œ: ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž์ฃผ ํ†ตํ•ฉํ•˜๋”๋ผ๋„ ์„œ๋น„์Šค๊ฐ€ ํ•ญ์ƒ ์–ธ์ œ๋“  '๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ'๋ฅผ ์œ ์ง€ํ•˜๋„๋ก ์ž๋™ํ™”๋œ ํ†ตํ•ฉ ๊ณผ์ •์„ ๊ตฌ์ถ•ํ•œ๋‹ค.

๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ: ๋ธŒ๋žœ์น˜์˜ ์ตœ์‹  ์ปค๋ฐ‹์ด ์ •์  ๋ถ„์„/ํ…Œ์ŠคํŠธ(๋‹จ์œ„/์ „์ฒด)/๋นŒ๋“œ/Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ๊นŒ์ง€ ๋ชจ๋‘ ํ†ต๊ณผํ•ด์„œ, ๊ทธ๋Œ€๋กœ ์šด์˜ ์„œ๋ฒ„์— ๋ฐฐํฌํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ์ƒํƒœ


1. ์ƒํ™ฉ ์ •๋ฆฌ

1) ํŒ€ ๊ฐœ๋ฐœ ์ƒํ™ฉ

์šฐ๋ฆฌ ํŒ€์€ ํ˜„์žฌ ์„œ๋น„์Šค ๊ฐœ๋ฐœ์ด ๋ณธ๊ฒฉํ™”๋˜๋ฉด์„œ ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋ฐ ํ†ตํ•ฉ ๋นˆ๋„๊ฐ€ ๊ธ‰๊ฒฉํžˆ ์ฆ๊ฐ€ํ•˜๊ณ  ์žˆ๋‹ค.

  • ๊ฐœ๋ฐœ ์ธ๋ ฅ ๊ตฌ์„ฑ: ์ด 6๋ช…
    • ํ’€์Šคํƒ(FE/BE) 2๋ช…: Spring Boot ๋ฐ React ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ๋‹ด๋‹น
    • AI 2๋ช…: FastAPI ๊ธฐ๋ฐ˜ AI ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ๋‹ด๋‹น
    • ํด๋ผ์šฐ๋“œ 2๋ช…: ์ธํ”„๋ผ ๊ตฌ์„ฑ, ๋ฐฐํฌ ๋ฐ ์šด์˜ ์ž๋™ํ™” ๋‹ด๋‹น
  • ๊ธฐ์ˆ  ์Šคํƒ:
    • Backend (Java, Spring Boot, Gradle)
    • Frontend (TypeScript, React, Vite)
    • AI Server (Python, FastAPI)
    • Database & Cache

2) ๋นˆ๋ฒˆํ•œ ์ฝ”๋“œ ํ†ตํ•ฉ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ 

๊ฐœ๋ฐœ ์ธ์›์ด ๊ฐ์ž์˜ ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ ์ž‘์—…ํ•˜๊ณ  ์ˆ˜๋™์œผ๋กœ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ฉํ•˜๋ฉด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ํ•„์—ฐ์ ์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค.

๋ฐœ์ƒ ๋ฌธ์ œ ๊ตฌ์ฒด์ ์ธ ์›์ธ ๋ฐ ์˜ํ–ฅ
Merge ์ดํ›„ ๋นŒ๋“œ ์‹คํŒจ ๋กœ์ปฌ์—์„œ๋Š” ์ •์ƒ ๋™์ž‘ํ–ˆ์œผ๋‚˜, ๋‹ค๋ฅธ ํŒ€์›์˜ ์ตœ์‹  ์ฝ”๋“œ์™€ ํ†ตํ•ฉ๋˜์—ˆ์„ ๋•Œ ์˜์กด์„ฑ ์ถฉ๋Œ์ด๋‚˜ ์ปดํŒŒ์ผ ์˜ค๋ฅ˜ ๋ฐœ์ƒ
๋ฏธ๊ฒ€์ฆ ์ฝ”๋“œ์˜ dev ๋ธŒ๋žœ์น˜ ์œ ์ž… ๋ฐ”์œ ๊ฐœ๋ฐœ ์ผ์ •์œผ๋กœ ์ธํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ PR์ด ์Šน์ธ๋˜์–ด dev์— Merge๋  ์ˆ˜ ์žˆ์Œ
๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ฐจ์ด๋กœ ์ธํ•œ ์˜ค๋ฅ˜ ์˜์กด์„ฑ ๋ฒ„์ „ ์ฐจ์ด ๋“ฑ์œผ๋กœ ๊ฐœ๋ฐœ์ž์˜ ๋กœ์ปฌ PC์—์„œ๋Š” ์ž˜ ๋Œ์•„๊ฐ€๋Š”๋ฐ ๋ฐฐํฌ ์„œ๋ฒ„์—์„œ๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ํ™˜๊ฒฝ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ ๋ฐœ์ƒ
Docker Image ์ˆ˜๋™ Build ์‹ค์ˆ˜ ๋‹ด๋‹น์ž๊ฐ€ ๋กœ์ปฌ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ˆ˜๋™ ๋นŒ๋“œ/ํ‘ธ์‹œํ•  ๊ฒฝ์šฐ ํƒœ๊ทธ ์˜คํƒ€, ํ•„์ˆ˜ ์„ค์ • ๋ˆ„๋ฝ ๋“ฑ์œผ๋กœ ์ž˜๋ชป๋œ ๋ฒ„์ „์ด ์ƒ์„ฑ๋  ์œ„ํ—˜
์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์ทจ์•ฝ์  ๋ฐœ์ƒ ๋‹ด๋‹น์ž๊ฐ€ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œ ์‹œ์— ๋น„๋ฐ€๊ฐ’์ด ํฌํ•จ๋˜๋Š” ๋“ฑ ์ด๋ฏธ์ง€๋กœ ์ธํ•ด ์ทจ์•ฝ์ ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ

Caution

์‚ฌ๋žŒ์ด ์ˆ˜๋™์œผ๋กœ ๊ฒ€์ฆํ•˜๊ณ  ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ์‹์€ Human Error๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ฝ”๋“œ ํ†ตํ•ฉ ๋นˆ๋„๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก Main ๋ธŒ๋žœ์น˜์˜ ์‹ ๋ขฐ์„ฑ์ด ๊ธ‰๊ฒฉํžˆ ๋–จ์–ด์ง„๋‹ค.


3) ์šฐ๋ฆฌ๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒƒ (CI ๋„์ž… ํ•„์š”์„ฑ)

๋‹จ์ˆœํžˆ ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ค„์ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ˆ„๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋“  ์ผ๊ด€๋œ ๊ฒ€์ฆ์„ ๊ฑฐ์ณ ํ•ญ์ƒ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด CI(์ง€์†์  ํ†ตํ•ฉ) ํŒŒ์ดํ”„๋ผ์ธ์ด ํ•„์š”ํ•˜๋‹ค.

(1) ์ฝ”๋“œ ํ…Œ์ŠคํŠธ ์ž๋™ํ™”

  • Merge ํ›„ ๋นŒ๋“œ ์‹คํŒจ, ์ฝ”๋“œ ์˜ค๋ฅ˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, PR ์š”์ฒญ ์‹œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋นŒ๋“œํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” human error ๊ฐ€๋Šฅ์„ฑ์„ ๊ฐ€์ง„๋‹ค.
  • ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•ด์•ผ๋งŒ Dev ๋ธŒ๋žœ์น˜์— Merge๋˜๋ฉฐ, ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ•œ ์ฝ”๋“œ๋Š” Dev ๋ธŒ๋žœ์น˜๋กœ Merge๋˜์ง€ ์•Š๋„๋ก ์ง„์ž…์„ ์ฐจ๋‹จํ•˜์—ฌ, Dev ๋ธŒ๋žœ์น˜๋ฅผ ํ•ญ์ƒ ๋กœ์ปฌ์—์„œ ๊ฒ€์ฆ ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•œ๋‹ค.
    • ์šด์˜ ๋ฐฐํฌ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋Š” ์ดํ›„ ์ „์ฒด ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜๋Š” main ์Šน๊ฒฉ ์‹œ์ ์— ํ™•์ •๋œ๋‹ค.
  • ๋ธŒ๋žœ์น˜ ๋“ฑ์„ ๋ณ‘ํ•ฉํ•  ๋•Œ ํ‹ˆํ‹ˆ์ด ์ง€์†์ ์œผ๋กœ ๊ฒ€์ฆํ•˜์—ฌ ์›ํ™œํ•œ ํ˜‘์—…์„ ์œ„ํ•œ ํ•˜๋‚˜์˜ ์ˆ˜๋‹จ์ด ๋˜๊ธฐ๋„ ํ•œ๋‹ค.

(2) ๋กœ์ปฌ ํ™˜๊ฒฝ์— ๋…๋ฆฝ์ ์ธ ํ‘œ์ค€ ๋นŒ๋“œ ํ™˜๊ฒฝ

  • ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ฐจ์ด๋กœ ์ธํ•œ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ๊ฐœ๋ฐœ์ž์˜ ๋กœ์ปฌ ๋จธ์‹  ์„ค์ •์— ์˜์กดํ•˜์ง€ ์•Š๊ณ , ์šด์˜ ํ™˜๊ฒฝ๊ณผ ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜๋Š” ํ‘œ์ค€ํ™”๋œ CI ๋Ÿฌ๋„ˆ ํ™˜๊ฒฝ์ด ํ•„์š”ํ•˜๋‹ค.

(3) ์ผ๊ด€๋œ ๋ฐฐํฌ ์‚ฐ์ถœ๋ฌผ(Docker Image) ์ž๋™ ์ƒ์„ฑ

  • Docker Image ์ˆ˜๋™ ๋นŒ๋“œ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋‚˜ ์ด ๋ฐฉ๋ฒ•๋„ human error๋ฅผ ์›์ฒœ ์ฐจ๋‹จํ•  ์ˆ˜๋Š” ์—†๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ฝ”๋“œ ๊ฒ€์ฆ์— ์„ฑ๊ณตํ•œ ์ปค๋ฐ‹์— ๋Œ€ํ•ด์„œ๋งŒ ์ž๋™์œผ๋กœ Docker ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ํ‘ธ์‹œํ•˜๋Š” ์ผ๊ด€๋œ ํŒŒ์ดํ”„๋ผ์ธ ํ๋ฆ„์ด ํ•„์š”ํ•˜๋‹ค.

2. CI ๋„๊ตฌ ์„ ์ •

CI ์„ค๊ณ„ ์‹œ ๊ธฐ์ค€

  1. ๊ฐœ๋ฐœ ์‹œ์— CI ๊ฐ€์šฉ์„ฑ์ด ํ•„์š”ํ•จ: ๊ฐœ๋ฐœ์˜ ํ๋ฆ„์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š์•„์•ผ ํ•จ
  2. ์ถ”๊ฐ€ ๋น„์šฉ์ด ํฌ์ง€ ์•Š์•„์•ผ ํ•จ

1) CI ํ™˜๊ฒฝ ์„ ์ •

Important

CI ๊ฐ€์šฉ์„ฑ์ด ์œ ์ง€๋˜๋ฉฐ, ํ˜„์žฌ ํŒ€์—์„œ ๋ฌด๋ฃŒ ํ•œ๋„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ CI ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

CI ํ™˜๊ฒฝ์€ ์•„๋ž˜ ์„ธ ๊ฐ€์ง€๋กœ ๋‚˜๋‰œ๋‹ค.

  1. ๋กœ์ปฌ PC ์ปจํ…Œ์ด๋„ˆ
    • ์ปดํ“จํ„ฐ๊ฐ€ ์žฌ๋ถ€ํŒ…๋˜๊ฑฐ๋‚˜ ์™€์ดํŒŒ์ด๊ฐ€ ๋Š๊ธฐ๋ฉด ๋‹ค๋ฅธ ํŒ€์›๋“ค์˜ PR ๋นŒ๋“œ์™€ ํ…Œ์ŠคํŠธ๊ฐ€ ๋ฉˆ์ถค
  2. ํด๋ผ์šฐ๋“œ ์ž์ฒด ํ˜ธ์ŠคํŒ…
    • CI ์„œ๋ฒ„ ๊ฐ€์šฉ์„ฑ ์œ ์ง€๋Š” ๊ฐ€๋Šฅํ•˜๋‚˜, EC2 ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด ๋น„์šฉ์ด ๋ฐœ์ƒ
  3. ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ CI
    • ์„œ๋ฒ„ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”์—†์œผ๋ฉฐ ๊ฐ€์šฉ์„ฑ์ด ์œ ์ง€๋˜๋ฉฐ, ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋ฐœ๋™๋˜์—ˆ์„ ๋•Œ์—๋งŒ ์ž‘๋™ํ•จ
    • ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ์„œ๋น„์Šคํ•˜๋Š” ๊ณณ๊ณผ ๊ฐ™์€ CI ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฐ๋™์„ฑ์ด ์ข‹์Œ
    • ์‚ฌ์šฉ๋Ÿ‰์— ๋”ฐ๋ฅธ ๋น„์šฉ์ด ์ฒญ๊ตฌ๋˜์ง€๋งŒ, ํ˜„์žฌ ํŒ€ ์ƒํ™ฉ์—์„œ๋Š” ๋ฌด๋ฃŒ ํ•œ๋„ ๋‚ด์—์„œ CI ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํŒ๋‹จ๋จ

๊ฐ€์šฉ์„ฑ ์œ ์ง€์™€ ๋น„์šฉ์„ ์ค„์ด๋Š” ๊ธฐ์ค€์— ์˜ํ•ด, ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ CI์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

2) ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ CI ์„œ๋น„์Šค ์„ ์ •

Important

์—ฌ๋Ÿฌ ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ CI ์„œ๋น„์Šค๊ฐ€ ๊ฐ€์šฉ์„ฑ๊ณผ ๋น„์šฉ์„ ์ถฉ์กฑํ•˜์ง€๋งŒ, ๊ทธ์ค‘์—์„œ ํ˜„์žฌ ํŒ€์˜ Github ๋ ˆํฌ์ง€ํ† ๋ฆฌ์™€ ์—ฐ๋™์„ฑ์ด ์ข‹์€ Github Actions๋ฅผ ์„ ํƒํ•œ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ CI๋กœ๋Š” ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€๋กœ ๋‚˜๋‰œ๋‹ค.

  • ํด๋ผ์šฐ๋“œ ํ”Œ๋žซํผ: AWS CodeBuild, Google Cloud Build, Azure Pipelines
  • SaaS: Circle CI, Travis CI
  • ์†Œ์Šค์ฝ”๋“œ ์ €์žฅ์†Œ ์ผ์ฒดํ˜•: Github Actions, GitLab CI/CD, BitBucket Pipelines

  1. ์„ธ๊ฐ€์ง€ ๋ชจ๋‘ ๊ฐ€์šฉ์„ฑ์€ ์ถฉ์กฑํ•œ๋‹ค.
  2. ์›”๊ฐ„ ์˜ˆ์ƒ CI/CD ์‹œ๊ฐ„์„ ๊ณ ๋ คํ•œ ๋น„์šฉ๋ฉด์—์„œ๋Š” CircleCI, Google Cloud Build, Github Actions ๋ชจ๋‘ ๋™์ผํ•˜๊ฒŒ ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ์„ธ๊ฐ€์ง€ ๋ชจ๋‘ ๋น„์šฉ๋ฉด์—์„œ๋„ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํฐ ์ฐจ์ด๊ฐ€ ๋‚˜์ง€ ์•Š์•˜๋‹ค. ์ด๋•Œ, ์šด์˜์˜ ํŽธ์˜์„ฑ ๋ถ€๋ถ„์„ ๊ณ ๋ คํ•ด Github ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ณ„๋„ ์ธ์ฆ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ Github Actions๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    • CircleCI, Google Cloud Build ๋ชจ๋‘ Github์™€ ์—ฐ๋™์„ฑ์ด ๋‚˜์˜์ง€ ์•Š๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Github ์ƒํƒœ๊ณ„๋ฅผ ํ†ตํ•ด์„œ ๋ณ„๋„๋กœ ์„ค์ •ํ•  ๊ฒƒ ์—†์ด ์„œ๋กœ ์ฆ‰์‹œ ์—ฐ๋™๋˜๋Š” ์ ์„ ์„ ํƒ์˜ ๊ทผ๊ฑฐ๋กœ ์‚ผ์•˜๋‹ค.
์›”๊ฐ„ ์˜ˆ์ƒ CI/CD ์‹œ๊ฐ„ (ํด๋ฆญํ•˜์—ฌ ํŽผ์น˜๊ธฐ)
์ž‘์—… ์ž‘์—… ๋‚ด์šฉ ์‹œ๊ฐ„ ์ผ์ผ ๋นˆ๋„ ์˜ˆ์ƒ ์‹œ๊ฐ„(20์ผ)
ํ”„๋ก ํŠธ์—”๋“œ CI ์ •์  ๋ถ„์„, ์ •์  ํŒŒ์ผ ๋นŒ๋“œ 2๋ถ„ ์ผ 5ํšŒ 200๋ถ„
๋ฐฑ์—”๋“œ CI ์ •์  ๋ถ„์„, ์ปดํŒŒ์ผ, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ 3๋ถ„ ์ผ 5ํšŒ 300๋ถ„
AI ์„œ๋ฒ„ CI ์ •์  ๋ถ„์„, API ๋‹จ์œ„ ๊ฒ€์ฆ 3๋ถ„ ์ผ 5ํšŒ 300๋ถ„
Docker Image ๋นŒ๋“œ ๋นŒ๋“œ ์‚ฐ์ถœ๋ฌผ ๊ธฐ๋ฐ˜ Docker Image ๋นŒ๋“œ ๋ฐ Push 3๋ถ„ ์ผ 5ํšŒ 300๋ถ„
CD EC2 ์ ‘์†, docker compose pull & up, ํ—ฌ์Šค์ฒดํฌ 4๋ถ„ ์ผ 5ํšŒ 400๋ถ„
์ดํ•ฉ 1500๋ถ„
ํด๋ผ์šฐ๋“œ ๊ธฐ๋ฐ˜ CI ์„œ๋น„์Šค ๋น„์šฉํ‘œ (ํด๋ฆญํ•˜์—ฌ ํŽผ์น˜๊ธฐ)
์„œ๋น„์Šค ์›”๊ฐ„ ๋ฌด๋ฃŒ ์ œ๊ณต๋Ÿ‰ ๋ถ„๋‹น ์š”๊ธˆ
AWS CodeBuild ์›” 100๋ถ„ $0.005 / ๋ถ„
Google Cloud Build ์›” 2500๋ถ„ $0.006 / ๋ถ„
Azure Pipelines ์›” 1800๋ถ„ $0.008 / ๋ถ„
CircleCI ์›” 30,000 ํฌ๋ ˆ๋”ง(์ตœ๋Œ€ 6000๋ถ„) $0.003 / ๋ถ„(์ตœ์†Œ)
Travis CI ์—†์Œ ์›” $15, 700๋ถ„
Github Actions Private 2000๋ถ„(Public ๋ฌด๋ฃŒ) $0.008 / ๋ถ„
GitLab CI/CD ์›” 400๋ถ„ $0.01/๋ถ„
BitBucket Pipelines ์›” 50๋ถ„ $0.01/๋ถ„

3. CI Trigger

๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ „๋žต: ๋ฉ€ํ‹ฐ ๋ ˆํฌ(ํ”„๋ก ํŠธ, ๋ฐฑ, AI)

๋ธŒ๋žœ์น˜ ์ „๋žต

  • ๋ธŒ๋žœ์น˜ ์ข…๋ฅ˜: main, dev, feat, hotfix
  • main: ๋‹น์žฅ ์šด์˜ ํ™˜๊ฒฝ์— ๋ฐฐํฌํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋Š”, ๊ฒ€์ฆ๋œ ์ƒํƒœ. ๋ฐฐํฌ ์‹œ์ ์—๋งŒ ๊ฐฑ์‹ 
  • dev: feat์—์„œ merge๋œ ๋ณ€๊ฒฝ์ด ๊ณ„์† ์Œ“์ด๋Š” ํ†ตํ•ฉ ๋ธŒ๋žœ์น˜. ๋ฐฐํฌ ์ฃผ๊ธฐ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์‹ค์‹œ๊ฐ„ ๊ฐฑ์‹ 
  • feat: ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ๋ธŒ๋žœ์น˜
  • hotfix: ์šด์˜ ์ค‘(main) ๋ฒ„์ „์˜ ๊ธด๊ธ‰ ๋ฒ„๊ทธ ์ˆ˜์ • ์ „์šฉ ๋ธŒ๋žœ์น˜. main์—์„œ ๋ถ„๊ธฐ

๋ธŒ๋žœ์น˜์™€ ํƒœ๊ทธ

  • feat -> dev PR: ์ •์  ๋ถ„์„, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, ๋นŒ๋“œ, docker image build
  • dev push(merge): ํ†ตํ•ฉ ์ด๋ฏธ์ง€ ๋นŒ๋“œ/push (ํƒœ๊ทธ: latest, dev-<short SHA>) -> ๋กœ์ปฌ/๊ฐœ์ธ EC2์—์„œ latest pull ๋ฐ›์•„ docker-compose๋กœ ๋™์ž‘ ๊ฒ€์ฆ
  • dev -> main (์ •๊ธฐ ๋ฐฐํฌ): ์ „์ฒด ํ…Œ์ŠคํŠธ ํ›„ merge. ๋‹จ, PR merge๋งŒ์œผ๋กœ๋Š” ์ด๋ฏธ์ง€๊ฐ€ ๋นŒ๋“œ๋˜์ง€ ์•Š์œผ๋ฉฐ, merge ํ›„ release ํƒœ๊ทธ(v*..)๋ฅผ pushํ•ด์•ผ Semantic Version ํƒœ๊ทธ๋กœ ์ด๋ฏธ์ง€ ๋นŒ๋“œ/push/๋ฐฐํฌ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋œ๋‹ค.
  • hotfix -> main (์ˆ˜์‹œ, ๊ธด๊ธ‰ ๋ฐฐํฌ): ์ ˆ๋Œ€ ์‹คํŒจ ๋ถˆ๊ฐ€ ๊ธฐ๋Šฅ(์ฑ„ํŒ…ํ•˜๊ธฐ, ๊ตํ™˜ ์ œ์•ˆ) ์˜ํ–ฅ ๋ฒ„๊ทธ ๋Œ€์ƒ. merge ํ›„ patch ๋ฒ„์ „(e.g. v1.0.1) release ํƒœ๊ทธ๋ฅผ pushํ•ด ์ฆ‰์‹œ ๋ฐฐํฌํ•˜๊ณ , dev์—๋„ ๋ฐ˜์˜
  • ์ง€์—ฐ ํ—ˆ์šฉ ๊ธฐ๋Šฅ(๋ชฉ๋ก/์ƒ์„ธ์กฐํšŒ, AI ๊ธฐ๋Šฅ ๋“ฑ) ๋ฒ„๊ทธ๋Š” hotfix๊ฐ€ ์•„๋‹Œ ๋‹ค์Œ ์ •๊ธฐ ๋ฐฐํฌ(dev -> main)์— ํฌํ•จ
  • release ํƒœ๊ทธ๋Š” GitHub Release ์ƒ์„ฑ(Target: main, ์ƒˆ ํƒœ๊ทธ v1.0.1 ํ˜•์‹ ์ž…๋ ฅ ํ›„ Publish)์œผ๋กœ pushํ•œ๋‹ค. main์œผ๋กœ ๋ณ‘ํ•ฉํ•˜๋Š” ์‹œ์ ๊ณผ ๋ฐฐํฌ์šฉ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“œ๋Š” ์‹œ์ ์„ ์˜๋„์ ์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.

CI Trigger

Trigger ์‹คํ–‰ ํ•ญ๋ชฉ ๋น„๊ณ 
feat -> dev PR ์ •์  ๋ถ„์„, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, ๋นŒ๋“œ, docker image build ๊ฒ€์ฆ์šฉ, docker image push ์—†์Œ
dev push(merge) docker image build, push ํƒœ๊ทธ: latest, dev-<short SHA>
dev -> main PR ์ „์ฒด ํ…Œ์ŠคํŠธ ์ •๊ธฐ ๋ฐฐํฌ ์ „, ๊ฒ€์ฆ์šฉ
hotfix -> main PR ์ •์  ๋ถ„์„, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, ๋นŒ๋“œ, docker image build ๊ธด๊ธ‰ ๋ฒ„๊ทธ ์ˆ˜์ •, ๊ฒ€์ฆ์šฉ, push ์—†์Œ
release ํƒœ๊ทธ(v*.*.*) push docker image build, push main push(merge)๊ฐ€ ์•„๋‹Œ release ํƒœ๊ทธ push๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ. ํƒœ๊ทธ: Semantic Version๋งŒ ์‚ฌ์šฉ
๋ฉ”ํƒ€๋ฐ์ดํ„ฐ: ์ด๋ฏธ์ง€ ๋ผ๋ฒจ์— ๋นŒ๋“œ ํƒ€์ž„์Šคํƒฌํ”„, ์ปค๋ฐ‹ ์ž‘์„ฑ์ž, Git SHA๋ฅผ OCI(Open Container Initiative) ํ‘œ์ค€์œผ๋กœ ์ฃผ์ž…
  • PR ๋‹จ๊ณ„์—์„œ๋Š” merge๊ฐ€ ๊ฑฐ์ ˆ๋˜์–ด ์ฝ”๋“œ๊ฐ€ ์ˆ˜์ •๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ Docker Image๋ฅผ build๋งŒ ํ•˜๊ณ  pushํ•˜์ง€ ์•Š๋Š”๋‹ค.
    • PR ๋‹จ๊ณ„์—์„œ Docker Image๋ฅผ buildํ•˜๋Š” ์ด์œ ๋Š”, PR ๋‹จ๊ณ„์—์„œ build ์‹คํŒจ๋ฅผ ํ™•์ธํ•˜์ง€ ๋ชปํ•˜๊ณ  dev๋‚˜ main์— merge๋˜๋ฉด dev, main ๋ธŒ๋žœ์น˜๊ฐ€ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์€ ์ƒํƒœ๊ฐ€ ๋˜์–ด, ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ์ƒํƒœ๋ฅผ ๋”ฐ๋กœ ๊ตฌ๋ถ„ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • dev ๋ธŒ๋žœ์น˜๋ฅผ Docker Image๋กœ ๋นŒ๋“œํ•˜๊ณ  pushํ•˜๋Š” ์ด์œ ๋Š”, main ๋ธŒ๋žœ์น˜์—๋Š” ์šด์˜ ์ค‘์ธ ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฏ€๋กœ, ์ •๊ธฐ ๋ฐฐํฌ ์ด์ „๊นŒ์ง€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ€์ง€๊ณ  ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.

4. CI Pipeline

1) ์ œ์–ด ์ •์ฑ…

  • Concurrency ์ œ์–ด
    • ๋™์ผ ๋ธŒ๋žœ์น˜/PR์— ์—ฐ์† Push ๋ฐœ์ƒ ์‹œ ์ง„ํ–‰ ์ค‘์ด๋˜ ์ด์ „ ์‹คํ–‰ ์ž๋™ ์ทจ์†Œ => GitHub Actions ํ ๋‚ญ๋น„ ๋ฐฉ์ง€
  • ๋ธŒ๋žœ์น˜ ๋ณดํ˜ธ
    • main, dev ๋ธŒ๋žœ์น˜์— Direct Push ์ฐจ๋‹จ
    • ๋ฐ˜๋“œ์‹œ PR์„ ๊ฑฐ์ณ์•ผ ํ•˜๋ฉฐ, ์ง€์ •๋œ CI ์›Œํฌํ”Œ๋กœ์šฐ๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ Merge ๋ฒ„ํŠผ ํ™œ์„ฑํ™”

2) ์Šค์ผ€์ค„๋Ÿฌ ์ •์ฑ…

์ •๊ธฐ ๋ฐฐํฌ ์ฃผ๊ธฐ(๋งค์ฃผ ์›”์š”์ผ ์˜ค์ „ 10์‹œ)์™€ ์‹œ์Šคํ…œ ์œ ์ง€๋ณด์ˆ˜ ์ง€์›

  • ์ •๊ธฐ ๋ฆด๋ฆฌ์ฆˆ ๋นŒ๋“œ ๊ฒ€์ฆ
    • ๋งค์ฃผ ์›”์š”์ผ ์˜ค์ „ 8์‹œ ์‹คํ–‰
    • ์˜ค์ „ 10์‹œ ์ •๊ธฐ ๋ฐฐํฌ ์ „ ์ตœ์ข… ๋ณ‘ํ•ฉ๋œ main ๋ธŒ๋žœ์น˜์˜ ์ตœ์‹  ์ƒํƒœ์— ๋Œ€ํ•ด E2E ํ…Œ์ŠคํŠธ ๋ฐ ๋ฐฐํฌ ๋Œ€์ƒ ์ด๋ฏธ์ง€ ํƒœ๊ทธ ํ™•์ •
  • ๋ณด์•ˆ ์ทจ์•ฝ์  ์ฃผ๊ธฐ์  ์Šค์บ”
    • ๋งค์ฃผ ์ผ์š”์ผ ์˜ค์ „ 3์‹œ ์‹คํ–‰
    • ์ƒˆ๋กœ์šด CVE ๋ฐœ์ƒ ์—ฌ๋ถ€ ํ™•์ธ์„ ์œ„ํ•ด ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€ ๋ฐ ์ข…์†์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฃผ๊ธฐ์ ์œผ๋กœ ์žฌ๊ฒ€์‚ฌ => ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‹ ๊ทœ ์ทจ์•ฝ์ ์ด๋‚˜ ์˜์กด์„ฑ ์†Œํ”„ํŠธ์›จ์–ด ๋…ธํ›„ํ™” ํƒ์ง€
      • ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž์ฃผ ์—†๋Š” ํ”„๋กœ์ ํŠธ๋ฉด ํ•„์š”ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๋Š” ์ตœ์†Œ 3์ผ 1ํšŒ CI ์‹œ์Šคํ…œ์ด ๋™์ž‘ํ•  ๊ฒƒ์ด๊ณ  ์ฃผ 1ํšŒ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์–ด ํ•„์ˆ˜์ ์ด์ง€ ์•Š๋‹ค.

3) ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์ •์ฑ…

์ด๋ฏธ์ง€ ํฌ๊ธฐ ๋‹ค์ด์–ดํŠธ

  • Multi-stage build๋กœ ๋นŒ๋“œ ๋„๊ตฌ๋ฅผ ์ตœ์ข… ๋Ÿฐํƒ€์ž„ ์ด๋ฏธ์ง€์—์„œ ์ œ์™ธ
  • ๊ฒฝ๋Ÿ‰ ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€ ์ฑ„ํƒ(alpine, slim)

3) CI Stages

[!NOTICE] GitHub Actions์˜ private ๋ ˆํฌ๋Š” GitHub-hosted ๋Ÿฌ๋„ˆ์— ์›”๋ณ„ 2,000๋ถ„๊ณผ ์Šคํ† ๋ฆฌ์ง€๋Š” ๋ฌด๋ฃŒ๋‹ค. => ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์„ ์ตœ์†Œํ™”ํ•˜์—ฌ ์‹œ๊ฐ„๊ณผ ๋ฆฌ์†Œ์Šค๋ฅผ ์ ˆ์•ฝํ•ด์•ผ ํ•œ๋‹ค.

  1. ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฒ€์ฆ
  • Spring Boot
    • SpotBugs: NPE, ์ž์› ๋ฏธ๋ฐ˜ํ™˜ ๋“ฑ ์ž ์žฌ์  ๋ฒ„๊ทธ ํƒ์ง€
    • PMD: ๋ฏธ์‚ฌ์šฉ ๋ณ€์ˆ˜, ๋ณต์žก๋„ ๋†’์€ ์ฝ”๋“œ ํƒ์ง€
    • Checkstyle๊ณผ ๊ฐ™์€ ์ฝ”๋“œ ์Šคํƒ€์ผ ํƒ์ง€๋Š” BE ์ธ์›์ด 1๋ช…์ด๋ผ ๊ฐœ์ธ IDE ๊ฒ€์‚ฌ๋กœ ์ถฉ๋ถ„ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ
  • FastAPI
    • Ruff: Linting, Formatting, import ์ •๋ฆฌ => ํƒ€ ๋„๊ตฌ๋ณด๋‹ค 10๋ฐฐ ์ด์ƒ ๋น ๋ฅด๋ฉฐ(1์ดˆ ๋ฏธ๋งŒ) ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋งŽ๋‹ค.
  • React
    • ESLint: ์„ ์–ธ๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜ ์‚ฌ์šฉ, ์ž˜๋ชป๋œ React Hooks ๊ทœ์น™ ์ค€์ˆ˜ ๋“ฑ ๋ฒ„๊ทธ๋กœ ์ด์–ด์ง€๋Š” ์˜ค๋ฅ˜ ํƒ์ง€
    • Prettier, Biome์™€ ๊ฐ™์€ ์ฝ”๋“œ ์Šคํƒ€์ผ ํƒ์ง€๋Š” FE ์ธ์›์ด 1๋ช…์ด๋ผ ๊ฐœ์ธ IDE ๊ฒ€์‚ฌ๋กœ ์ถฉ๋ถ„ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ
  • ๋ ˆํฌ ๋ฃจํŠธ์— .editorconfig ํŒŒ์ผ์„ ์ •์˜ํ•˜์—ฌ ์ผ๊ด€๋œ ๊ทœ์น™์œผ๋กœ Formatting => OS ์ฐจ์ด๋กœ ์ธํ•ด ์ค„๋ฐ”๊ฟˆ์ด๋‚˜ ๋“ค์—ฌ์“ฐ๊ธฐ ๋ถˆ์ผ์น˜ ๋ฐฉ์ง€
  1. ๋นŒ๋“œ ๋ฐ ๊ฒฉ๋ฆฌ ํ…Œ์ŠคํŠธ
  • ์ข…์†์„ฑ ์บ์‹ฑ ํ™œ์šฉ(Gradle, pip, npm/pnpm ์บ์‹œ)
  • ์™ธ๋ถ€ ์˜์กด์„ฑ(DB) ์—†์ด ํ†ต๊ณผ ๊ฐ€๋Šฅํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์œ„์ฃผ ์‹คํ–‰ => DB ์—ฐ๋™ ํ…Œ์ŠคํŠธ ํ•„์š” ์‹œ Testcontainers ๋˜๋Š” ๊ฒฝ๋Ÿ‰ H2/์ธ๋ฉ”๋ชจ๋ฆฌ DB๋กœ ๊ฒฉ๋ฆฌํ•˜์—ฌ ์‹คํ–‰ ์†๋„ ๋ณด์žฅ => Testcontainers ์‚ฌ์šฉ ์‹œ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์–ด ํ•„์ˆ˜์ ์ธ์ง€ ๊ณ ๋ฏผํ•ด์•ผ ํ•œ๋‹ค.
  1. ์ปจํ…Œ์ด๋„ˆ ํŒจํ‚ค์ง•
  • GitHub Hosted ๋Ÿฌ๋„ˆ์—์„œ ARM64 ํƒ€๊ฒŸ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ํšจ์œจ์„ฑ์„ ์œ„ํ•ด ARM64 ์ „์šฉ ๋Ÿฌ๋„ˆ ๋ผ๋ฒจ ์ง€์ •
  • Dockerfile์—์„œ ์†Œ์Šค ์ฝ”๋“œ ๋ณต์‚ฌ ์ „์— ํŒจํ‚ค์ง€ ์ •์˜ ํŒŒ์ผ์„ ์šฐ์„  ๋ณต์‚ฌ ๋ฐ ์˜์กด์„ฑ ์„ค์น˜ ๋ช…๋ น์–ด ๋ฐฐ์น˜(์˜์กด์„ฑ ๋ ˆ์ด์–ด ๋ถ„๋ฆฌ) => ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์ˆ˜์ •๋˜์–ด๋„ ๋ ˆ์ด์–ด ์บ์‹œ ์œ ์ง€ => v1์—์„œ ์‹ค์ œ๋กœ ์ ์šฉ๋จ
  • BuildKit cache mount๋Š” v1 ๋ฒ”์œ„์—์„œ ์ œ์™ธ => v1 ๊ทœ๋ชจ(์ ์€ CI ์‹คํ–‰ ๋นˆ๋„)์—์„œ๋Š” ๋นŒ๋“œ ์†๋„๊ฐ€ ์•„์ง ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จํ•ด, ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ถ•์†Œ์™€ ์˜์กด์„ฑ ๋ ˆ์ด์–ด ๋ถ„๋ฆฌ๋งŒ v1 ์ตœ์ ํ™” ๋Œ€์ƒ์œผ๋กœ ์ขํž˜
  1. ๋ณด์•ˆ ๊ฒ€์ฆ ๊ฒŒ์ดํŠธ
  • ๋นŒ๋“œ๋œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋Œ€์ƒ์œผ๋กœ Trivy ๋˜๋Š” Grype๋กœ OS ํŒจํ‚ค์ง€ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ทจ์•ฝ์  ๊ฒ€์‚ฌ => Trivy(์•ฝ 815์ดˆ, ์บ์‹œ ํ™œ์šฉ 1.2์ดˆ)์™€ Grype(์•ฝ 920์ดˆ, ์บ์‹œ ํ™œ์šฉ 0.7์ดˆ)๋Š” ๊ฒ€์ฆ ์‹œ๊ฐ„์— ์ฐจ์ด๊ฐ€ 30% ์ •๋„ ์žˆ์ง€๋งŒ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๊ฐ€ 150MB ์ •๋„๋กœ ์˜ˆ์ƒ๋˜๋Š” ํ˜„์žฌ ์ƒํ™ฉ์—์„œ๋Š” ํฐ ์ฐจ์ด๊ฐ€ ์—†๋‹ค. => ์ดˆ๊ธฐ ๊ตฌํ˜„ ๋‹จ๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— ํŒจํ‚ค์ง€ ์ทจ์•ฝ์ ๋งŒ ์ง‘์ค‘ ํƒ์ƒ‰ํ•˜๋Š” Grype ๋Œ€์‹  Trivy๋กœ ์„ค์ •, Secrets, IaC ํŒŒ์ผ ๋“ฑ์„ ํฌํ•จํ•˜์—ฌ ์ข…ํ•ฉ์ ์œผ๋กœ ๊ฒ€์‚ฌํ•œ๋‹ค.
  • CRITICAL ๋“ฑ๊ธ‰ ์ทจ์•ฝ์  ๋ฐœ๊ฒฌ ์‹œ ๋นŒ๋“œ ์‹คํŒจ ์ฒ˜๋ฆฌ => ์œ ์ €๊ฐ€ ์ œํ•œ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ฆ‰๊ฐ์ ์ธ ์กฐ์น˜๊ฐ€ ํ•„์š”ํ•œ ์ˆ˜์ค€์ด ์•„๋‹ˆ๋ฉด ๋‹ค์Œ ๋ฒ„์ „์— ๋ฐ˜์˜
  1. ์‚ฐ์ถœ๋ฌผ ์ €์žฅ
  • ๋ชจ๋“  ๊ฒ€์ฆ์ด ์™„๋ฃŒ๋œ ์ด๋ฏธ์ง€์— ํƒœ๊ทธ๋ฅผ ๋ถ€์—ฌํ•˜๊ณ  ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— Push

5. Docker Image ๊ด€๋ฆฌ ์ „๋žต

1) ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ

Important

3๊ฐœ์˜ Private ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์‚ฌ์šฉ ์‹œ, ๋น„์šฉ์ ์œผ๋กœ ์šฐ์ˆ˜ํ•˜๊ณ  github ์ƒํƒœ๊ณ„์˜ ํŽธ์˜์„ฑ์ด ๋†’์€ GHCR๋ฅผ ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

  • 3๊ฐœ์˜ Private ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํ™˜๊ฒฝ์—์„œ GHCR๋งŒ ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • CI/CD ๋‹จ๊ณ„์—์„œ Docker hub์™€ ECR, Google Artifact Registry๋Š” ๊ฐ๊ฐ ์‹œํฌ๋ฆฟ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ, GHCR๋Š” github์—์„œ ์ œ๊ณตํ•˜๋Š” ์ธ์ฆ ํ† ํฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ํŽธ๋ฆฌํ•˜๋‹ค.(${{ secrets.GITHUB_TOKEN }})

๋”ฐ๋ผ์„œ ๋น„์šฉ์ ์œผ๋กœ ์šฐ์ˆ˜ํ•˜๊ณ  ํŒ€์ด ์‚ฌ์šฉํ•˜๋Š” github ์ƒํƒœ๊ณ„(github repo, github actions) ๋‚ด์—์„œ ํŽธ์˜์„ฑ์ด ๋†’์€ GHCR๋ฅผ ์ปจํ…Œ์ด๋„ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

๋น„๊ต ํ•ญ๋ชฉ AWS ECR GitHub Packages (GHCR) Docker Hub Pro Google Artifact Registry
๊ธฐ๋ณธ ์Šคํ† ๋ฆฌ์ง€ ์š”๊ธˆ $0.10 / GB / ์›”
(์‹ ๊ทœ 1๋…„ 500MB ๋ฌด๋ฃŒ)
ํ˜„์žฌ ๋ฌด๋ฃŒ(currently free)

$0.25 / GB / ์›”
(Free 500MB, Team 2GB ๋ฌด๋ฃŒ)
์›” $15 ๊ณ ์ •
(๋ฌด์ œํ•œ Private Repo)
1๊ฐœ free
$0.10 / GiB / ์›”
(๊ณ„์ •๋‹น 0.5GiB ๋ฌด๋ฃŒ)

์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ •์ฑ…

  • ๊ฐ ์ฝ”๋“œ ์ €์žฅ์†Œ(ํ”„๋ก ํŠธ, ๋ฐฑ, AI)์— ๋Œ€ํ•ด ๊ฐ๊ฐ์˜ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ด ๊ด€๋ฆฌํ•œ๋‹ค.

2) Docker Image ์ •์ฑ…

docker image tag ์ •์ฑ…

Important

  • ๋ฐฐํฌ ์ด๋ฏธ์ง€(release ํƒœ๊ทธ v*.*.* push): Semantic Version(e.g. 1.0.0)๋งŒ ํƒœ๊ทธ๋กœ ์‚ฌ์šฉ
  • dev ์ด๋ฏธ์ง€(dev push): dev-<short SHA>, ์ตœ์‹  ๋ฒ„์ „์€ latest
  • latest๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์‹œ ํŽธ์˜๋ฅผ ์œ„ํ•œ ํฌ์ธํ„ฐ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.
  • dev์˜ commit SHA๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ์›๋ณธ ์ปค๋ฐ‹์„ ์ฐธ์กฐํ•˜๋Š” ๋ถˆ๋ณ€๊ฐ’์„ ํƒœ๊ทธ๋กœ ๋‹ฌ์•„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.
  • main์€ dev๋‚˜ hotfix์—์„œ๋งŒ ๋ณ‘ํ•ฉ๋˜๋ฏ€๋กœ, main์— push๋˜๋Š” ์ปค๋ฐ‹์€ ํ•ญ์ƒ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋งค๋ฒˆ Semantic Version ํƒœ๊ทธ๋ฅผ ๋ถ€์—ฌํ•˜๋ฉฐ, commit SHA๋Š” ํƒœ๊ทธ ๋Œ€์‹  ์•„๋ž˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— ๊ธฐ๋กํ•ด ์ถ”์ ํ•œ๋‹ค.
  • ์ด๋ฏธ์ง€ ๋นŒ๋“œ ํŠธ๋ฆฌ๊ฑฐ๋Š” main push(merge)๊ฐ€ ์•„๋‹Œ release ํƒœ๊ทธ(v*.*.*) push๋‹ค. ๋ฒ„์ „์„ ์ฝ”๋“œ ํŒŒ์ผ(package.json๋ฅ˜)๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ๋งค ๋ฐฐํฌ๋งˆ๋‹ค ๊ทธ ํŒŒ์ผ์„ ๊ณ ์น˜๋Š” PR์ด ๋ณ„๋„๋กœ ํ•„์š”ํ•˜์ง€๋งŒ, Git tag๋ฅผ ๋‹จ์ผ ์ง„์‹ค ๊ณต๊ธ‰์›์œผ๋กœ ์‚ผ์œผ๋ฉด ๊ทธ ์ ˆ์ฐจ๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.
  • ํƒœ๊ทธ๋Š” dev/hotfix -> main PR์„ mergeํ•œ ๋’ค GitHub Release๋ฅผ ์ƒ์„ฑ(Target: main, ํƒœ๊ทธ v1.0.1 ํ˜•์‹)ํ•ด pushํ•œ๋‹ค. main์œผ๋กœ merge๋งŒ ํ•ด์„œ๋Š” ์ด๋ฏธ์ง€๊ฐ€ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

Semantic Version ์ •์ฑ…

[!NOTICE] Semantic Version: MAJOR.MINOR.PATCH ์˜ˆ์‹œ: 1.0.1

  • MAJOR: ๊ธฐ์กด API์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๋ณ€๊ฒฝ
  • MINOR: ๊ธฐ์กด API์™€ ํ˜ธํ™˜๋˜๋ฉด์„œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋œ ๊ฒฝ์šฐ
  • PATCH: API/๊ธฐ๋Šฅ ๋ณ€ํ™” ์—†๋Š” ์‚ฌ์†Œํ•œ ์ˆ˜์ • (๋ฒ„๊ทธ ์ˆ˜์ •, ์„ฑ๋Šฅ ๊ฐœ์„  ๋“ฑ)

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ

  • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ: ์ด๋ฏธ์ง€ ๋ผ๋ฒจ์— ๋นŒ๋“œ ํƒ€์ž„์Šคํƒฌํ”„, ์ปค๋ฐ‹ ์ž‘์„ฑ์ž, Git SHA๋ฅผ OCI(Open Container Initiative) ํ‘œ์ค€์œผ๋กœ ์ฃผ์ž… => ์šด์˜ ํ™˜๊ฒฝ์—์„œ ์žฅ์•  ๋ฐœ์ƒ ์‹œ Git ๋กœ๊ทธ ์ถ”์  ์šฉ์ด => OCI ํ‘œ์ค€ ์‚ฌ์šฉ ์‹œ ๋ณด์•ˆ ์Šค์บ๋‹, CI/CD ๋„๊ตฌ๋“ค์ด ๋ณ„๋„ ์ถ”๊ฐ€ ์„ค์ •์ด๋‚˜ ์†์‹ค ์—†์ด ์ผ๊ด€๋˜๊ฒŒ ๋ถ„์„ ๊ฐ€๋Šฅ

main ๋ฐฐํฌ์‹œ Semantic Version ์ฑ…์ • ๊ทœ์น™

  • Semantic Version์€ ๋ฐฐํฌ๋งˆ๋‹ค MAJOR, MINOR, PATCH๋ฅผ ํ†ตํ‹€์–ด์„œ ์ˆซ์ž ํ•˜๋‚˜๋งŒ์„ ์˜ฌ๋ฆฐ๋‹ค. (e.g. 1.0.0 -> 1.0.1)
  • hotfix -> main (๊ธด๊ธ‰ ๋ฐฐํฌ): ํ•ญ์ƒ PATCH
  • dev -> main (์ •๊ธฐ ๋ฐฐํฌ): ๊ทธ ์ฃผ dev์— ์Œ“์ธ ๋ณ€๊ฒฝ ์ค‘ ๊ฐ€์žฅ ์˜ํ–ฅ๋„ ๋†’์€ ๋“ฑ๊ธ‰์œผ๋กœ ๊ฒฐ์ • (MAJOR > MINOR > PATCH ์šฐ์„ )

image ๊ฐœ์ˆ˜ ๊ด€๋ฆฌ ์ •์ฑ…

Important

  • ๋กค๋ฐฑ์„ ์œ„ํ•œ ์ตœ์‹  5๊ฐœ(์šด์˜ ๋ฒ„์ „์„ ํฌํ•จ)
  • ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ dev 2๊ฐœ
  • ๋กค๋ฐฑ์„ ์œ„ํ•œ ์ตœ์‹  5๊ฐœ(์šด์˜ ๋ฒ„์ „์„ ํฌํ•จ) - release ํƒœ๊ทธ push(๋ฐฐํฌ)๋งˆ๋‹ค FIFO๋กœ ๊ต์ฒด
    • ์ผ์ฃผ์ผ์— release ํƒœ๊ทธ push๋กœ ์ƒ์„ฑ๋˜๋Š” ์ด๋ฏธ์ง€์˜ ์ˆ˜๋Š” 3ํšŒ(ํ‰์ผ 2, ์ฃผ๋ง 1) ์ •๋„ ์˜ˆ์ƒ๋œ๋‹ค.
  • ํ…Œ์ŠคํŠธ์šฉ dev ์ด๋ฏธ์ง€ ์ตœ์‹  2๊ฐœ - dev push๋งˆ๋‹ค FIFO๋กœ ๊ต์ฒด, latest๋Š” ๊ทธ์ค‘ ์ตœ์‹  ๊ฒƒ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

6. ์‹คํŒจ ์ฒ˜๋ฆฌ ์ •์ฑ…

1) PR ๋‹จ๊ณ„ ์‹คํŒจ

  • PR์‹œ CI: ์ •์  ๋ถ„์„, ๋‹จ์œ„/์ „์ฒด ํ…Œ์ŠคํŠธ, ๋นŒ๋“œ, Docker Image ๋นŒ๋“œ
  • PR ๋‹จ๊ณ„ CI๊ฐ€ ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋งŒ ํ†ตํ•ฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ merge๋ฅผ ๋ง‰์Œ
  • ๋”ฐ๋กœ ์•Œ๋ฆผ์€ ๋ฐœ์†กํ•˜์ง€ ์•Š๊ณ  PR ์ž‘์„ฑ์ž๊ฐ€ ํ™•์ธ

2) dev push ์‹คํŒจ

  • dev push ์ดํ›„ CI: Docker Image ๋นŒ๋“œ, Docker Image push
  • dev push๊ฐ€ ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ, ์šด์˜์—๋Š” ์˜ํ–ฅ์ด ์—†์œผ๋‚˜ PR ๋‹จ๊ณ„์—์„œ Docker Image ๋นŒ๋“œ๋ฅผ ํ†ต๊ณผํ–ˆ์œผ๋ฏ€๋กœ, 1ํšŒ ์žฌ์‹œ๋„ ํ•˜๋ฉฐ ์‹คํŒจ ์‹œ ์›Œํฌํ”Œ๋กœ์šฐ ์ค‘๋‹จ
  • ์ดํ›„ ์ธํ”„๋ผ ๋‹ด๋‹น์ž(tobby/janna)๊ฐ€ ๋Œ€์‘ํ•œ๋‹ค.

3) release ํƒœ๊ทธ push ์ดํ›„ ์‹คํŒจ

  • release ํƒœ๊ทธ(v*.*.*) push ์ดํ›„ CI: ์ „์ฒด ํ…Œ์ŠคํŠธ, Docker Image ๋นŒ๋“œ, Docker Image push
  • release ํƒœ๊ทธ push ๋‹จ๊ณ„๊ฐ€ ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ, ํŒ€ ๋””์Šค์ฝ”๋“œ์— Webhook์œผ๋กœ CI ์‹คํŒจ ์•Œ๋ฆผ์„ ๋ณด๋‚ธ๋‹ค.
  • ์•Œ๋ฆผ์„ ํ™•์ธํ•œ ์ธํ”„๋ผ ๋‹ด๋‹น์ž(tobby/janna)๊ฐ€ ๋Œ€์‘ํ•œ๋‹ค.

release ํƒœ๊ทธ push ์‹คํŒจ ๋Œ€์‘ ์ •์ฑ…

  • release ํƒœ๊ทธ push๊ฐ€ ์‹คํŒจํ•ด๋„ ์‹ค์ œ ์ด๋ฏธ์ง€ registry์— push๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์šด์˜ ์„œ๋ฒ„์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค.(๋กค๋ฐฑ ํ•„์š” ์—†์Œ)
  • ์‹คํŒจ ์•Œ๋ฆผ์„ ๋ฐ›์€ ์ธํ”„๋ผ ๋‹ด๋‹น์ž๋Š” ๋กœ๊ทธ ํ™•์ธ ํ›„ ์›์ธ์„ ํŒŒ์•…ํ•˜์—ฌ ํ•ด๊ฒฐํ•œ ๋’ค, ํ•„์š”ํ•˜๋ฉด ํƒœ๊ทธ๋ฅผ ๋‹ค์‹œ pushํ•˜๊ฑฐ๋‚˜ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์žฌ์‹คํ–‰ํ•œ๋‹ค.
โš ๏ธ **GitHub.com Fallback** โš ๏ธ