리μ : ap-northeast-2 (μμΈ) / ꡬ쑰: λ¨μΌ EC2 μμ
app+mysql+redis컨ν μ΄λ μ΄μ λ°©μ: ν μ€νΈν λλ§terraform applyλ‘ μ¬λ¦¬κ³ , λλλ©΄terraform destroyλ‘ λ΄λ¦Ό (μμ νκ²½)μ΅μ’ λͺ©ν: λ¨μΌ μλ²λ‘ λ°°ν¬νλ scale-out(λ€μ€ μλ²) μ±λ₯ μ°¨μ΄λ₯Ό μΈ‘μ ν μ μκ² λ§λλ κ². μ΄ λ¬Έμλ 첫 λ°°ν¬ κΈ°μ€ μ²΄ν¬λ¦¬μ€νΈλ€.
EC2 (t3.medium, Ubuntu, ap-northeast-2)
ββββββββββββββββββββββββββββββββββββββββββββ
:80 app (Spring Boot)
βββ mysql (컨ν
μ΄λ, EBS λ³Όλ₯¨)
βββ redis (컨ν
μ΄λ)
ββββββββββββββββββββββββββββββββββββββββββββ
Terraformλ‘ νλ‘λΉμ λ Β· user-dataλ‘ λΆνΈμ€νΈλ©
λ°°ν¬ 3λ¨κ³ μ μ λ°λμ λλ΄μΌ νλ μ€λΉ.
-
docker-compose.prod.ymlμ MySQL 컨ν μ΄λ μΆκ° +appμ΄DB_HOST=mysqlλ‘ μ°κ²° - μ± μ΄λ―Έμ§ μ¬λΉλ & Docker Hub push β
β οΈ μ΅μ 리ν©ν°λ§ λ°μλ³ΈμΌλ‘ (κΈ°μ‘΄ μ΄λ―Έμ§λ μ μ½λ)bash ./gradlew clean bootJar docker build -t <DOCKER_USERNAME>/docker-springboot:latest . docker push <DOCKER_USERNAME>/docker-springboot:latest - μλ λ°μ΄ν° β
β οΈ κ³Όλͺ©/νμμ΄ μμΌλ©΄ λΆνν μ€νΈμμ μ μ²ν λμμ΄ μμ βDataInitializer(CommandLineRunner)λ‘ κ³Όλͺ© + ν μ€νΈ νμ Nλͺ μμ± (BCrypt ν΄μ μ²λ¦¬) -
.envμμ± (DB λΉλ² λ±) +.gitignoreνμΈ (μ»€λ° κΈμ§)
- AWS κ³μ , IAM μ¬μ©μ + μ‘μΈμ€ν€ λ°κΈ (Terraformμ©, μ΅μκΆν)
- λ‘컬μ AWS CLI μ€μΉ +
aws configure(region:ap-northeast-2) - λ‘컬μ Terraform μ€μΉ
- SSH ν€νμ΄ μμ± (
ssh-keygen -t ed25519)
μ½λλ‘ AWS 리μμ€λ₯Ό μ μνκ³ apply.
- Terraform νλ‘μ νΈ κ΅¬μ‘°
provider.tfβ AWS provider,region = "ap-northeast-2"main.tfβ 리μμ€ μ μvariables.tf/terraform.tfvars(gitignore) β λ³μΒ·λΉλ°κ°outputs.tfβ μλ£ ν νΌλΈλ¦ IP μΆλ ₯
- 리μμ€
- κΈ°λ³Έ VPC/μλΈλ· (
dataλ‘ μ°Έμ‘°, μλ‘ μ λ§λ¦) - Security Group: 22(SSH, λ΄ IPλ§), 80(HTTP, μ 체)
- Key Pair (Phase 0 곡κ°ν€ λ±λ‘)
- EC2:
t3.medium, Ubuntu 22.04 (AMIλdataλ‘ μ΅μ μ‘°ν) - (μ ν) Elastic IP β μ¬μμ μ IP κ³ μ (μ μ°λ©΄ μλ΅)
- κΈ°λ³Έ VPC/μλΈλ· (
-
terraform initβplanβapplyβ νΌλΈλ¦ IP νλ
EC2κ° λΆν νλ©° μλ μ€ννλ μ€ν¬λ¦½νΈ.
-
user-data.sh- Docker + docker-compose plugin μ€μΉ
- μ± νμΌ λ°°μΉ:
docker-compose.prod.yml,.env(git clone λλ scp) .envλΉλ°κ° μ£Όμ (νμ΅ λ¨κ³λ scp, μ΄ν SSM Parameter Store κΆμ₯)
- lua λ± λ¦¬μμ€λ jar(classpath)μ ν¬ν¨λλμ§ νμΈ β ν¬ν¨λλ©΄ λ³λ μ μ‘ λΆνμ
-
docker compose -f docker-compose.prod.yml up -d - MySQL μ€ν€λ§:
ddl-auto: updateκ° ν μ΄λΈ μλ μμ± β μλλ‘ κ³Όλͺ© λ°μ΄ν° νμΈ - μ€λͺ¨ν¬ ν
μ€νΈ:
http://<IP>μ μ β λ‘κ·ΈμΈ β μκ°μ μ² νλ‘μ° 1ν (리ν©ν°λ§ ν 첫 μ€λμ κ²μ¦) - λ‘κ·Έ νμΈ:
docker compose logs -f
- λ΄λ¦΄ λ:
terraform destroyβ κ³ΌκΈ λ¦¬μμ€ 0 -
β οΈ destroy μ MySQL 컨ν μ΄λ λ°μ΄ν°λ μμ λ¨ β λΆνν μ€νΈλ λ§€λ² κΉ¨λν μνκ° μ’κ³ , μλκ° λ€μ μ±μ - λ€μ μ¬λ¦΄ λ:
terraform apply
- μΈμ
μΈλΆν:
spring-session-data-redis(λ€μ€ μΈμ€ν΄μ€ λ‘κ·ΈμΈ μ μ§) - nginx + app replica λ€μ€ν, μ΄ν EC2 λ€μ€ + ALB
- μ€μΌμ€λ¬ μ€λ³΅ μ€ν λ¬Έμ λ°κ²¬ β
ShedLockμΌλ‘ λ¨μΌ μΈμ€ν΄μ€ μ€ν 보μ₯ - λ¨μΌ vs λ€μ€ μλ² λΆνν μ€νΈ(k6) λΉκ΅