๐จ๏ธ CI/CD
๐ CI/CD์ ๊ฐ๋ ์ ์ดํดํ๊ณ , ์ด๋ฅผ ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํ์ฌ ์๋ํ๋ ๋น๋, ํ ์คํธ, ๋ฐฐํฌ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด๊ฒ ์ต๋๋ค.
- CI/CD์ ๊ธฐ๋ณธ ๊ฐ๋
- CI์ CD์ ์ ์์ ๋ชฉ์ ์ ์ดํดํฉ๋๋ค.
- CI/CD๋ฅผ ๋์ ํจ์ผ๋ก์จ ์ป์ ์ ์๋ ์ฅ์ ์ ํ์ตํฉ๋๋ค.
- CI/CD ๋๊ตฌ ์๊ฐ
- ๋ค์ํ CI/CD ๋๊ตฌ๋ค(GitHub Actions, Jenkins, GitLab CI ๋ฑ)์ ํน์ง๊ณผ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์์๋ด ๋๋ค.
- GitLab๋ฅผ ์ด์ฉํ CI/CD ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
- GitLab์ ์ค์ ํ์ผ ์์ฑ ๋ฐฉ๋ฒ์ ์ตํ๊ณ , ์ด๋ฅผ ํ์ฉํ์ฌ ์๋ํ๋ ๋น๋ ๋ฐ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํฉ๋๋ค.
- ๋ฐฐํฌ ์๋ํ
- AWS์ ๊ฐ์ ํด๋ผ์ฐ๋ ํ๋ซํผ์ ์ด์ฉํ์ฌ CI/CD ํ์ดํ๋ผ์ธ์ ๋ฐฐํฌ ๋จ๊ณ๋ฅผ ์๋ํํ๋ ๋ฐฉ๋ฒ์ ํ์ตํฉ๋๋ค.
CI/CD ๊ฐ์
CI/CD๋?
- CI (Continuous Integration)
- CI๋ ๊ฐ๋ฐ์๊ฐ ๋ณ๊ฒฝํ ์ฝ๋๋ฅผ ์์ฃผ ํตํฉํ๊ณ , ์ด ์ฝ๋๊ฐ ์ ์ฒด ์์คํ ๊ณผ ์ ์ด์ฐ๋ฌ์ง๋์ง ์๋์ผ๋ก ํ ์คํธํ๋ ํ๋ก์ธ์ค์ ๋๋ค.
- ์ฝ๋ ๋ณ๊ฒฝ์ด ๋ฐ์ํ ๋๋ง๋ค ๋น๋ ๋ฐ ํ ์คํธ๋ฅผ ์ํํ์ฌ ์ฝ๋ ํ์ง์ ์ ์งํ๊ณ ๋ฌธ์ ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
- CD (Continuous Delivery)
- CD๋ CI์ ๊ฒฐ๊ณผ๋ฌผ์ ์ฌ์ฉ์์๊ฒ ์๋์ผ๋ก ๋ฐฐํฌํ๋ ํ๋ก์ธ์ค๋ฅผ ํฌํจํฉ๋๋ค. ์ฝ๋ ๋ณ๊ฒฝ์ด ํตํฉ๋๊ณ ํ ์คํธ๋ฅผ ํต๊ณผํ๋ฉด, ์ด๋ฅผ ์๋์ผ๋ก ์คํ ์ด์ง ํ๊ฒฝ ๋๋ ํ๋ก๋์ ํ๊ฒฝ์ ๋ฐฐํฌํฉ๋๋ค.
- ์ง์์ ์ธ ๋ฐฐํฌ(Continuous Deployment)๋ CI/CD์ ํ์ฅ ๊ฐ๋ ์ผ๋ก, ์น์ธ ์ ์ฐจ ์์ด ์๋์ผ๋ก ํ๋ก๋์ ํ๊ฒฝ์ ๋ฐฐํฌํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
CI/CD์ ์ฅ์
- ๋น ๋ฅธ ํผ๋๋ฐฑ
- ์ฝ๋ ๋ณ๊ฒฝ ํ ์ฆ๊ฐ์ ์ธ ๋น๋ ๋ฐ ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ด, ๊ฐ๋ฐ์๊ฐ ๋ฌธ์ ๋ฅผ ๋น ๋ฅด๊ฒ ์ธ์งํ๊ณ ์์ ํ ์ ์์ต๋๋ค.
- ์๋ํ๋ ํ๋ก์ธ์ค
- ๋น๋, ํ ์คํธ, ๋ฐฐํฌ ๊ณผ์ ์ด ์๋ํ๋์ด ์๋ ์์ ์ ์ค์ด๊ณ , ์ธ์ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
- ์ผ๊ด๋ ๋ฐฐํฌ
- ๋์ผํ ๋ฐฐํฌ ํ๋ก์ธ์ค๋ฅผ ํตํด ๋ชจ๋ ํ๊ฒฝ(๊ฐ๋ฐ, ํ ์คํธ, ์คํ ์ด์ง, ํ๋ก๋์ )์์ ์ผ๊ด๋ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฅํฉ๋๋ค.
- ๋์ ํ์ง ์ ์ง
- ์ฝ๋ ํ์ง์ ์ง์์ ์ผ๋ก ๊ฒ์ฆํ๊ณ , ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ์ฌ ํ์ง์ ์ ์งํ ์ ์์ต๋๋ค.
- ๊ฐ๋ฐ ์๋ ํฅ์
- ์๋ํ๋ ํ์ดํ๋ผ์ธ์ ํตํด ๊ฐ๋ฐ ์ฃผ๊ธฐ๋ฅผ ๋จ์ถํ๊ณ , ์๋ก์ด ๊ธฐ๋ฅ์ ๋น ๋ฅด๊ฒ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํ ์ ์์ต๋๋ค.
CI/CD ๋๊ตฌ
GitHub Actions
- GitHub Actions๋ GitHub ์ ์ฅ์์ ์ง์ ํตํฉ๋์ด ์๋ CI/CD ๋๊ตฌ๋ก, YAML ํ์ผ์ ์ฌ์ฉํ์ฌ ์ํฌํ๋ก์ฐ๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
- ํน์ง
- GitHub ์ ์ฅ์์์ ๊ฐ๋ ฅํ ํตํฉ
- ๋ค์ํ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํธ๋ฆฌ๊ฑฐ
- ํ๋ถํ ์ปค๋ฎค๋ํฐ ๋ฐ Marketplace ์ง์
- ๋ฌด๋ฃ ์ฌ์ฉ ๊ฐ๋ฅ (์ ํ๋ ๋ฐํ์ ์ ๊ณต)
Jenkins
- Jenkins๋ ์คํ ์์ค CI/CD ๋๊ตฌ๋ก, ํ๋ฌ๊ทธ์ธ์ ํตํด ๋ค์ํ ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์์ต๋๋ค.
- ํน์ง
- ๋์ ์ปค์คํฐ๋ง์ด์ง ๊ฐ๋ฅ
- ๋ค์ํ ํ๋ฌ๊ทธ์ธ ์ง์
- ๋ถ์ฐ ๋น๋ ๋ฐ ๋ค์ค ํ๋ซํผ ์ง์
- ๋๊ท๋ชจ ํ๋ก์ ํธ์ ์ ํฉ
GitLab CI
- GitLab CI๋ GitLab๊ณผ ํตํฉ๋ CI/CD ๋๊ตฌ๋ก, GitLab ์ ์ฅ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก CI/CD ํ์ดํ๋ผ์ธ์ ์ค์ ํ ์ ์์ต๋๋ค.
- ํน์ง
- GitLab๊ณผ์ ํตํฉ
- ๊ฐ๋ ฅํ ํ์ดํ๋ผ์ธ ํธ์ง๊ธฐ ์ ๊ณต
- ์๋ํ๋ DevOps ์๋ช ์ฃผ๊ธฐ ๊ด๋ฆฌ
- ํด๋ผ์ฐ๋ ๋ฐ ์จํ๋ ๋ฏธ์ค ๋ชจ๋ ์ง์
๐จ๏ธ Amazon ECS
Amazon ECS ๊ฐ์
Amazon ECS๋?
- AWS Elastic Container Service๋ docker ์ ํ๋ฆฌ์ผ์ด์
์ ์ฝ๊ฒ ๋ฐฐํฌํ๊ณ ์ด์ํ ์ ์๋๋ก ์ง์ํ๋ ์์ ๊ด๋ฆฌํ Container Orchestration ์๋น์ค
- ์ปจํ ์ด๋ ์ค์ผ์คํธ๋ ์ด์ (Container Orchestration): ์์ญ~์๋ฐฑ ๊ฐ์ ๋์ปค ์ปจํ ์ด๋๋ค์ด ๋ฌธ์ ์์ด ๋์๊ฐ๋๋ก, ์ค์ผ์คํธ๋ผ ์งํ์์ฒ๋ผ ์๋์ผ๋ก ๋ฐฐํฌ, ๋ณต๊ตฌ, ํ์ฅ(Scaling)์ ์ด๊ด ์งํํ๋ ๊ด๋ฆฌ ์์คํ ์ ๋๋ค.
- Kubernetes์ ๊ฐ์ container Orchestration ์๋น์ค
- Kubernetes ๋ณด๋ค ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ , ๋น์ฉ์ ์ผ๋ก๋ ์ ๋ ดํ๊ธฐ ๋๋ฌธ์ ์/์ค ๊ท๋ชจ์ ํ๋ก์ ํธ์ ๋๋ฆฌ ์ฌ์ฉ
- serverless๋ก ๊ตฌ์ฑํ ์ ์๋๋ฐ, ์ด๋ ๊ฒ ํ๋ฉด ์ธ์คํด์ค(๊ฐ์ฑ์๋ฒ)๋ฅผ ๊ตฌ์ฑํ๊ณ ๊ด๋ฆฌํ ํ์๋ ์์
- ์๋ฒ๋ฆฌ์ค (Serverless): ์๋ฒ๊ฐ ์์ ์๋ค๋ ๋ป์ด ์๋๋ผ, ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ฐ์ ์๋ฒ(EC2 ๋ฑ)๋ฅผ ์ธํ ํ๊ณ ๊ด๋ฆฌํ๋ ๊ท์ฐฎ์ ์์ ์์ด ํด๋ผ์ฐ๋(AWS)๊ฐ ์์์ ์๋ฒ ์ธํ๋ผ๋ฅผ ๋์์ฃผ๋ ๊ธฐ์
๊ตฌ์กฐ
- ECS๋ ํฌ๊ฒ ECR, ECS Cluster, ECS Service, ECS Task๋ก ์ด๋ฃจ์ด์ง๋๋ค.
- ECR: Docker image ์ ์ฅ์
- ECS Cluster: ์ปจํ ์ด๋๋ฅผ ์คํํ๊ธฐ ์ํ Cluster๋ก ์ฌ๋ฌ ์ธ์คํด์ค๋ก ์ด๋ฃจ์ด์ง๋๋ค. ์ด ์ธ์คํด์ค์ Docker container๊ฐ ๋ถ์ฐ ์คํ๋ฉ๋๋ค. Serverless๋ก ํ ๊ฒฝ์ฐ์๋ ์ธ์คํด์ค๋ ํ์๊ฐ ์์ต๋๋ค.
- ECS Server: Docker ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํ ๊ทธ๋ฃน์ ๋๋ค.
- ECS Task: ECS Server์ ์ค์ ๋ก ์คํ๋๋ docker container๋ค์ Task ๋ผ๊ณ ํฉ๋๋ค.
- ๋ก๋๋ฐธ๋ฐ์์, ๋ชจ๋ํฐ๋ง, Auto Scaling ๋ฑ์ ์์๋ ์์. ECS๋ฅผ ์ด์ฉํ๋ฉด ์ด๋ฐ ์์๋ค๊น์ง ์๋์ผ๋ก ๊ด๋ฆฌ
๐ ECS ์ปจํ ์ด๋ ์คํ ๋ฐฉ์ (EC2 vs Fargate) ์๋ฒฝ ์์ฝ
- ์ธ์คํด์ค(EC2) ์ง์ ๊ด๋ฆฌ
- ๊ฐ๋ : ๊ฐ์ ์๋ฒ์ ์ด์์ฒด์ (OS), ๋ณด์, ๋คํธ์ํฌ ๋ฑ ๊ธฐ๋ฐ ์ธํ๋ผ ์ ์ฒด๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ํต์ ํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐฉ์์ ๋๋ค.
- ๋น์ : "์์ธ ๋ด๊ณ ํต์งธ๋ก ๋น๋ฆฐ ๋ด ์๊ฐ." ์ง์ ์ฒญ์/๊ด๋ฆฌํด์ผ ํ์ง๋ง ๋ด ๋ง๋๋ก ๊ฐ์กฐํ ์ ์๊ณ , 24์๊ฐ ๋ด๋ด ์ฅ์ฌํ ๋๋ ๊ฐ์ฑ๋น๊ฐ ์ข์ต๋๋ค. (๋๊ท๋ชจ/๊ณ ์ ํธ๋ํฝ์ฉ)
- ์๋ฒ๋ฆฌ์ค(Fargate) ๋ฐฉ์
- ๊ฐ๋ : ๊ท์ฐฎ์ ์ธํ๋ผ ๊ด๋ฆฌ๋ AWS์ ์ ๋ฉด ์์ํ๊ณ , ๊ฐ๋ฐ์๋ ์ค์ง '๋์ปค ์ปจํ ์ด๋(์ฑ) ์คํ' ์์ฒด์๋ง ์ง์คํ๋ ๋ฐฉ์์ ๋๋ค.
- ๋น์ : "ํ์ํ ๋๋ง ๋น๋ ค ์ฐ๋ ํ๋ฆฌ๋ฏธ์ ๊ณต์ ์คํผ์ค." ๊ด๋ฆฌํด ์ฃผ๋ ์ง์์ด ์์ด ๊ฐ๋ฐ์๋ง ์ง์คํ ์ ์์ง๋ง, ์ฅ๊ธฐ๊ฐ ํ๊ฐ๋ํ๋ฉด ์๊ธ์ด ๋น์๋๋ค. (์๊ท๋ชจ/๋ณ๋์ฑ ํธ๋ํฝ์ฉ)

