Skip to content

Commit 1d9f6e9

Browse files
authored
[CHORE]: 인프라 및 CD 수정 (#94)
* chore: 디렉토리 설정 수정 - 일부 환경에서 디렉토리 설정 오류로 인해 docker-compose가 제대로 정상작동되지 않는 현상 수정 * chore: CD 스크립트 수정 - docker 볼륨 추가 : AI 응답 속도 개선을 위한 텍스트 파일 저장 목적의 마운트 추가 * chore: acm 및 cdn 링크 추가로 인한 수정 * chore: 외부 접근 시 권한 문제로 인한 수정 * chore: ec2 종료 시 디스크가 초기화 되지 않도록 수정 * chore: fixme 파트 제거
1 parent 6630398 commit 1d9f6e9

File tree

8 files changed

+104
-76
lines changed

8 files changed

+104
-76
lines changed

.github/workflows/Backend-CD.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ jobs:
249249
HEALTH_PORT="${{ env.HEALTH_CHECK_PORT }}"
250250
NET="${{ env.DOCKER_NETWORK }}"
251251
ENV_FILE="/tmp/relife.env"
252+
DOCKER_PROJECT_DIR="/dockerProjects/relife_app"
252253
253254
echo "🔹 Use image: ${IMAGE}"
254255
if ! docker pull "${IMAGE}"; then
@@ -317,21 +318,28 @@ jobs:
317318
# ---------------------------------------------------------
318319
# 4) green 역할 컨테이너 재기동
319320
# - 같은 네트워크 상에서 NPM이 컨테이너명:PORT로 프록시하므로 -p 불필요
321+
# - 호스트 볼륨 마운트로 Blue/Green 간 데이터 영속성 보장
320322
# ---------------------------------------------------------
321323
docker rm -f "${GREEN}" >/dev/null 2>&1 || true
324+
325+
# 볼륨 디렉토리 생성 (없으면)
326+
mkdir -p ${DOCKER_PROJECT_DIR}/{data,logs}
327+
322328
echo "🚀 run new container → ${GREEN}"
323329
docker run -d --name "${GREEN}" \
324330
--restart unless-stopped \
325331
--network "${NET}" \
326332
--env-file "${ENV_FILE}" \
327333
-e TZ=Asia/Seoul \
334+
-v ${DOCKER_PROJECT_DIR}/data:/app/data \
335+
-v ${DOCKER_PROJECT_DIR}/logs:/app/logs \
328336
"${IMAGE}"
329337
330338
# ---------------------------------------------------------
331339
# 5) 헬스체크 (/actuator/health/readiness 200 OK까지 대기)
332340
# ---------------------------------------------------------
333341
echo "⏱ health-check: ${GREEN}"
334-
TIMEOUT=120
342+
TIMEOUT=180
335343
INTERVAL=3
336344
ELAPSED=0
337345
sleep 8 # 초기 부팅 여유
@@ -350,7 +358,7 @@ jobs:
350358
351359
if [[ "${CODE:-000}" != "200" ]]; then
352360
echo "❌ ${GREEN} health failed"
353-
docker logs --tail=200 "${GREEN}" || true
361+
docker logs --tail=300 "${GREEN}" || true
354362
docker rm -f "${GREEN}" || true
355363
exit 1;
356364
fi
@@ -371,7 +379,7 @@ jobs:
371379
else
372380
echo "❌ Failed to switch upstream! Received HTTP status code: ${HTTP_CODE}"
373381
# [수정] 전환 실패 시, 새로 띄운 Green 컨테이너는 즉시 제거하고 실패 처리
374-
docker logs --tail=200 "${GREEN}" || true
382+
docker logs --tail=300 "${GREEN}" || true
375383
docker rm -f "${GREEN}" || true
376384
exit 1
377385
fi

back/docker-compose-dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ services:
1414
environment:
1515
TZ: "Asia/Seoul"
1616
volumes:
17-
- /dockerProjects/redis_1/volumes/data:/data
17+
- ~/dockerProjects/redis_1/volumes/data:/data
1818

1919
networks:
2020
common:

infra/aws/terraform/cloudfront.tf

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ resource "aws_cloudfront_distribution" "cloudfront_distribution" {
3131
cached_methods = ["GET", "HEAD"]
3232
target_origin_id = "S3-${aws_s3_bucket.s3_1.id}"
3333
viewer_protocol_policy = "redirect-to-https"
34+
compress = true # Gzip/Brotli 압축 활성화
3435

3536
forwarded_values {
3637
query_string = false
@@ -39,10 +40,10 @@ resource "aws_cloudfront_distribution" "cloudfront_distribution" {
3940
}
4041
}
4142

42-
# 캐시 설정
43+
# 캐시 설정 - 정적 리소스는 길게
4344
min_ttl = 0
44-
default_ttl = 86400
45-
max_ttl = 31536000
45+
default_ttl = 86400 # 1일
46+
max_ttl = 31536000 # 1년
4647
}
4748

4849
restrictions {
@@ -51,9 +52,22 @@ resource "aws_cloudfront_distribution" "cloudfront_distribution" {
5152
}
5253
}
5354

55+
# 존재하지 않는 오브젝트 요청 시
5456
custom_error_response {
55-
error_caching_min_ttl = 600
5657
error_code = 404
58+
error_caching_min_ttl = 300 # 5분 (에러 캐싱으로 Origin 부하 감소)
59+
}
60+
61+
# 권한 없음 에러 (예: S3 퍼미션 문제)
62+
custom_error_response {
63+
error_code = 403
64+
error_caching_min_ttl = 120
65+
}
66+
67+
# S3 서비스 장애 시
68+
custom_error_response {
69+
error_code = 503
70+
error_caching_min_ttl = 10
5771
}
5872

5973
# 과금 정책
@@ -62,15 +76,15 @@ resource "aws_cloudfront_distribution" "cloudfront_distribution" {
6276
# PriceClass_All: 전세계
6377
price_class = "PriceClass_100"
6478

65-
# fixme: CDN 도메인 설정
66-
# aliases = [var.cdn_domain]
79+
# CDN 도메인 설정
80+
aliases = [var.cdn_domain]
6781

6882
viewer_certificate {
69-
cloudfront_default_certificate = true
70-
# fixme: ACM 인증서 사용(CDN 도메인 설정) 시 아래 주석 해제
71-
# acm_certificate_arn = aws_acm_certificate.cdn_domain_cert.arn
72-
# ssl_support_method = "sni-only"
73-
# minimum_protocol_version = "TLSv1.2_2021"
83+
# cloudfront_default_certificate = true
84+
# ACM 인증서 사용(CDN 도메인 설정) 시 아래 주석 해제
85+
acm_certificate_arn = aws_acm_certificate_validation.cdn_domain_cert_validation.certificate_arn
86+
ssl_support_method = "sni-only"
87+
minimum_protocol_version = "TLSv1.2_2021"
7488
}
7589

7690
tags = merge(local.common_tags, {
@@ -82,17 +96,26 @@ resource "aws_cloudfront_distribution" "cloudfront_distribution" {
8296
# ACM 인증서
8397
##################
8498
# CloudFront는 us-east-1 리전에 있어야 함
85-
# fixme: CDN 도메인 설정 시 주석 해제
86-
# resource "aws_acm_certificate" "cdn_domain_cert" {
87-
# provider = "us-east-1"
88-
# domain_name = var.cdn_domain
89-
# validation_method = "DNS"
90-
#
91-
# lifecycle {
92-
# create_before_destroy = true
93-
# }
94-
#
95-
# tags = merge(local.common_tags, {
96-
# Name = "${var.prefix}-cdn-domain-cert"
97-
# })
98-
# }
99+
resource "aws_acm_certificate" "cdn_domain_cert" {
100+
provider = aws.us_east_1
101+
domain_name = var.cdn_domain
102+
key_algorithm = "EC_prime256v1"
103+
validation_method = "DNS"
104+
105+
lifecycle {
106+
create_before_destroy = true
107+
}
108+
109+
tags = merge(local.common_tags, {
110+
Name = "${var.prefix}-cdn-domain-cert"
111+
})
112+
}
113+
114+
resource "aws_acm_certificate_validation" "cdn_domain_cert_validation" {
115+
provider = aws.us_east_1
116+
certificate_arn = aws_acm_certificate.cdn_domain_cert.arn
117+
118+
timeouts {
119+
create = "1h"
120+
}
121+
}

infra/aws/terraform/ec2.tf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,10 @@ resource "aws_instance" "ec2_1" {
110110

111111
# 루트 볼륨 설정
112112
root_block_device {
113-
volume_type = "gp2"
114-
volume_size = 30 # 볼륨 크기를 30GB로 설정
115-
encrypted = true
113+
volume_type = "gp2"
114+
volume_size = 30 # 볼륨 크기를 30GB로 설정
115+
encrypted = true
116+
delete_on_termination = false
116117
}
117118

118119
user_data = local.ec2_user_data

infra/aws/terraform/main.tf

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
########################################################
2-
# 마지막 수정: 251001
2+
# 마지막 수정: 251010
33
# 작성자: gooraeng
44
#
55
# AWS 인프라를 코드로 관리하기 위한 Terraform 메인 설정 파일
@@ -29,6 +29,12 @@ provider "aws" {
2929
region = var.region
3030
}
3131

32+
# CloudFront는 us-east-1 리전의 ACM 인증서가 필요
33+
provider "aws" {
34+
alias = "us_east_1"
35+
region = "us-east-1"
36+
}
37+
3238
################
3339
# 로컬 변수
3440
################

infra/aws/terraform/outputs.tf

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,23 @@ output "cloudfront_domain" {
3333
##################
3434
# ACM 인증서 출력 (CDN 도메인 설정 시)
3535
##################
36-
# fixme: CDN 도메인 설정 시 주석 해제
37-
# output "cdn_domain_cert_arn" {
38-
# description = "ACM Certificate ARN"
39-
# value = aws_acm_certificate.cdn_domain_cert.arn
40-
# }
41-
#
42-
# output "cdn_domain_cert_status" {
43-
# description = "Certificate Status"
44-
# value = aws_acm_certificate.cdn_domain_cert.status
45-
# }
46-
#
47-
# output "cdn_domain_cert_validation_records" {
48-
# description = "DNS validation records for certificate"
49-
# value = {
50-
# for dvo in aws_acm_certificate.cdn_domain_cert.domain_validation_options : dvo.domain_name => {
51-
# name = dvo.resource_record_name
52-
# record = dvo.resource_record_value
53-
# type = dvo.resource_record_type
54-
# }
55-
# }
56-
# }
36+
output "cdn_domain_cert_arn" {
37+
description = "ACM Certificate ARN"
38+
value = aws_acm_certificate.cdn_domain_cert.arn
39+
}
40+
41+
output "cdn_domain_cert_status" {
42+
description = "Certificate Status"
43+
value = aws_acm_certificate.cdn_domain_cert.status
44+
}
45+
46+
output "cdn_domain_cert_validation_records" {
47+
description = "DNS validation records for certificate"
48+
value = {
49+
for dvo in aws_acm_certificate.cdn_domain_cert.domain_validation_options : dvo.domain_name => {
50+
name = dvo.resource_record_name
51+
record = dvo.resource_record_value
52+
type = dvo.resource_record_type
53+
}
54+
}
55+
}

infra/aws/terraform/s3.tf

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,37 +36,29 @@ resource "aws_s3_bucket_ownership_controls" "s3_1_ownership" {
3636
# S3 버킷 정책
3737
#########################
3838
# CloudFront OAI가 S3 버킷에 접근할 수 있도록 허용
39+
# EC2 인스턴스가 파일 업로드/관리 가능
40+
# AWS 계정 소유자 및 Admin 사용자 접근 허용
3941
# Presigned URL을 통한 접근 차단
4042
resource "aws_s3_bucket_policy" "s3_1_policy" {
4143
bucket = aws_s3_bucket.s3_1.id
4244
policy = jsonencode({
4345
Version = "2012-10-17",
4446
Statement = [
45-
# CloudFront가 S3 버킷에 접근할 수 있도록 허용
47+
# 1. CloudFront OAI: S3 객체 읽기 (CDN 콘텐츠 제공)
4648
{
4749
Sid = "AllowCloudFrontOAIReadOnly",
4850
Effect = "Allow",
4951
Principal = {
5052
AWS = aws_cloudfront_origin_access_identity.oai_1.iam_arn
5153
},
52-
Action = "s3:GetObject",
53-
Resource = "${aws_s3_bucket.s3_1.arn}/*"
54-
},
55-
# Presigned URL을 통한 접근 차단
56-
{
57-
Sid = "DenyPresignedUrls",
58-
Effect = "Deny",
59-
Principal = "*",
60-
Action = "s3:*",
54+
Action = [
55+
"s3:GetObject",
56+
"s3:ListBucket"
57+
],
6158
Resource = [
6259
aws_s3_bucket.s3_1.arn,
6360
"${aws_s3_bucket.s3_1.arn}/*"
64-
],
65-
Condition = {
66-
StringLike = {
67-
"s3:authType" = "REST-QUERY-STRING"
68-
}
69-
}
61+
]
7062
}
7163
]
7264
})

infra/aws/terraform/variables.tf

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@ variable "base_domain" {
2727
default = "relife.kr"
2828
}
2929

30-
# fixme: CDN 도메인 변수
31-
# variable "cdn_domain" {
32-
# description = "cdn domain"
33-
# type = string
34-
# default = "cdn.gooraeng.xyz"
35-
# }
30+
variable "cdn_domain" {
31+
description = "cdn domain"
32+
type = string
33+
default = "cdn.relife.kr"
34+
}
3635

3736
variable "encryption_type" {
3837
description = "S3 암호화 타입 (AES256, aws:kms)"

0 commit comments

Comments
 (0)