Cloud Design 2nd - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki
Important
๋ชฉํ: ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ฅผ ์์ฃผ ํตํฉํ๋๋ผ๋ ์๋น์ค๊ฐ ํญ์ ์ธ์ ๋ '๋ฐฐํฌ ๊ฐ๋ฅํ ์ํ'๋ฅผ ์ ์งํ๋๋ก ์๋ํ๋ ํตํฉ ๊ณผ์ ์ ๊ตฌ์ถํ๋ค.
๋ฐฐํฌ ๊ฐ๋ฅํ ์ํ: ๋ธ๋์น์ ์ต์ ์ปค๋ฐ์ด ์ ์ ๋ถ์/ํ ์คํธ(๋จ์/์ ์ฒด)/๋น๋/Docker ์ด๋ฏธ์ง ๋น๋๊น์ง ๋ชจ๋ ํต๊ณผํด์, ๊ทธ๋๋ก ์ด์ ์๋ฒ์ ๋ฐฐํฌํด๋ ๋ฌธ์ ๊ฐ ์๋ ์ํ
์ฐ๋ฆฌ ํ์ ํ์ฌ ์๋น์ค ๊ฐ๋ฐ์ด ๋ณธ๊ฒฉํ๋๋ฉด์ ์ฝ๋ ๋ณ๊ฒฝ ๋ฐ ํตํฉ ๋น๋๊ฐ ๊ธ๊ฒฉํ ์ฆ๊ฐํ๊ณ ์๋ค.
-
๊ฐ๋ฐ ์ธ๋ ฅ ๊ตฌ์ฑ: ์ด 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
๊ฐ๋ฐ ์ธ์์ด ๊ฐ์์ ๋ก์ปฌ ํ๊ฒฝ์์ ์์ ํ๊ณ ์๋์ผ๋ก ์ฝ๋๋ฅผ ํตํฉํ๋ฉด์ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ํ์ฐ์ ์ผ๋ก ๋ฐ์ํ๋ค.
| ๋ฐ์ ๋ฌธ์ | ๊ตฌ์ฒด์ ์ธ ์์ธ ๋ฐ ์ํฅ |
|---|---|
| Merge ์ดํ ๋น๋ ์คํจ | ๋ก์ปฌ์์๋ ์ ์ ๋์ํ์ผ๋, ๋ค๋ฅธ ํ์์ ์ต์ ์ฝ๋์ ํตํฉ๋์์ ๋ ์์กด์ฑ ์ถฉ๋์ด๋ ์ปดํ์ผ ์ค๋ฅ ๋ฐ์ |
| ๋ฏธ๊ฒ์ฆ ์ฝ๋์ dev ๋ธ๋์น ์ ์ | ๋ฐ์ ๊ฐ๋ฐ ์ผ์ ์ผ๋ก ์ธํด ํ ์คํธ ์ฝ๋๋ฅผ ์คํํ์ง ์์ ์ํ์์ PR์ด ์น์ธ๋์ด dev์ Merge๋ ์ ์์ |
| ๊ฐ๋ฐ ํ๊ฒฝ ์ฐจ์ด๋ก ์ธํ ์ค๋ฅ | ์์กด์ฑ ๋ฒ์ ์ฐจ์ด ๋ฑ์ผ๋ก ๊ฐ๋ฐ์์ ๋ก์ปฌ PC์์๋ ์ ๋์๊ฐ๋๋ฐ ๋ฐฐํฌ ์๋ฒ์์๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ํ๊ฒฝ ๋ถ์ผ์น ๋ฌธ์ ๋ฐ์ |
| Docker Image ์๋ Build ์ค์ | ๋ด๋น์๊ฐ ๋ก์ปฌ์์ ์ด๋ฏธ์ง๋ฅผ ์๋ ๋น๋/ํธ์ํ ๊ฒฝ์ฐ ํ๊ทธ ์คํ, ํ์ ์ค์ ๋๋ฝ ๋ฑ์ผ๋ก ์๋ชป๋ ๋ฒ์ ์ด ์์ฑ๋ ์ํ |
| ์ปจํ ์ด๋ ์ด๋ฏธ์ง ์ทจ์ฝ์ ๋ฐ์ | ๋ด๋น์๊ฐ ์ด๋ฏธ์ง๋ฅผ ๋น๋ ์์ ๋น๋ฐ๊ฐ์ด ํฌํจ๋๋ ๋ฑ ์ด๋ฏธ์ง๋ก ์ธํด ์ทจ์ฝ์ ์ด ๋ฐ์ํ ์ ์์ |
Caution
์ฌ๋์ด ์๋์ผ๋ก ๊ฒ์ฆํ๊ณ ๋น๋ํ๋ ๋ฐฉ์์ Human Error๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฉฐ, ์ฝ๋ ํตํฉ ๋น๋๊ฐ ๋์ด๋ ์๋ก Main ๋ธ๋์น์ ์ ๋ขฐ์ฑ์ด ๊ธ๊ฒฉํ ๋จ์ด์ง๋ค.
๋จ์ํ ๋ฐฐํฌ ์คํฌ๋ฆฝํธ๋ฅผ ์ค์ด๋ ๊ฒ์ด ์๋๋ผ, ๋๊ฐ ์ฝ๋๋ฅผ ์์ฑํ๋ ์ผ๊ด๋ ๊ฒ์ฆ์ ๊ฑฐ์ณ ํญ์ ๋ฐฐํฌ ๊ฐ๋ฅํ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํด CI(์ง์์ ํตํฉ) ํ์ดํ๋ผ์ธ์ด ํ์ํ๋ค.
- Merge ํ ๋น๋ ์คํจ, ์ฝ๋ ์ค๋ฅ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, PR ์์ฒญ ์ ๊ฐ๋ฐ์๊ฐ ์ง์ ๋น๋ํ๊ณ ํ ์คํธํ ์ ์๋ค. ์ด๋ human error ๊ฐ๋ฅ์ฑ์ ๊ฐ์ง๋ค.
- ํ
์คํธ๋ฅผ ํต๊ณผํด์ผ๋ง Dev ๋ธ๋์น์ Merge๋๋ฉฐ, ํ
์คํธ๋ฅผ ํต๊ณผํ์ง ๋ชปํ ์ฝ๋๋ Dev ๋ธ๋์น๋ก Merge๋์ง ์๋๋ก ์ง์
์ ์ฐจ๋จํ์ฌ, Dev ๋ธ๋์น๋ฅผ ํญ์ ๋ก์ปฌ์์ ๊ฒ์ฆ ๊ฐ๋ฅํ๋ฉฐ ๋ฐฐํฌ ๊ฐ๋ฅํ ์ํ๋ก ์ ์งํ๋ค.
- ์ด์ ๋ฐฐํฌ ๊ฐ๋ฅ ์ฌ๋ถ๋ ์ดํ ์ ์ฒด ํ ์คํธ๋ฅผ ๊ฑฐ์น๋ main ์น๊ฒฉ ์์ ์ ํ์ ๋๋ค.
- ๋ธ๋์น ๋ฑ์ ๋ณํฉํ ๋ ํํ์ด ์ง์์ ์ผ๋ก ๊ฒ์ฆํ์ฌ ์ํํ ํ์ ์ ์ํ ํ๋์ ์๋จ์ด ๋๊ธฐ๋ ํ๋ค.
- ๊ฐ๋ฐ ํ๊ฒฝ ์ฐจ์ด๋ก ์ธํ ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ๊ฐ๋ฐ์์ ๋ก์ปฌ ๋จธ์ ์ค์ ์ ์์กดํ์ง ์๊ณ , ์ด์ ํ๊ฒฝ๊ณผ ๋์ผํ ํ๊ฒฝ์ ์ ๊ณตํ๋ ํ์คํ๋ CI ๋ฌ๋ ํ๊ฒฝ์ด ํ์ํ๋ค.
- Docker Image ์๋ ๋น๋ ์ค์๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋น๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฌธ์ํํ๊ณ ์ฒดํฌ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค์ด ํด๊ฒฐํ ์ ์์ผ๋ ์ด ๋ฐฉ๋ฒ๋ human error๋ฅผ ์์ฒ ์ฐจ๋จํ ์๋ ์๋ค.
- ๋ฐ๋ผ์ ์ฝ๋ ๊ฒ์ฆ์ ์ฑ๊ณตํ ์ปค๋ฐ์ ๋ํด์๋ง ์๋์ผ๋ก Docker ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ๊ณ ๋ ์ง์คํธ๋ฆฌ์ ํธ์ํ๋ ์ผ๊ด๋ ํ์ดํ๋ผ์ธ ํ๋ฆ์ด ํ์ํ๋ค.
CI ์ค๊ณ ์ ๊ธฐ์ค
- ๊ฐ๋ฐ ์์ CI ๊ฐ์ฉ์ฑ์ด ํ์ํจ: ๊ฐ๋ฐ์ ํ๋ฆ์ ๋ฐฉํดํ์ง ์์์ผ ํจ
- ์ถ๊ฐ ๋น์ฉ์ด ํฌ์ง ์์์ผ ํจ
Important
CI ๊ฐ์ฉ์ฑ์ด ์ ์ง๋๋ฉฐ, ํ์ฌ ํ์์ ๋ฌด๋ฃ ํ๋๋ก ์ฌ์ฉํ ์ ์๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ CI ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ค.
CI ํ๊ฒฝ์ ์๋ ์ธ ๊ฐ์ง๋ก ๋๋๋ค.
- ๋ก์ปฌ PC ์ปจํ
์ด๋
- ์ปดํจํฐ๊ฐ ์ฌ๋ถํ ๋๊ฑฐ๋ ์์ดํ์ด๊ฐ ๋๊ธฐ๋ฉด ๋ค๋ฅธ ํ์๋ค์ PR ๋น๋์ ํ ์คํธ๊ฐ ๋ฉ์ถค
- ํด๋ผ์ฐ๋ ์์ฒด ํธ์คํ
- CI ์๋ฒ ๊ฐ์ฉ์ฑ ์ ์ง๋ ๊ฐ๋ฅํ๋, EC2 ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํด ๋น์ฉ์ด ๋ฐ์
- ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ CI
- ์๋ฒ ๊ด๋ฆฌ๊ฐ ํ์์์ผ๋ฉฐ ๊ฐ์ฉ์ฑ์ด ์ ์ง๋๋ฉฐ, ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ฐ๋๋์์ ๋์๋ง ์๋ํจ
- ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์๋น์คํ๋ ๊ณณ๊ณผ ๊ฐ์ CI ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฐ๋์ฑ์ด ์ข์
- ์ฌ์ฉ๋์ ๋ฐ๋ฅธ ๋น์ฉ์ด ์ฒญ๊ตฌ๋์ง๋ง, ํ์ฌ ํ ์ํฉ์์๋ ๋ฌด๋ฃ ํ๋ ๋ด์์ CI ์์ ์ ํ ์ ์๋ค๊ณ ํ๋จ๋จ
๊ฐ์ฉ์ฑ ์ ์ง์ ๋น์ฉ์ ์ค์ด๋ ๊ธฐ์ค์ ์ํด, ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ 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
- ์ธ๊ฐ์ง ๋ชจ๋ ๊ฐ์ฉ์ฑ์ ์ถฉ์กฑํ๋ค.
- ์๊ฐ ์์ CI/CD ์๊ฐ์ ๊ณ ๋ คํ ๋น์ฉ๋ฉด์์๋ CircleCI, Google Cloud Build, Github Actions ๋ชจ๋ ๋์ผํ๊ฒ ๋ฌด๋ฃ๋ก ์ฌ์ฉํ ์ ์๋ค.
- ์ธ๊ฐ์ง ๋ชจ๋ ๋น์ฉ๋ฉด์์๋ ๋์ผํ๊ธฐ ๋๋ฌธ์, ํฐ ์ฐจ์ด๊ฐ ๋์ง ์์๋ค. ์ด๋, ์ด์์ ํธ์์ฑ ๋ถ๋ถ์ ๊ณ ๋ คํด 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/๋ถ |
๋ ํฌ์งํ ๋ฆฌ ์ ๋ต: ๋ฉํฐ ๋ ํฌ(ํ๋ก ํธ, ๋ฐฑ, 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์ผ๋ก ๋ณํฉํ๋ ์์ ๊ณผ ๋ฐฐํฌ์ฉ ์ด๋ฏธ์ง๋ฅผ ๋ง๋๋ ์์ ์ ์๋์ ์ผ๋ก ๋ถ๋ฆฌํ๊ธฐ ์ํจ์ด๋ค.
| 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 ๋ธ๋์น์๋ ์ด์ ์ค์ธ ์ฝ๋๊ฐ ์กด์ฌํ๋ฏ๋ก, ์ ๊ธฐ ๋ฐฐํฌ ์ด์ ๊น์ง ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์ง๊ณ ๊ฒ์ฆํ๊ธฐ ์ํจ์ด๋ค.
- Concurrency ์ ์ด
- ๋์ผ ๋ธ๋์น/PR์ ์ฐ์ Push ๋ฐ์ ์ ์งํ ์ค์ด๋ ์ด์ ์คํ ์๋ ์ทจ์ => GitHub Actions ํ ๋ญ๋น ๋ฐฉ์ง
- ๋ธ๋์น ๋ณดํธ
- main, dev ๋ธ๋์น์ Direct Push ์ฐจ๋จ
- ๋ฐ๋์ PR์ ๊ฑฐ์ณ์ผ ํ๋ฉฐ, ์ง์ ๋ CI ์ํฌํ๋ก์ฐ๊ฐ ์ฑ๊ณตํด์ผ Merge ๋ฒํผ ํ์ฑํ
์ ๊ธฐ ๋ฐฐํฌ ์ฃผ๊ธฐ(๋งค์ฃผ ์์์ผ ์ค์ 10์)์ ์์คํ ์ ์ง๋ณด์ ์ง์
- ์ ๊ธฐ ๋ฆด๋ฆฌ์ฆ ๋น๋ ๊ฒ์ฆ
- ๋งค์ฃผ ์์์ผ ์ค์ 8์ ์คํ
- ์ค์ 10์ ์ ๊ธฐ ๋ฐฐํฌ ์ ์ต์ข ๋ณํฉ๋ main ๋ธ๋์น์ ์ต์ ์ํ์ ๋ํด E2E ํ ์คํธ ๋ฐ ๋ฐฐํฌ ๋์ ์ด๋ฏธ์ง ํ๊ทธ ํ์
- ๋ณด์ ์ทจ์ฝ์ ์ฃผ๊ธฐ์ ์ค์บ
- ๋งค์ฃผ ์ผ์์ผ ์ค์ 3์ ์คํ
- ์๋ก์ด CVE ๋ฐ์ ์ฌ๋ถ ํ์ธ์ ์ํด ๋ฒ ์ด์ค ์ด๋ฏธ์ง ๋ฐ ์ข
์์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ์ฌ๊ฒ์ฌ
=> ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ๊ท ์ทจ์ฝ์ ์ด๋ ์์กด์ฑ ์ํํธ์จ์ด ๋
ธํํ ํ์ง
- ์ ๋ฐ์ดํธ๊ฐ ์์ฃผ ์๋ ํ๋ก์ ํธ๋ฉด ํ์ํ์ง๋ง ์ฐ๋ฆฌ ํ๋ก์ ํธ๋ ์ต์ 3์ผ 1ํ CI ์์คํ ์ด ๋์ํ ๊ฒ์ด๊ณ ์ฃผ 1ํ ์ ๋ฐ์ดํธ๊ฐ ์์ด ํ์์ ์ด์ง ์๋ค.
์ด๋ฏธ์ง ํฌ๊ธฐ ๋ค์ด์ดํธ
- Multi-stage build๋ก ๋น๋ ๋๊ตฌ๋ฅผ ์ต์ข ๋ฐํ์ ์ด๋ฏธ์ง์์ ์ ์ธ
- ๊ฒฝ๋ ๋ฒ ์ด์ค ์ด๋ฏธ์ง ์ฑํ(alpine, slim)
[!NOTICE] GitHub Actions์ private ๋ ํฌ๋ GitHub-hosted ๋ฌ๋์ ์๋ณ 2,000๋ถ๊ณผ ์คํ ๋ฆฌ์ง๋ ๋ฌด๋ฃ๋ค. => ๋ถํ์ํ ์์ ์ ์ต์ํํ์ฌ ์๊ฐ๊ณผ ๋ฆฌ์์ค๋ฅผ ์ ์ฝํด์ผ ํ๋ค.
- ์ฝ๋ ํ์ง ๊ฒ์ฆ
- 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 ์ฐจ์ด๋ก ์ธํด ์ค๋ฐ๊ฟ์ด๋ ๋ค์ฌ์ฐ๊ธฐ ๋ถ์ผ์น ๋ฐฉ์ง
- ๋น๋ ๋ฐ ๊ฒฉ๋ฆฌ ํ ์คํธ
- ์ข ์์ฑ ์บ์ฑ ํ์ฉ(Gradle, pip, npm/pnpm ์บ์)
- ์ธ๋ถ ์์กด์ฑ(DB) ์์ด ํต๊ณผ ๊ฐ๋ฅํ ๋จ์ ํ ์คํธ ์์ฃผ ์คํ => DB ์ฐ๋ ํ ์คํธ ํ์ ์ Testcontainers ๋๋ ๊ฒฝ๋ H2/์ธ๋ฉ๋ชจ๋ฆฌ DB๋ก ๊ฒฉ๋ฆฌํ์ฌ ์คํ ์๋ ๋ณด์ฅ => Testcontainers ์ฌ์ฉ ์ ๋ฆฌ์์ค ๋ญ๋น๋ก ์ด์ด์ง ์ ์์ด ํ์์ ์ธ์ง ๊ณ ๋ฏผํด์ผ ํ๋ค.
- ์ปจํ ์ด๋ ํจํค์ง
- GitHub Hosted ๋ฌ๋์์ ARM64 ํ๊ฒ ์ด๋ฏธ์ง ์์ฑ ํจ์จ์ฑ์ ์ํด ARM64 ์ ์ฉ ๋ฌ๋ ๋ผ๋ฒจ ์ง์
- Dockerfile์์ ์์ค ์ฝ๋ ๋ณต์ฌ ์ ์ ํจํค์ง ์ ์ ํ์ผ์ ์ฐ์ ๋ณต์ฌ ๋ฐ ์์กด์ฑ ์ค์น ๋ช ๋ น์ด ๋ฐฐ์น(์์กด์ฑ ๋ ์ด์ด ๋ถ๋ฆฌ) => ์์ค ์ฝ๋๊ฐ ์์ ๋์ด๋ ๋ ์ด์ด ์บ์ ์ ์ง => v1์์ ์ค์ ๋ก ์ ์ฉ๋จ
- BuildKit cache mount๋ v1 ๋ฒ์์์ ์ ์ธ => v1 ๊ท๋ชจ(์ ์ CI ์คํ ๋น๋)์์๋ ๋น๋ ์๋๊ฐ ์์ง ๋ฌธ์ ๊ฐ ์๋๋ผ๊ณ ํ๋จํด, ์ด๋ฏธ์ง ํฌ๊ธฐ ์ถ์์ ์์กด์ฑ ๋ ์ด์ด ๋ถ๋ฆฌ๋ง v1 ์ต์ ํ ๋์์ผ๋ก ์ขํ
- ๋ณด์ ๊ฒ์ฆ ๊ฒ์ดํธ
- ๋น๋๋ ์ปจํ
์ด๋ ์ด๋ฏธ์ง๋ฅผ ๋์์ผ๋ก Trivy ๋๋ Grype๋ก OS ํจํค์ง ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ทจ์ฝ์ ๊ฒ์ฌ
=> Trivy(์ฝ 8
15์ด, ์บ์ ํ์ฉ 1.2์ด)์ Grype(์ฝ 920์ด, ์บ์ ํ์ฉ 0.7์ด)๋ ๊ฒ์ฆ ์๊ฐ์ ์ฐจ์ด๊ฐ 30% ์ ๋ ์์ง๋ง ์ด๋ฏธ์ง ํฌ๊ธฐ๊ฐ 150MB ์ ๋๋ก ์์๋๋ ํ์ฌ ์ํฉ์์๋ ํฐ ์ฐจ์ด๊ฐ ์๋ค. => ์ด๊ธฐ ๊ตฌํ ๋จ๊ณ์ด๊ธฐ ๋๋ฌธ์ ํจํค์ง ์ทจ์ฝ์ ๋ง ์ง์ค ํ์ํ๋ Grype ๋์ Trivy๋ก ์ค์ , Secrets, IaC ํ์ผ ๋ฑ์ ํฌํจํ์ฌ ์ข ํฉ์ ์ผ๋ก ๊ฒ์ฌํ๋ค. - CRITICAL ๋ฑ๊ธ ์ทจ์ฝ์ ๋ฐ๊ฒฌ ์ ๋น๋ ์คํจ ์ฒ๋ฆฌ => ์ ์ ๊ฐ ์ ํ์ ์ด๊ธฐ ๋๋ฌธ์ ์ฆ๊ฐ์ ์ธ ์กฐ์น๊ฐ ํ์ํ ์์ค์ด ์๋๋ฉด ๋ค์ ๋ฒ์ ์ ๋ฐ์
- ์ฐ์ถ๋ฌผ ์ ์ฅ
- ๋ชจ๋ ๊ฒ์ฆ์ด ์๋ฃ๋ ์ด๋ฏธ์ง์ ํ๊ทธ๋ฅผ ๋ถ์ฌํ๊ณ ๋ ์ง์คํธ๋ฆฌ์ Push
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)์ ๋ํด ๊ฐ๊ฐ์ ์ปจํ ์ด๋ ์ด๋ฏธ์ง ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ์์ฑํด ๊ด๋ฆฌํ๋ค.
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๋ง ํด์๋ ์ด๋ฏธ์ง๊ฐ ๋ง๋ค์ด์ง์ง ์๋๋ค.
[!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 ์ฐ์ )
Important
- ๋กค๋ฐฑ์ ์ํ ์ต์ 5๊ฐ(์ด์ ๋ฒ์ ์ ํฌํจ)
- ํ ์คํธ๋ฅผ ์ํ dev 2๊ฐ
- ๋กค๋ฐฑ์ ์ํ ์ต์ 5๊ฐ(์ด์ ๋ฒ์ ์ ํฌํจ) - release ํ๊ทธ push(๋ฐฐํฌ)๋ง๋ค FIFO๋ก ๊ต์ฒด
- ์ผ์ฃผ์ผ์ release ํ๊ทธ push๋ก ์์ฑ๋๋ ์ด๋ฏธ์ง์ ์๋ 3ํ(ํ์ผ 2, ์ฃผ๋ง 1) ์ ๋ ์์๋๋ค.
- ํ ์คํธ์ฉ dev ์ด๋ฏธ์ง ์ต์ 2๊ฐ - dev push๋ง๋ค FIFO๋ก ๊ต์ฒด, latest๋ ๊ทธ์ค ์ต์ ๊ฒ์ ๊ฐ๋ฆฌํจ๋ค.
- PR์ CI: ์ ์ ๋ถ์, ๋จ์/์ ์ฒด ํ ์คํธ, ๋น๋, Docker Image ๋น๋
- PR ๋จ๊ณ CI๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ, ๋ฐฐํฌ ๊ฐ๋ฅํ ์ฝ๋๋ง ํตํฉํด์ผ ํ๋ฏ๋ก merge๋ฅผ ๋ง์
- ๋ฐ๋ก ์๋ฆผ์ ๋ฐ์กํ์ง ์๊ณ PR ์์ฑ์๊ฐ ํ์ธ
- dev push ์ดํ CI: Docker Image ๋น๋, Docker Image push
- dev push๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ, ์ด์์๋ ์ํฅ์ด ์์ผ๋ PR ๋จ๊ณ์์ Docker Image ๋น๋๋ฅผ ํต๊ณผํ์ผ๋ฏ๋ก, 1ํ ์ฌ์๋ ํ๋ฉฐ ์คํจ ์ ์ํฌํ๋ก์ฐ ์ค๋จ
- ์ดํ ์ธํ๋ผ ๋ด๋น์(tobby/janna)๊ฐ ๋์ํ๋ค.
- release ํ๊ทธ(
v*.*.*) push ์ดํ CI: ์ ์ฒด ํ ์คํธ, Docker Image ๋น๋, Docker Image push - release ํ๊ทธ push ๋จ๊ณ๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ, ํ ๋์ค์ฝ๋์ Webhook์ผ๋ก CI ์คํจ ์๋ฆผ์ ๋ณด๋ธ๋ค.
- ์๋ฆผ์ ํ์ธํ ์ธํ๋ผ ๋ด๋น์(tobby/janna)๊ฐ ๋์ํ๋ค.
release ํ๊ทธ push ์คํจ ๋์ ์ ์ฑ
- release ํ๊ทธ push๊ฐ ์คํจํด๋ ์ค์ ์ด๋ฏธ์ง registry์ push๋์ง ์์ผ๋ฏ๋ก ์ด์ ์๋ฒ์๋ ๋ฌธ์ ๊ฐ ์๋ค.(๋กค๋ฐฑ ํ์ ์์)
- ์คํจ ์๋ฆผ์ ๋ฐ์ ์ธํ๋ผ ๋ด๋น์๋ ๋ก๊ทธ ํ์ธ ํ ์์ธ์ ํ์ ํ์ฌ ํด๊ฒฐํ ๋ค, ํ์ํ๋ฉด ํ๊ทธ๋ฅผ ๋ค์ pushํ๊ฑฐ๋ ์ํฌํ๋ก์ฐ๋ฅผ ์ฌ์คํํ๋ค.