- Task definition
- ECS์ ์ต์ ์คํ๋จ์๋ “Task”
- “Service”๋ Task๊ฐ ๋ ๊ฐ ์ด์ ๋ชจ์ธ ๊ฒ
- Task๋ docker ์ ํ๋ฆฌ์ผ์ด์
- ์ด๋ ํฌํธ์์ ๋ช ๊ฐ์ ๋์ปค ์ปจํ ์ด๋๋ฅผ ์ด๋ค ์ด๋ฏธ์ง๋ก ์คํํ ์ง ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์ ๋ณด๊ฐ ํ์ํจ.
- ์ด ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์๋ ๊ฒ์ด Task definition

๐จ๏ธ ์ค์ต ๊ฐ์
- Gitlab์ ์ฌ์ฉํ์ฌ CI/CD๋ฅผ ์ค์ตํฉ๋๋ค.
- Gitlab ํ์ดํ๋ผ์ธ์์ build๋ฅผ ์ํํ์ฌ AWS ECR์ ๋์ปค ์ด๋ฏธ์ง๋ฅผ ๋ฑ๋กํ๊ณ ํ์ดํ๋ผ์ธ์ deploy์์ ECS์ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌ ํฉ๋๋ค.
๐จ๏ธ GitLab
์๊ฐ
- GitLab์ ์ด์ฉํด์ CI/CD ํ๊ฒฝ์ ๊ตฌ์ถํ๊ณ CI ๊ณผ์ ์ ์๋ํ ํฉ๋๋ค.
- GitLab ํ๋ก์ ํธ๋ฅผ ๋ง๋ค๊ณ ์ฌ๊ธฐ์ ๊ฐ๋ฐํ ์ฝ๋๋ฅผ PUSH ํฉ๋๋ค.
- ๊ทธ๋ฌ๋ฉด GitLab์ ์ฝ๋ Push๊ฐ ๋ ๊ฒ์ ํ์ธํ๊ณ Docker Image๋ฅผ ์์ฑ ECR์ ๋ฑ๋กํฉ๋๋ค.
- ์ด Docker Image๋ก๋ถํฐ docker container๋ฅผ ECS์ ์คํํ๊ฒ ๋ฉ๋๋ค.

GitLab ๊ฐ์ ๋ฐ ๊ทธ๋ฃน, ํ๋ก์ ํธ ์์ฑ
- GitLab ์ฌ์ดํธ์ ๊ฐ์
- https://about.gitlab.com/ ํ์ด์ง์์ gitlab ์๋น์ค์ ๊ฐ์ ์ ํฉ๋๋ค.
- GitLab์ ๊ทธ๋ฃน์ ์์ฑํ๊ณ ๋ธ๋ญํฌ ํ๋ก์ ํธ๋ฅผ ์์ฑ


spring ํ๋ก์ ํธ ์์ฑ ๋ฐ ์ค๋น(GtiLab ์ฐ๋)
์คํ๋ง ํ๋ก์ ํธ๋ฅผ ์์ฑํ์ฌ IDE์์ ์ด๊ณ GitLab๊ณผ ์ฐ๋ํฉ๋๋ค.
- ์คํ๋ง ํ๋ก์ ํธ ์์ฑ

- Gitlab ํ๋ก์ ํธ์ ๋ค์ด๊ฐ์ Code ๋ฒํผ์ ํด๋ฆญํ์ฌ Clone with HTTPS ์์ ํ ์คํธ๋ฅผ ๋ณต์ฌ

- ํ๋ก์ ํธ ์ฐ๋ ์๊ฒฉ ์ ์ URL์ ์์ ์ฃผ์๋ฅผ ๋ถ์ฌ ๋ฃ์ต๋๋ค.




- ํ๋ก์ ํธ๋ฅผ ํํฉ๋๋ค. ๋ง์ฝ ํ์ ํด๋ฆญํ์ฌ ๋์จ ์ฐฝ์ main ์ด๋ผ๋ ๋ธ๋์น๊ฐ ์ ๋์จ๋ค๋ฉด IDE๋ฅผ ์ข ๋ฃํ๊ณ ๋ค์ ์คํํฉ๋๋ค.


- ํ๋ก์ ํธ์ ์ปจํธ๋กค๋ฌ๋ฅผ ์์ฑํฉ๋๋ค. (src/main/java/com/spring/sample/SampleController.java)
package com.spring.sample;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SampleController {
@GetMapping("/sample")
public String sample() {
return "Hello World";
}
}
- application.properties๋ฅผ ์์ ํฉ๋๋ค. (src/main/resources/application.properties)
spring.application.name=sample
server.port=8080
- ๋ฃจํธ์ Dockerfile์ ์์ฑํฉ๋๋ค. (Dockerfile)
FROM openjdk:17-jdk-slim
VOLUME /tmp
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
๐จ๏ธ AWS ๋ณด์๊ทธ๋ฃน ์ถ๊ฐ
๐ ์ธ๋ถ์์ ์ปจํ ์ด๋์ ์ ์ํ ์ ์๋๋ก ํฌํธ์ ์ด์ด์ค๋๋ค.
- EC2 ํ์ด์ง์ ์ ๊ทผํ์ฌ ๋ณด์ ๊ทธ๋ฃน์ ํด๋ฆญํฉ๋๋ค.

- ์์ฑ๋์ด ์๋ ๋ณด์ ๊ทธ๋ฃน์ ์์ด๋๋ฅผ ํด๋ฆญํฉ๋๋ค.

- ์ธ๋ฐ์ด๋ ๊ท์น ํธ์ง์ ํด๋ฆญํ๊ณ 8080ํฌํธ์ 80 ํฌํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
- ๋ ํฌํธ ๋ชจ๋ 0.0.0.0/0 ์ ์ ๋ ฅํด์ค๋๋ค.


๐ก๏ธ AWS ์ธ๋ฐ์ด๋ ๊ท์น ์ค์ (ํฌํธ์ 0.0.0.0/0) ํต์ฌ ์์ฝ
- 80๊ณผ 8080 ํฌํธ๋ฅผ ์ฌ๋ ์ด์ : 80๋ฒ ํฌํธ๋ ์ผ๋ฐ์ ์ธ ์ธํฐ๋ท ์น(HTTP) ์ ์์ ์ํ '๊ธฐ๋ณธ ๋๋ฌธ'์ด๊ณ , 8080๋ฒ ํฌํธ๋ ์ฐ๋ฆฌ๊ฐ ๋ง๋ ์คํ๋ง ๋ถํธ ์๋ฒ๊ฐ ์๋์ ๊ธฐ๋ค๋ฆฌ๋ '์ ์ฉ ๋ฐฉ๋ฌธ'์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
- 0.0.0.0/0์ ์ง์ง ์๋ฏธ (์์ ๊ฐ๋ฐฉ): "์ ์ธ๊ณ ์ด๋ค ์ปดํจํฐ(IP)์์ ์ ์ํ๋ ๋ชจ๋ ํ๋ฝํ๊ฒ ๋ค"๋ ๋ป์ ๋๋ค. ์ฌ๊ธฐ์ ๋ค์ ๋ถ์ /0์ ๋คํธ์ํฌ ์ ํ ๋ฒ์๋ฅผ ์ ํ๋ ๋ฌธ๋ฒ(CIDR)์ธ๋ฐ, ์ซ์๊ฐ 0์ด๋ฉด '์๋ฌด๋ฐ ์ ํ์ ๋์ง ์๊ฒ ๋ค(Anywhere)'๋ ์๋ฏธ๊ฐ ๋ฉ๋๋ค.
๐จ๏ธ AWS ECR
๐ Amazon ECR์ AWS์์ ์ ๊ณตํ๋ ์์ ๊ด๋ฆฌํ docker image ์ ์ฅ์์ ๋๋ค. Amazon์ ECS, EKS, Elastic Beanstalk ๋ฑ ์ฌ๋ฌ ์๋น์ค์ ํตํฉ๋ ์ ์์ต๋๋ค. ๋ฐฐํฌํ๊ธฐ ์ํด์๋ ์ผ๋จ ์ด๋ฏธ์ง๋ฅผ ECR์ ๋ฑ๋ก์ ํด์ผ ํฉ๋๋ค.
- AWS์ ๊ฐ์ ํ ECR ๋์๋ณด๋์ ์ ์ํฉ๋๋ค. ๊ทธ ํ ๋ฆฌํฌ์งํ ๋ฆฌ ์์ฑ์ ํด๋ฆญํฉ๋๋ค. ์๋ณํ๊ธฐ ์ฝ๋๋ก ๋ฆฌํฌ์งํ ๋ฆฌ ์ด๋ฆ์ ๊น๋ฉ์ ๊ทธ๋ฃน/๋ฆฌํฌ์งํ ๋ฆฌ์ ์ผ์น์ํต๋๋ค.


- ์์ฑํ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ํด๋ฆญํ์ฌ ํธ์ฌ ๋ช ๋ น ๋ณด๊ธฐ๋ฅผ ํด๋ฆญํฉ๋๋ค. ์ด ๋ช ๋ น์ด๋ค์ ๊น๋ฉ CI/CD์์ ์ฌ์ฉ๋ ๊ฒ์ ๋๋ค.


๐จ๏ธ AWS ECS
๐ Amazon ECS (Elastic Container Service)๋ Amazon Web Services (AWS)์์ ์ ๊ณตํ๋ ์์ ๊ด๋ฆฌํ ์ปจํ ์ด๋ ์ค์ผ์คํธ๋ ์ด์ ์๋น์ค์ ๋๋ค. ์ด๋ Docker ์ปจํ ์ด๋๋ฅผ ์ฝ๊ฒ ์คํ, ์ ์ง, ๊ด๋ฆฌํ ์ ์๊ฒ ๋์์ค๋๋ค.
- ECS ๋์๋ณด๋์ ์ ์ํ์ฌ ํด๋ฌ์คํฐ ์์ฑ์ ํด๋ฆญํฉ๋๋ค. ์ด๋ฆ๋ง ์ค์ ํ๊ณ ์ธํ๋ผ๋ ์๋ฒ๋ฆฌ์ค ์ ํ ํ ์์ฑํฉ๋๋ค.

- ํ์คํฌ ์ ์ ๋ฉ๋ด์์ ์ ํ์คํฌ ์ ์ ์์ฑ์ ํด๋ฆญํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํจ๋ฐ๋ฆฌ ์ด๋ฆ์ ์ ๋ ฅํด์ค๋๋ค.

- ์คํฌ๋กค ํ์ฌ ์ปจํ
์ด๋์ ์ ๋ณด๋ฅผ ์
๋ ฅํฉ๋๋ค.
- ์ด๋ฏธ์ง URL์๋ ECR์ ๋ฆฌํฌ์งํ ๋ฆฌ URL์ ์ ๋ ฅํฉ๋๋ค.
- ํฌํธ์ 80 ํฌํธ๋ฅผ 8080์ผ๋ก ์์ ํฉ๋๋ค.
- ๊ทธ ํ ์์ฑ์ ํด๋ฆญํฉ๋๋ค.


- ํด๋ฌ์คํฐ ๋ฉ๋ด๋ก ๋์๊ฐ์ ์์ฑ๋ ํด๋ฌ์คํฐ๋ฅผ ํด๋ฆญํ ํ, ์๋น์ค์์ ์์ฑ์ ํด๋ฆญํฉ๋๋ค.
- ๋ฐฐํฌ ๊ตฌ์ฑ์์ ํจ๋ฐ๋ฆฌ๋ฅผ ์์ ์์ฑํ๋ ํ์คํฌ๋ฅผ ์ ํํฉ๋๋ค. ์๋น์ค ์ด๋ฆ๋ ์ ๋ ฅํด์ค๋๋ค.


- ์คํฌ๋กค ํ์ฌ ์๋์๋ ๋ก๋ ๋ฐธ๋ฐ์ฑ์์ ์ดํ๋ฆฌ์ผ์ด์
๋ก๋ ๋ฐธ๋ฐ์ฑ์ ์ ํํฉ๋๋ค.
- ์ ๋ณด๋ ์๋์ ๊ฐ์ด ์ ๋ ฅํฉ๋๋ค. ํฌํธ๋ 80์์ ํ์ธํฉ๋๋ค.

โ๏ธ ๋ก๋ ๋ฐธ๋ฐ์(ALB)์ ํฌํธ๊ฐ 80์ธ ์ด์
- 80๋ฒ ํฌํธ์ ์ ์ฒด: "์ธํฐ๋ท์ ํ์ค ๋๋ฌธ"
- ์ฐ๋ฆฌ๊ฐ ์ธํฐ๋ท ๋ธ๋ผ์ฐ์ ์์ http://๋ก ์์ํ๋ ์น์ฌ์ดํธ์ ์ ์ํ ๋, ๋ธ๋ผ์ฐ์ ๋ ์ฌ์ฉ์ ๋ชฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก 80๋ฒ ํฌํธ๋ฅผ ํฅํด ์ฐพ์๊ฐ๋๋ค.
- ์ฆ, ์ผ๋ฐ ์ฌ์ฉ์๋ค์ด ์ฃผ์์ฐฝ ๋ค์ :8080 ๊ฐ์ ๊ท์ฐฎ์ ์ซ์๋ฅผ ๋ถ์ด์ง ์๊ณ ๊น๋ํ๊ฒ ์ฃผ์๋ง ์ณ์ ๋ค์ด์ค๊ฒ ํ๋ ค๋ฉด, ๋ฐ์ผ๋ก ํตํ๋ ๋๋ฌธ์ ๋ฐ๋์ 80๋ฒ์ผ๋ก ์ด์ด๋์ด์ผ ํฉ๋๋ค.
- ๋ก๋ ๋ฐธ๋ฐ์์ ์ปจํ
์ด๋์ ์๋ฒฝํ ์ญํ ๋ถ๋ด
- ๋ก๋ ๋ฐธ๋ฐ์ (80๋ฒ ๋๊ธฐ): ์๋น์ '์ ๋ฌธ'์ ๋๋ค. ๋ฐ์์ ์ค๋ ์๋(ํธ๋ํฝ)์ 80๋ฒ ๋ฌธ์์ ๊ฐ์ฅ ๋จผ์ ๋ง์ดํฉ๋๋ค.
- ์คํ๋ง ๋ถํธ ์ปจํ ์ด๋ (8080๋ฒ ๋๊ธฐ): ์๋น์ '์ฃผ๋ฐฉ'์ ๋๋ค. ์์ ํ์คํฌ ์ ์์์ ์๋ฒ๊ฐ ์ผํ ๊ณต๊ฐ์ 8080์ผ๋ก ์ค์ ํ์์ฃ .
- ์ฐ๊ฒฐ ๊ณผ์ : ๋ก๋ ๋ฐธ๋ฐ์๊ฐ ์ ๋ฌธ(80๋ฒ)์ผ๋ก ๋ค์ด์จ ํธ๋ํฝ์ ์์ ํ๊ฒ ๋ฐ์์, ๋ค์์ ๋ฌต๋ฌตํ ์ผํ๊ณ ์๋ ์คํ๋ง ๋ถํธ ์ฃผ๋ฐฉ(8080๋ฒ)์ผ๋ก ํ ์ค(์ ๋ฌ)ํด ์ฃผ๋ ๊ฒ์ ๋๋ค.
- ๐ก ํ ์ค ์์ฝ: "์ผ๋ฐ ์ฌ์ฉ์๊ฐ ์ฃผ์์ฐฝ์ ํฌํธ ๋ฒํธ ์์ด ํธํ๊ฒ ์ ์(HTTP ๊ธฐ๋ณธ ํฌํธ 80)ํ๊ฒ ๋ง๋ค๊ณ , ๋ก๋ ๋ฐธ๋ฐ์๊ฐ ์ด ์์ฒญ์ ๋ฐ์์ ๋ด๋ถ์ ์คํ๋ง ๋ถํธ ์๋ฒ(8080)๋ก ์์ ํ๊ฒ ํ ์คํด ์ฃผ๊ธฐ ์ํ ์ค์ ์ ๋๋ค!"
๐จ๏ธ AWS IAM
- AWS IAM ์ ์ ์ํ์ฌ ์ฌ์ฉ์ ์์ฑ์ ํด๋ฆญํฉ๋๋ค.
- ์ง์ ์ ์ฑ ์ฐ๊ฒฐ์ ํด๋ฆญํ์ฌ AdministratorAccess ๊ถํ์ ๋ถ์ฌํ์ฌ ์ฌ์ฉ์๋ฅผ ์์ฑํฉ๋๋ค.


- ์์ฑํ ์ฌ์ฉ์ ์์ธํ์ด์ง์ ์ ์ํ์ฌ ์ก์ธ์ค ํค ๋ง๋ค๊ธฐ๋ฅผ ํด๋ฆญํฉ๋๋ค. ๊ทธ ํ ๊ธฐํ๋ฅผ ํด๋ฆญํฉ๋๋ค. ์ก์ธ์ค ํค๊ฐ ๋ง๋ค์ด์ง๋ฉด .csv ํ์ผ ๋ค์ด๋ก๋๋ฅผ ํด๋ฆญํ์ฌ ํ์ผ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค ํ์ผ์๋ ์์ธ์ค์ ๊ด๋ จ๋ ํค๊ฐ ์ ์ฅ๋์ด ์์ต๋๋ค.


๐จ๏ธ ๊น๋ฉ CI ํ์ผ ์์ฑ ๋ฐ ํธ์ฌ
- ๊น๋ฉ ํ๋ก์ ํธ ๋ฆฌํฌ์งํ ๋ฆฌ ๋ฉ๋ด์์ Settings > CI/CD > Variables ๋ฅผ ํด๋ฆญํ๊ณ 2๊ฐ ๋ณ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- โก๏ธ ์ด ๋ ํค์ ๊ฐ์ ์๊น AWS IAM ์์ ๋ค์ด๋ฐ์ csv์ ์์ต๋๋ค.

๐ GitLab CI/CD Variables & Expand ์ค์ ํต์ฌ ์์ฝ
- ํ๋ก์ ํธ Variables (๋ณ์)
- ์ญํ : ์ฝ๋์ ์ง์ ๋ ธ์ถ๋๋ฉด ์ํํ '๋น๋ฐ ์ ๋ณด(AWS ์ ์ ํค, DB ๋น๋ฐ๋ฒํธ, API ํ ํฐ ๋ฑ)'๋ฅผ ์์ ํ๊ฒ ๋ณด๊ดํ๋ ๊ธ๊ณ ์ ๋๋ค.
- ์ด์ : ์์ค ์ฝ๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ทธ๋๋ก ์ ์ด์ ์ฌ๋ฆฌ๋ฉด ํดํน์ ํ์ ์ด ๋ฉ๋๋ค. ๊ทธ๋์ ์ด๊ณณ์๋ง ๋ฐ๋ก ๋ฑ๋กํด๋๊ณ , CI/CD(์๋ ๋ฐฐํฌ)๊ฐ ์คํ๋ ๋๋ง ์์ ํ๊ฒ ๊ฐ์ ธ๋ค ์ฐ๋๋ก ๊ฒฉ๋ฆฌํด ๋๋ ๊ฒ์
๋๋ค.
- Protected
→ main/master ๊ฐ์ ๋ณดํธ ๋ธ๋์น์์๋ง Variables ์ฌ์ฉ ๊ฐ๋ฅํ๊ฒ ์ ํํ๋ ์ต์ - Masked
→ CI/CD ๋ก๊ทธ์ ๋น๋ฐ๋ฒํธ๋ ํ ํฐ ๊ฐ์ด ๋ ธ์ถ๋์ง ์๋๋ก ์จ๊ธฐ๋ ์ต์ - โป ์ค์ต ํ๊ฒฝ์์๋ ํ ์คํธ ํธ์๋ฅผ ์ํด ์ต์ ์ ํด์ ํ๊ณ ์ฌ์ฉ
- Protected
- Expand variable reference (๋ณ์ ํ์ฅ ์ฐธ์กฐ)
- ์ญํ : ์ ๋ ฅํ ๊ฐ ์์ $ ๊ธฐํธ๊ฐ ์์ ๋, ์ด๋ฅผ '๋ ๋ค๋ฅธ ๋ณ์'๋ก ํด์ํ ์ง ์๋๋ฉด '๊ทธ๋ฅ ํน์๋ฌธ์ $'๋ก ์ฝ์์ง ๊ฒฐ์ ํ๋ ์ต์ ์ ๋๋ค.
- โ ์ฒดํฌํ ๋: ๊ฐ ์์ ๋ค๋ฅธ ๋ณ์๋ฅผ ์กฐํฉํด์ ์ธ ๋ (์: $USER_NAME์ด๋ผ๊ณ ์ ์ผ๋ฉด ์ค์ ์ด๋ฆ์ผ๋ก ๋ณํํด์ ๊ฐ์ ธ์ด)
- โ ์ฒดํฌ ํด์ ํ ๋ (๋งค์ฐ ์ค์ ๐จ): ๋น๋ฐ๋ฒํธ๋ ํค ๊ฐ์ ํน์๋ฌธ์๋ก $๊ฐ ํฌํจ๋์ด ์์ ๋! ์ด ์ฒดํฌ๊ฐ ์ผ์ ธ ์์ผ๋ฉด ๊น๋ฉ์ด $ ๋ค์ ๊ธ์๋ค์ ๋ณ์๋ก ์ฐฉ๊ฐํด์ ๊ฐ์ ์๋ฑํ๊ฒ ๋ง๊ฐ๋จ๋ฆฝ๋๋ค. ๋ฐ๋ผ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฑ๋กํ ๋๋ ๊ผญ ์ฒดํฌ๋ฅผ ํด์ ํด์ผ ํฉ๋๋ค.
- ํ๋ก์ ํธ ๋ฃจํธ ํด๋์ .gitlab-ci.yml์ ์์ฑํฉ๋๋ค. docker build ์์ ์คํฌ๋ฆฝํธ๋ ECR์์ ํธ์ฌ ๋ช
๋ น ๋ณด๊ธฐ๋ฅผ ์ฐธ๊ณ ํ์ฌ ์์ฑํฉ๋๋ค.
- deploy ์์ ์๋ ํญ๋ชฉ์ ECS์ ์์ฑ ํญ๋ชฉ๋ค ์ด๋ฆ์ ์ฐธ๊ณ ํฉ๋๋ค.
services:
- docker:stable-dind
# โญ๏ธ [ํต์ฌ 1] ํ์ดํ๋ผ์ธ ์ ์ฒด 3๋จ๊ณ ํ๋ฆ (์ด ์์๋๋ก ์์
์ด ์งํ๋จ)
stages:
- build jar
- build and push docker image
- deploy
variables:
APPLICATION_NAME: "01"
TAG_NAME: "latest"
DOCKER_IMAGE: "group-18934028/project-01"
build:
image: openjdk:17-jdk-slim
stage: build jar
script:
- chmod +x gradlew
- ./gradlew clean build
# โญ๏ธ [ํต์ฌ 2] ํ์ผ ๋๊ฒจ์ฃผ๊ธฐ (๋ฐฉ๊ธ ๋ง๋ .jar ํ์ผ์ ๋ฒ๋ฆฌ์ง ์๊ณ ๋ค์ ๋์ปค ์์
์ผ๋ก ์ ๋ฌ!)
artifacts:
paths:
- build/libs/*.jar
docker build:
image: docker:latest
stage: build and push docker image
rules:
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_REF_NAME == "main"
variables:
TAG_NAME: "latest"
- if: $CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_REF_NAME == "develop"
variables:
TAG_NAME: "develop"
script:
# ๐๏ธ ์ด ๋ถ๋ถ์ ๋จ์ํ AWS ์ ์ ๋๊ตฌ๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ์ค์นํ๋ ๋ช
๋ น์ด๋ค์
๋๋ค.
- apk add --update --no-cache curl py3-pip py3-virtualenv
- python3 -m venv /tmp/venv
- source /tmp/venv/bin/activate
- pip install awscli
# โญ๏ธ [ํต์ฌ 3] ๋น๋ฐ๋ฒํธ ์จ๊ฒจ์ ์ฐ๊ธฐ! (๊น๋ฉ์ ๋ฑ๋กํ ๋ณด์ํค๋ฅผ $ ๊ธฐํธ๋ก ๋ถ๋ฌ์์ ์์ ํ๊ฒ ์ธํ
)
- aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
- aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
- aws configure set region ap-northeast-2
# (๋์ปค ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค๊ณ , AWS ECR ์ ์ฅ์ ์ด๋ฆํ๋ฅผ ๋ถ์ธ ๋ค ๋ฐ์ด ์ฌ๋ฆฌ๋ ํต์ฌ ์์
๋ค)
- docker build -t $DOCKER_IMAGE .
- docker tag $DOCKER_IMAGE:latest 730335597998.dkr.ecr.ap-northeast-2.amazonaws.com/$DOCKER_IMAGE:$TAG_NAME
- aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 730335597998.dkr.ecr.ap-northeast-2.amazonaws.com
- docker push 730335597998.dkr.ecr.ap-northeast-2.amazonaws.com/$DOCKER_IMAGE:$TAG_NAME
deploy:
image: python:3.9-slim
stage: deploy
script:
# ๐๏ธ ์ฌ๊ธฐ๋ 2๋จ๊ณ์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋จ์ ๋๊ตฌ ์ค์น ๊ณผ์ ์
๋๋ค.
- python3 -m venv /tmp/venv
- source /tmp/venv/bin/activate
- pip install awscli
- aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
- aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
- aws configure set region ap-northeast-2
# โญ๏ธ [ํต์ฌ 4] ๋๋ง์ ์๋ ๋ฐฐํฌ ๋ฒํผ! (AWS ECS์๊ฒ "์ ์ด๋ฏธ์ง ์ฌ๋ผ์์ผ๋ ๊ฐ์ ๋ก ์๋ฒ ์๋ก๊ณ ์นจ ํด!" ๋ผ๊ณ ์ง์)
- aws ecs update-service --cluster project-cluster --service project-01-service --task-definition project-01-task:1 --force-new-deployment
- IDE์์ ํ๋ก์ ํธ๋ฅผ ์ปค๋ฐ, ํธ์ฌํ์ฌ ๋ฐ์ํฉ๋๋ค. ์ค ๊ตฌ๋ถ ๊ธฐํธ ๊ฒฝ๊ณ ๊ฐ ๋์ค๋ฉด ๊ทธ๋๋ก ์ปค๋ฐ์ ์ ๋ ฅํฉ๋๋ค.


- GitLab์ ํ์ดํ๋ผ์ธ์ ํ์ธํฉ๋๋ค. ์คํ ์ด์ง๊ฐ ๋ชจ๋ ์ฑ๊ณตํ์ง ์์ผ๋ฉด ์คํจํ ์คํ ์ด์ง๋ฅผ ํด๋ฆญํ์ฌ ์ค๋ฅ ๋ด์ฉ์ ํ์ธํฉ๋๋ค.

๐ [CI/CD] GitLab + Docker + AWS(ECR/ECS) ์๋ ๋ฐฐํฌ ํ๋ฆ ์ ๋ฆฌ
- ์ฝ๋๋ฅผ ์์ ํ๊ณ Push๋ง ํ๋ฉด, ๋น๋๋ถํฐ AWS ์๋ฒ ๋ฐฐํฌ๊น์ง ๋ชจ๋ ๊ณผ์ ์ด ์๋์ผ๋ก ์ด๋ฃจ์ด์ง๋ CI/CD ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ์ต๋๋ค.
๐ 1. ์ ์ฒด ์๋ ๋ฐฐํฌ ํ๋ฆ (Pipeline)
- git push ํ ๋ฒ์ผ๋ก ์๋์ 4๋จ๊ณ๊ฐ ์๋์ผ๋ก ์ํ๋ฉ๋๋ค.
- ๋ด PC: git push (GitLab์ผ๋ก ์ฝ๋ ์ ์ก)
- GitLab CI/CD (build jar): Gradle๋ก Spring Boot ํ๋ก์ ํธ ๋น๋
- Docker (docker build & push): Docker Image ์์ฑ ํ AWS ECR์ ์ ๋ก๋
- AWS ECS (deploy): ECR์์ ์ด๋ฏธ์ง๋ฅผ Pull ๋ฐ์ ์ปจํ ์ด๋ ์คํ (์๋ฒ ์ฌ๋ฐฐํฌ)
๐ก 2. ๋ฐฐํฌ ๊ณผ์ ํ์ ํต์ฌ ๊ฐ๋
- Dockerfile: "์ด ํ๋ก์ ํธ๋ฅผ ์ด๋ค ํ๊ฒฝ์์ ์ด๋ป๊ฒ ์คํํ ์ง" ์ ์ด๋ ์คํ ์ค๋ช ์.
- ๋ฒ ์ด์ค ์ด๋ฏธ์ง: ์ปจํ ์ด๋ ์์ "๊ธฐ๋ณธ ์ปดํจํฐ ํ๊ฒฝ(Java/Linux)". (์ด๊ฒ ์์ผ๋ฉด Docker ์ปจํ ์ด๋ ์์ฒด๋ฅผ ๋ง๋ค ์ ์์!)
- Docker Image: ์คํ์ ํ์ํ ์ฝ๋ + Java + ์ค์ ๋ฑ์ ์ ๋ถ ๋ฌถ์ ์คํ ํจํค์ง.
- AWS ECR: ์์ฑ๋ Docker ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๋ ์ ์ฅ์.
- AWS ECS: ECR์์ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ ์ปจํ ์ด๋๋ก ๋์ฐ๊ณ ๊ด๋ฆฌํ๋ ์คํ/๊ด๋ฆฌ ์๋น์ค.
๐จ ํธ๋ฌ๋ธ์ํ (Troubleshooting) ํต์ฌ ์ ๋ฆฌ
โ OpenJDK ์ด๋ฏธ์ง Pull ์คํจ (๋ฒ ์ด์ค ์ด๋ฏธ์ง ๋ถ์ฌ)
- ์๋ฌ ๋ฉ์์ง:
manifest for openjdk:17-jdk-slim not found
- ์์ธ: Docker Hub์ ํด๋น ์ด๋ฏธ์ง ํ๊ทธ(openjdk:17-jdk-slim)๊ฐ ์กด์ฌํ์ง ์์ GitLab Runner๊ฐ ์ด๋ฏธ์ง๋ฅผ ์ฐพ์ง ๋ชปํจ.
- ํด๊ฒฐ: Dockerfile๊ณผ GitLab CI์์ Java ๋ฒ ์ด์ค ์ด๋ฏธ์ง๋ฅผ ์์ ์ ์ธ eclipse-temurin:17-jdk๋ก ๋ณ๊ฒฝ.
build:
image: eclipse-temurin:17-jdk
stage: build jar
script:
- chmod +x gradlew
- ./gradlew clean build
artifacts:
paths:
- build/libs/*.jar
โ ECS ์ด๋ฏธ์ง Pull ์คํจ (๋ธ๋์น๋ช ๋ถ์ผ์น๋ก ์ธํ Docker Build ์คํต)
- ์๋ฌ ๋ฉ์์ง:
์ค์ง ์ฝ๋: TaskFailedToStart
CannotPullContainerError: pull image manifest has been retried 7 time(s): failed to resolve ref ... :latest: not found
- ์์ธ: ECS๊ฐ ECR์์ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ค๋ ค ํ์ผ๋ ์ ์ฅ์๊ฐ ๋น์ด์์์. ํ์ดํ๋ผ์ธ ๋ก๊ทธ๋ฅผ ์ถ์ ํด ๋ณด๋ ์ ์ฒด 3๋จ๊ณ ์ค ์์ ์ด 2๊ฐ(build jar, deploy)๋ง ์คํ๋์์. ํ์ฌ GitLab ํ๋ก์ ํธ์ ๊ธฐ๋ณธ ๋ธ๋์น๋ master์ธ๋ฐ, .gitlab-ci.yml์ ์คํ ์กฐ๊ฑด(rules)์๋ main ๋ธ๋์น๋ง ์ค์ ๋์ด ์์ด ์ค๊ฐ์ Docker ์ด๋ฏธ์ง ๋น๋ ๋ฐ ECR ์ ๋ก๋ ๋จ๊ณ๊ฐ ํต์งธ๋ก ์คํต(Skip) ๋ ๊ฒ์ด ๊ทผ๋ณธ ์์ธ.
- ํด๊ฒฐ: .gitlab-ci.yml ํ์ผ์ docker build ์์ rules ์กฐ๊ฑด์ master ๋ธ๋์น๋ฅผ ๋ช ์์ ์ผ๋ก ์ถ๊ฐํ์ฌ, ์ฝ๋๋ฅผ ํธ์ํ ๋ ๋์ปค ๋น๋์ ECR ์ ๋ก๋๊ฐ ์ ์์ ์ผ๋ก ์ํ๋๋๋ก ์์ .
docker build:
image: docker:latest
stage: build and push docker image
rules:
# ๊ธฐ์กด main ์กฐ๊ฑด ๋ค์ master ๋ธ๋์น ์กฐ๊ฑด์ ์ถ๊ฐ!
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_REF_NAME == "main" || $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_REF_NAME == "master"
variables:
TAG_NAME: "latest"
- if: $CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_REF_NAME == "develop"
variables:
TAG_NAME: "develop"
โ Docker ์ด๋ฏธ์ง ๋น๋ ์คํจ (GitLab ํ๊ฒฝ vs ์ค์ ๋ฐฐํฌ ํ๊ฒฝ์ ์ฐจ์ด)
- ์ฆ์: .gitlab-ci.yml์ ์๋ฐ ์ด๋ฏธ์ง๋ฅผ ์์ ํ์ฌ build jar ๋จ๊ณ๋ ์ฑ๊ณตํ์ผ๋, docker build ๋จ๊ณ์์ ๋ค์ ์คํจํจ.
- ์์ธ: Java๊ฐ ํ์ํ ๊ณณ์ด ๋ ๊ตฐ๋ฐ์๋๋ฐ ํ ๊ณณ๋ง ์์ ํ๊ธฐ ๋๋ฌธ.
- yml ํ์ผ: ์ฝ๋๋ฅผ ๋น๋ํ ๋ ์ ๊น ๋น๋ ค ์ฐ๋ '์์ ์์ ์ค'
- Dockerfile: ์ค์ AWS ์๋ฒ์์ ๊ณ์ ๋์๊ฐ '์ต์ข ์คํ ํ๊ฒฝ' ์์ ์์ ์ค์ ์ค๋ฅ๋ ๊ณ ์ณค์ง๋ง, ์ต์ข ์คํ ํ๊ฒฝ์ ๋ผ๋๊ฐ ๋๋ Dockerfile์ ๋ฒ ์ด์ค ์ด๋ฏธ์ง(openjdk:17)๋ ์ฌ์ ํ Docker Hub์์ ์ฐพ์ ์ ์๋ ์ํ์์.
- ํด๊ฒฐ: Dockerfile์ FROM ๊ตฌ๋ฌธ ์ญ์ ์์ ์ ์ธ ๊ณต์ ๋ฐฐํฌํ์ธ eclipse-temurin:17-jdk๋ก ๋ณ๊ฒฝํ์ฌ ํด๊ฒฐ.
FROM eclipse-temurin:17-jdk
VOLUME /tmp
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
๐จ๏ธ ํ์ธํ๊ธฐ
- ECS ๋์๋ณด๋์์ ํด๋ฌ์คํฐ๋ฅผ ํด๋ฆญํ๊ณ ์๋น์ค ์์ธ ํ์ด์ง๊น์ง ์ ์ํฉ๋๋ค. ๊ทธ ํ ๋ก๋ ๋ฐธ๋ฐ์ ๋ณด๊ธฐ ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.

- ๋ก๋ ๋ฐธ๋ฐ์ ํ์ด์ง์์ DNS ์ด๋ฆ์ ๋ณต์ฌํ์ฌ ์น์ ์ ๋ ฅํ๊ณ ์คํ๋ง ํ๋ก์ ํธ์ ์๋ ํฌ์ธํธ์ ์ ๊ทผํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํฉ๋๋ค.


๐จ๏ธ ์ถ๊ฐ ์ ๋ณด) ๊นํ๋ธ ์ก์
- ์ธํ ๋ฆฌ์ ์ด ์ค์ ์์ ๊นํ๋ธ๋ฅผ ๋ก๊ทธ์ธํ ๋ฉ๋ด์์ VCS ๋๋ Git ๋ฉ๋ด์์ Github์ ํ๋ก์ ํธ ๊ณต์ ๋ฅผ ํด๋ฆญํ์ฌ ๊นํ๋ธ์๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค.

- Actions ํ์ด์ง์์ Ecs๋ฅผ ๊ฒ์ํ๊ณ “Configure”๋ฅผ ํด๋ฆญํฉ๋๋ค.

- ์ดํ ๋์ค๋ ํ์ด์ง์ ๋ด์ฉ์ ์๋์ ๋ด์ฉ์ผ๋ก ๋์ฒด ํฉ๋๋ค.
- ๋ด์ฉ์ ๋์ฒดํ ๋, env ์์ญ์ ์ ๋ณด๋ฅผ ๋์ AWS ์ ๋ณด๋ก ๋์ฒดํ์ฌ ์ ๋ ฅํฉ๋๋ค. ๊ทธ ํ “Commit changes” ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.

# This workflow will build and push a new container image to Amazon ECR,
# and then will deploy a new task definition to Amazon ECS, when there is a push to the "main" branch.
#
# To use this workflow, you will need to complete the following set-up steps:
#
# 1. Create an ECR repository to store your images.
# For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`.
# Replace the value of the `ECR_REPOSITORY` environment variable in the workflow below with your repository's name.
# Replace the value of the `AWS_REGION` environment variable in the workflow below with your repository's region.
#
# 2. Create an ECS task definition, an ECS cluster, and an ECS service.
# For example, follow the Getting Started guide on the ECS console:
# https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun
# Replace the value of the `ECS_SERVICE` environment variable in the workflow below with the name you set for the Amazon ECS service.
# Replace the value of the `ECS_CLUSTER` environment variable in the workflow below with the name you set for the cluster.
#
# 3. Store your ECS task definition as a JSON file in your repository.
# The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`.
# Replace the value of the `ECS_TASK_DEFINITION` environment variable in the workflow below with the path to the JSON file.
# Replace the value of the `CONTAINER_NAME` environment variable in the workflow below with the name of the container
# in the `containerDefinitions` section of the task definition.
#
# 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
# See the documentation for each action used below for the recommended IAM policies for this IAM user,
# and best practices on handling the access key credentials.
name: Deploy to Amazon ECS
on:
push:
branches: [ "main" ]
env:
AWS_REGION: ap-southeast-2 # set this to your preferred AWS region, e.g. us-west-1
ECR_REPOSITORY: group-18934028/test-01 # set this to your Amazon ECR repository name
ECS_SERVICE: test-01-service # set this to your Amazon ECS service name
ECS_CLUSTER: test-01-cluster # set this to your Amazon ECS cluster name
ECS_TASK_DEFINITION: .github/workflows/project-01-task-revision1.json # set this to the path to your Amazon ECS task definition
# file, e.g. .aws/task-definition.json
CONTAINER_NAME: test-01-container # set this to the name of the container in the
# containerDefinitions section of your task definition
permissions:
contents: read
jobs:
build:
name: Build Jar
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build
- name: Upload Build Artifacts
uses: actions/upload-artifact@v3
with:
name: build-libs
path: build/libs/*.jar
deploy:
name: Deploy
runs-on: ubuntu-latest
needs: build
environment: production
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download Build Artifacts
uses: actions/download-artifact@v3
with:
name: build-libs
path: build/libs
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ env.ECS_TASK_DEFINITION }}
container-name: ${{ env.CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: true
- ๊นํ๋ธ ํ๋ก์ ํธ ๋ฃจํธ์์ Code ๋ฒํผ์ ํด๋ฆญํ๊ณ Codespaces ํญ์์ Create codespace on main์ ํด๋ฆญํ์ฌ ์น IDE๋ฅผ ์ฝ๋๋ค. (์ด ๋ด์ฉ์ ์ธํ ๋ฆฌ์ ์ด์์ ํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.)

- .github/workflows ํด๋์ project-01-task-revision1.json์ด๋ผ๋ ํ์ผ์ ๋ง๋ญ๋๋ค. AWS์ ํ
์คํฌ ์ ์ ์์ธ ํ์ด์ง์์ JSON ํญ์ ํด๋ฆญํ์ฌ ํด๋ฆฝ๋ณด๋๋ก ๋ณต์ฌ ๋ฒํผ์ ํด๋ฆญํ์ฌ ๋ด์ฉ์ ๋ณต์ฌํฉ๋๋ค.
- project-01-task-revision1.json ํ์ผ์ ๋ณต์ฌํ ๋ด์ฉ์ ๋ถ์ฌ๋ฃ๊ธฐ ํ๊ณ ์ปค๋ฐ, ํธ์ฌ ํฉ๋๋ค.
- ์ ํ์ผ์ ์ ์ฒด: CPU, ๋ฉ๋ชจ๋ฆฌ, ์ด์ด๋ ํฌํธ ๋ฑ ์๋ฒ๋ฅผ ์ด๋ป๊ฒ ๊ตฌ๋ํ ์ง ๋ช ์ํด ๋ 'ECS ์๋ฒ ์คํ ์ค๊ณ๋'์ ๋๋ค.
- AWS์ ์๋๋ฐ ๊ตณ์ด GitHub์ ๋ฃ๋ ์ด์ : ๋ฐฐํฌ์ ์ฃผ๋๊ถ์ด AWS์์ GitHub๋ก ๋์ด์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์๋ํ ํด์ธ GitHub Actions๊ฐ ์๊ฒฉ์ผ๋ก AWS ์๋ฒ๋ฅผ ์กฐ์ข ํ์ฌ ์ ๋ฒ์ ์ ๋์ฐ๋ ค๋ฉด, ๊ทธ '์คํ ๊ธฐ์ค ํ ํ๋ฆฟ'์ ์์ ์ ์ ์ฅ์ ๋ด๋ถ์ ์ง์ ๋ค๊ณ ์์ด์ผ ๋ช ๋ น์ ๋ด๋ฆด ์ ์์ต๋๋ค.
- "์ฆ, AWS์ ์๋ ๊ธฐ์กด ์ค์ ์ ๊ทธ๋๋ก ๋ ์์, GitHub๊ฐ ๋ฐฐํฌํ ๋๋ง๋ค '์ด ์ค๊ณ๋(JSON) ์ค์ ๊ทธ๋๋ก ๋ฐฉ๊ธ ๋ง๋ ์ ์ด๋ฏธ์ง๋ฅผ ์คํํด ์ค!'
- project-01-task-revision1.json ํ์ผ์ ๋ณต์ฌํ ๋ด์ฉ์ ๋ถ์ฌ๋ฃ๊ธฐ ํ๊ณ ์ปค๋ฐ, ํธ์ฌ ํฉ๋๋ค.




- ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ Settngs > Secrity > Secrets and variables > Actions์ ํ์ด์ง์์ Secrets ํญ์์ ์๋ก์ด ์ํฌ๋ฆฟ์ ์
๋ ฅํฉ๋๋ค.
- AWS IAM ์์ ์์ฑํ ์์ธ์ค ํค์ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉฐ 2๊ฐ๋ฅผ ์์ฑํฉ๋๋ค.
- AWS_ACCESS_KEY_ID , AWS_SECRET_ACCESS_KEY


- ์ด์ Actions ํญ์ workflow ๋ฅผ ์คํํ๊ณ Gitlab์์์ ๊ฐ์ด ์น์์ ๋ก๋ ๋ฐธ๋ฐ์์ DNS ์ด๋ฆ์ผ๋ก ์ ์ํ์ฌ ๋ฐฐํฌ๋ฅผ ํ์ธํฉ๋๋ค.



๐ [CI/CD] GitHub Actions + Docker + AWS (ECR/ECS) ์๋ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
๐ 1. ์ ์ฒด ์๋ ๋ฐฐํฌ ์ํฌํ๋ก์ฐ (Workflow Flow)
- GitLab์ Pipeline์ ํด๋นํ๋ GitHub์ ์ํฌํ๋ก์ฐ ์คํ(Workflow Run) ์์์ ๋๋ค. git push ํ ๋ฒ์ผ๋ก ์๋ ๊ณผ์ ์ด ์๋์ผ๋ก ์งํ๋ฉ๋๋ค.
- ๐ป GitHub Push: ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ฅผ main ๋๋ master ๋ธ๋์น์ ํธ์
- ๐ ๏ธ Build Job: GitHub Runner๊ฐ ์์ ํ๊ฒฝ(JDK 17)์ ๋์ฐ๊ณ ./gradlew clean build ์คํ
- ๐ฆ Artifact ์์ ์ ์ฅ: ๋น๋๋ .jar ํ์ผ์ ๋ค์ ๋ฐฐํฌ ๋จ๊ณ๋ก ๋๊ธฐ๊ธฐ ์ํด ๋ณด๊ด (upload-artifact)
- ๐ AWS ์ธ์ฆ: GitHub Secrets์ ์จ๊ฒจ๋ ์๊ฒฉ ์ฆ๋ช (ACCESS_KEY)์ผ๋ก ์์ ํ๊ฒ ๋ก๊ทธ์ธ
- ๐ณ Docker Build & Push: Dockerfile์ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค๊ณ AWS ECR(์ ์ฅ์)์ ์ ๋ก๋
- ๐ Task Definition ๊ฐฑ์ : AWS ECS ์คํ ์ค๊ณ๋(JSON)์ ์ด๋ฏธ์ง ์ฃผ์๋ฅผ ๋ฐฉ๊ธ ๋ง๋ ์ ์ด๋ฏธ์ง๋ก ๊ต์ฒด
- ๐ ECS Deploy: ECS ์๋น์ค๊ฐ ์๋ก์ด ์ค์ ์ผ๋ก ์๋ฒ(์ปจํ ์ด๋)๋ฅผ ์๋ ์ฌ๋ฐฐํฌ
๐ก 2. ํ์ดํ๋ผ์ธ ํ์ ํต์ฌ ๊ฐ๋ ์ฌ์
- [GitHub & ๋น๋ ๊ด๋ จ]
- .github/workflows/aws.yml: GitHub Actions์ ์๋ํ ์คํฌ๋ฆฝํธ. ์ธ์ , ์ด๋ค ์์๋ก ๋์ํ ์ง ์ ์ํ๋ ํต์ฌ ์ค์ ํ์ผ์ ๋๋ค.
- Artifact (์ํฐํฉํธ): ํ์ดํ๋ผ์ธ์ ์์ (Job) ๊ฐ์ ์ฃผ๊ณ ๋ฐ๋ ๊ฒฐ๊ณผ๋ฌผ. ์ฌ๊ธฐ์๋ ์์ ๋น๋ํ .jar ํ์ผ์ ๋ค์ ๋์ปค ๋ฐฐํฌ ๋จ๊ณ๋ก ๋๊ฒจ์ฃผ๊ธฐ ์ํด ์ฌ์ฉํ์ต๋๋ค.
- GitHub Secrets: AWS ์ ์ ํค(ACCESS_KEY_ID ๋ฑ)์ฒ๋ผ ์ฝ๋์ ์ง์ ๋ ธ์ถ๋๋ฉด ์ ๋๋ ๋ฏผ๊ฐํ ํ๊ฒฝ ๋ณ์๋ฅผ ์์ ํ๊ฒ ๋ณด๊ดํ๋ ๊ธ๊ณ ์ ๋๋ค.
- [Docker ํ๊ฒฝ ๊ด๋ จ]
- Dockerfile: Spring Boot ์ฑ์ ์คํํ "๋ฆฌ๋ ์ค ์คํ ํ๊ฒฝ ๋ฐ์ค(์ปจํ ์ด๋)"๋ฅผ ๋ง๋๋ ์กฐ๋ฆฌ ์ค๋ช ์์ ๋๋ค.
- eclipse-temurin:17-jdk: Docker Hub์์ ์ ๊ณตํ๋ Java 17 ์คํ์ฉ ๋ฆฌ๋ ์ค ๊ธฐ๋ฐ ๋ฒ ์ด์ค ์ด๋ฏธ์ง. ์ค์ ECS์์ Spring Boot๋ฅผ ์คํํ ๋ ๋ผ๋๋ก ์ฌ์ฉ๋ฉ๋๋ค.
- [AWS ์ธํ๋ผ ๊ด๋ จ]
- ECR (Elastic Container Registry): ์ฐ๋ฆฌ๊ฐ ๋ง๋ Docker ์ด๋ฏธ์ง๋ฅผ ์ฐจ๊ณก์ฐจ๊ณก ๋ณด๊ดํ๋ AWS ์ ์ฉ ์ ์ฅ์์ ๋๋ค.
- ECS (Elastic Container Service): ECR์์ ์ด๋ฏธ์ง๋ฅผ ๊บผ๋ด์ ์ค์ ์ปจํ ์ด๋ ์๋ฒ๋ก ์คํํ๊ณ ๊ด๋ฆฌํด ์ฃผ๋ ์งํ์์ ๋๋ค.
- Task Definition (ํ์คํฌ ์ ์): ECS๊ฐ ์ปจํ ์ด๋๋ฅผ ์คํํ ๋ "์ด๋ค ์ด๋ฏธ์ง, ๋ช ๋ฒ ํฌํธ, ์ผ๋งํผ์ ๋ฉ๋ชจ๋ฆฌ"๋ก ์คํํ ์ง ์ ์ด๋ ์๋ฒ ์คํ ์ค๊ณ๋(JSON)์ ๋๋ค.
- Load Balancer DNS: ์ปจํ ์ด๋๋ ์ฌ์์๋ ๋๋ง๋ค ๋ด๋ถ IP๊ฐ ๊ณ์ ๋ฐ๋๋๋ค. ๊ทธ๋์ ์ฌ์ฉ์๊ฐ IP ๋์ ์ธ์ ๋ ๋ณํจ์์ด ์ ์ํ ์ ์๋๋ก ์ ๊ณตํด ์ฃผ๋ ๊ณ ์ ์ ์ ์ฃผ์(๋๋ฌธ)์ ๋๋ค.
๐ 3. ํ๋์ ๋ณด๋ ๋น๊ต (GitLab CI/CD vs GitHub Actions)
- ๋ ํ๋ซํผ ๋ชจ๋ ํฐ ํ๋ฆ(Push ํธ๋ฆฌ๊ฑฐ → ๋น๋ → Docker ์์ฑ → ECR ์ ๋ก๋ → ECS ๋ฐฐํฌ)์ ์๋ฒฝํ๊ฒ ๋์ผํฉ๋๋ค. ํ๋ซํผ๊ณผ ๋ฌธ๋ฒ์ ์ฐจ์ด๋ง ์กด์ฌํ ๋ฟ์ ๋๋ค.
| ๊ตฌ๋ถ | GitLab CI/CD | GitHub Actions |
| ์ค์ ํ์ผ ์์น | ์ต์๋จ .gitlab-ci.yml | .github/workflows/aws.yml |
| ์์ ๋จ์ ๋ช ์นญ | Pipeline (ํ์ดํ๋ผ์ธ) | Workflow Run (์ํฌํ๋ก์ฐ ๋ฐ) |
| ์์ ํ๋ฆ ์ ์ | stages ์ jobs๋ก ๊ตฌ์ฑ | jobs ์ steps๋ก ๊ตฌ์ฑ |
| ๋น๋ฐ ๋ณ์ ๊ด๋ฆฌ | Settings > CI/CD > Variables | Settings > Secrets and variables |
๐ ์์ฝํ์๋ฉด: GitLab์์๋ ํ๋์ ํ์ดํ๋ผ์ธ ์์์ ๋จ๊ณ๋ฅผ ๋๋์ด ์คํํ๋ค๋ฉด, GitHub Actions์์๋ .yml ํ์ผ์ ์ฝ์ด ์ ํด์ง ์์ (Job)๊ณผ ์ธ๋ถ ๋จ๊ณ(Step)๋ฅผ ์คํํ๋ ๋ฐฉ์์ ๋๋ค. ์ด๋ค ๋๊ตฌ๋ฅผ ์ฐ๋ CI/CD์ ๋ณธ์ง์ ์ธ ์ํคํ ์ฒ๋ ๋์ผํ๋ค๋ ๊ฒ์ ๋ฐฐ์ธ ์ ์์์ต๋๋ค!
๐จ ํธ๋ฌ๋ธ์ํ (Troubleshooting) ํต์ฌ ์ ๋ฆฌ
โ GitHub Actions ํ์ดํ๋ผ์ธ ์์ ์คํ ์ ๋จ (ํธ๋ฆฌ๊ฑฐ ๋ธ๋์น ๋ถ์ผ์น)
- ์ฆ์: ์ฝ๋๋ฅผ ์ปค๋ฐํ๊ณ ํธ์(git push)ํ๋๋ฐ๋ GitHub Actions ํญ์ ์๋ฌด๋ฐ ์์ ์ด ๋จ์ง ์๊ณ ์กฐ์ฉํจ.
- ์์ธ: GitHub Actions๋ ์ค์ ํ์ผ(.yml)์ ์คํ ์กฐ๊ฑด์ด ๋ง์์ผ๋ง ๋์ํจ. aws.yml ํ์ผ์ ์คํ ์กฐ๊ฑด(on: push)์ main ๋ธ๋์น๋ก ์ ํ ์์์ผ๋, ํ์ฌ ๊นํ๋ธ์ ์ค์ ๋ธ๋์น๋ master์๊ธฐ ๋๋ฌธ์ GitHub๊ฐ ์คํ ์กฐ๊ฑด์ด ์๋๋ผ๊ณ ํ๋จํ์ฌ ์์ ์๋์ ์คํตํ ๊ฒ.
- ํด๊ฒฐ: aws.yml ์์ ๋ธ๋์น ์กฐ๊ฑด์ branches: [ "master" ]๋ก ์์ ํ์ฌ ์ ์ ์๋ ํ์ธ.
on:
push:
branches: [ "master" ]
โ ํ์ดํ๋ผ์ธ ์ค๊ฐ ๋ฉ์ถค (Artifact Action ๊ตฌ๋ฒ์ ๋ง๋ฃ)
- ์๋ฌ ๋ฉ์์ง:
deprecated version of `actions/upload-artifact: v3` - ์์ธ: ๋น๋๋ ํ์ผ(.jar ๋ฑ)์ ์์๋ก ์ ์ฅํด๋๋ GitHub์ ๊ธฐ๋ณธ ์ก์ (upload-artifact) ๋ฒ์ ์ด ๊ตฌ๋ฒ์ (v3)์ด์๋๋ฐ, GitHub ์ธก์์ ํด๋น ๋ฒ์ ์ ์ง์์ ๊ฐ์ ๋ก ์ข ๋ฃ(Deprecated)ํด๋ฒ๋ ค์ ๋ฐ์ํ ์์คํ ์ ์ค๋ฅ.
- ํด๊ฒฐ: aws.yml ์ฝ๋ ๋ด๋ถ์ upload-artifact@v3์ download-artifact@v3๋ฅผ ๋ชจ๋ ์ต์ ๋ฒ์ ์ธ @v4๋ก ๋ณ๊ฒฝ.
โ ECS ์ต์ข ๋ฐฐํฌ ์คํจ (Task Definition JSON ํธํ์ฑ ์ค๋ฅ)
- ์๋ฌ ๋ฉ์์ง:
Unexpected key 'enableFaultInjection' - ์์ธ: AWS ์ฝ์์ด ์ต๊ทผ ์ ๋ฐ์ดํธ๋๋ฉด์ ECS ์ค์ JSON ํ์ผ์ ์ต์ ์ต์ (enableFaultInjection: ์ธ์์ ์ฅ์ ํ ์คํธ์ฉ)์ ์๋์ผ๋ก ์ถ๊ฐํด์ ๋ฐ๊ธํด ์ค. ํ์ง๋ง GitHub Action์ ๋ฐฐํฌ ๊ธฐ๋ฅ์ ์์ง ์ด ์ต์ ํค์๋๋ฅผ ์ธ์ํ์ง ๋ชปํด์ ๋ชจ๋ฅด๋ ์ค์ ์ด ๋ค์ด์๋ค๋ฉฐ ์๋ฌ๋ฅผ ๋ฑ์ด๋ธ ์ํฉ.
- ํด๊ฒฐ: ํด๋น ๊ธฐ๋ฅ์ ๋จ์ ๋ฐฐํฌ ํ๋ฆ์ ์ ํ ํ์ ์๋ ๊ณ ๊ธ ์ต์ ์ด๋ฏ๋ก, ํ๋ก์ ํธ ๋ด์ project-01-task.json ํ์ผ์์ ํด๋น ์ค("enableFaultInjection": false,)์ ์ฐพ์ ์ญ์ ํ ํ ๋ค์ ํธ์ํ์ฌ ์ต์ข ๋ฐฐํฌ ์ฑ๊ณต!
'Back-End > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ๋๊ท๋ชจ ์คํธ๋ฆผ ์ฒ๋ฆฌ (0) | 2026.05.14 |
|---|---|
| ํ๋ก์ ํธ ๊ด๋ฆฌ ์ฌํ: ์ฑํฐ 1 (Docker) (0) | 2026.05.04 |
| MSA (Microservice Architecture) (0) | 2026.04.14 |
| Spring ์๋ จ: ์ฑํฐ 2 (0) | 2026.04.08 |
| Spring ์๋ จ: ์ฑํฐ 1 (0) | 2026.04.07 |