From 496558e1323a3ee44bba9616a8dd3081d807e107 Mon Sep 17 00:00:00 2001 From: namgigun Date: Mon, 29 Sep 2025 10:50:06 +0900 Subject: [PATCH 1/4] =?UTF-8?q?Infra:=20=EC=9A=B4=EC=98=81=ED=99=98?= =?UTF-8?q?=EA=B2=BD(application-prod.yml)=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - redis 설정 추가 - Oauth 설정 추가 - logging 설정 변경 - 스터디룸 설정 추가 --- src/main/resources/application-prod.yml | 96 ++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 10 deletions(-) diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 3bb300f2..d35b7738 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -1,22 +1,98 @@ spring: - jpa: - database-platform: org.hibernate.dialect.MySQLDialect - hibernate: - ddl-auto: update # [none | validate | update | create | create-drop] - - config: - import: optional:file:.env[.properties] - datasource: url: jdbc:mysql://${MYSQL_HOST}:3306/${MYSQL_DATABASE}?serverTimezone=Asia/Seoul&characterEncoding=UTF-8 driver-class-name: com.mysql.cj.jdbc.Driver username: ${MYSQL_USERNAME} password: ${MYSQL_PASSWORD} + data: + redis: + host: redis_1 + port: 6379 + + config: + import: optional:file:.env[.properties] + + jpa: + database-platform: org.hibernate.dialect.MySQLDialect + hibernate: + ddl-auto: update # [none | validate | update | create | create-drop] + + security: + oauth2: + client: + registration: + kakao: + client-id: ${KAKAO_CLIENT_ID} + authorization-grant-type: authorization_code + client-name: Kakao + redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" + scope: profile_nickname, profile_image, account_email + naver: + client-id: ${NAVER_CLIENT_ID} + client-secret: ${NAVER_CLIENT_SECRET} + client-name: Naver + authorization-grant-type: authorization_code + redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" + scope: email, nickname, profile_image + google: + client-id: ${GOOGLE_CLIENT_ID} + client-secret: ${GOOGLE_CLIENT_SECRET} + client-name: Google + authorization-grant-type: authorization_code + redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" + scope: + - email + - profile + github: + client-id: ${GITHUB_CLIENT_ID} + client-secret: ${GITHUB_CLIENT_SECRET} + client-name: GitHub + authorization-grant-type: authorization_code + redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" + scope: user:email + provider: + kakao: + authorization-uri: https://kauth.kakao.com/oauth/authorize + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + user-name-attribute: id + naver: + authorization-uri: https://nid.naver.com/oauth2.0/authorize + token-uri: https://nid.naver.com/oauth2.0/token + user-info-uri: https://openapi.naver.com/v1/nid/me + user-name-attribute: response + google: + authorization-uri: https://accounts.google.com/o/oauth2/v2/auth + token-uri: https://oauth2.googleapis.com/token + user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo + user-name-attribute: sub + github: + authorization-uri: https://github.com/login/oauth/authorize + token-uri: https://github.com/login/oauth/access_token + user-info-uri: https://api.github.com/user + user-name-attribute: id + springdoc: default-produces-media-type: application/json;charset=UTF-8 +logging: + level: + org.hibernate.orm.jdbc.bind: OFF + org.springframework.web.socket: INFO + org.springframework.messaging: INFO + jwt: - secret: ${JWT_SECRET:test-jwt-secret-key-12345678901234567890} # 운영 시에는 반드시 환경 변수로 설정할 것 + secret: ${JWT_SECRET} # 운영 시에는 반드시 환경 변수로 설정할 것 access-token-expiration: ${JWT_ACCESS_TOKEN_EXPIRATION:1800} # 30분 (초 단위) - refresh-token-expiration: ${JWT_REFRESH_TOKEN_EXPIRATION:604800} # 7일 (초 단위) \ No newline at end of file + refresh-token-expiration: ${JWT_REFRESH_TOKEN_EXPIRATION:604800} # 7일 (초 단위) + +# 스터디룸 설정 +studyroom: + heartbeat: + timeout-minutes: 5 # Heartbeat 타임아웃 (분) + default: + max-participants: 10 # 기본 최대 참가자 수 + allow-camera: true + allow-audio: true + allow-screen-share: true \ No newline at end of file From 74d2005772bdf8bab58c407b65b56687e2e918b1 Mon Sep 17 00:00:00 2001 From: namgigun Date: Mon, 29 Sep 2025 11:31:44 +0900 Subject: [PATCH 2/4] =?UTF-8?q?Infra:=20EmbeddedRedisConfig=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 작업환경 정보 출력 - 기존 : 맥 환경이면 embedded-redis 비활성화 -> 변경 : 맥 환경이거나 현재 운영환경인 경우 embedded-redis 비활성화 --- .../com/back/global/config/EmbeddedRedisConfig.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/back/global/config/EmbeddedRedisConfig.java b/src/main/java/com/back/global/config/EmbeddedRedisConfig.java index 16d15044..f8fa4067 100644 --- a/src/main/java/com/back/global/config/EmbeddedRedisConfig.java +++ b/src/main/java/com/back/global/config/EmbeddedRedisConfig.java @@ -2,6 +2,7 @@ import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; +import lombok.extern.log4j.Log4j2; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import redis.embedded.RedisServer; @@ -17,6 +18,7 @@ */ @Configuration @Profile({"dev", "test"}) +@Log4j2 public class EmbeddedRedisConfig { private RedisServer redisServer; @@ -26,10 +28,12 @@ public class EmbeddedRedisConfig { public void startRedis() { try { String osName = System.getProperty("os.name").toLowerCase(); + String activeProfile = System.getProperty("spring.profiles.active", "dev"); + log.info("현재환경: " + activeProfile); - // Mac 환경이면 embedded-redis 건너뛰고 docker-compose Redis 사용 - if (osName.contains("mac")) { - System.out.println("Mac 환경 감지 → embedded-redis 비활성화, docker-compose Redis 사용"); + // 운영환경/Mac 환경이라면 embedded-redis 비활성화 + if (osName.contains("mac") || "prod".equalsIgnoreCase(activeProfile)) { + log.info("운영환경/Mac 환경 감지 → embedded-redis 비활성화, 일반 Redis 사용"); System.setProperty("spring.data.redis.port", "6379"); // docker-compose 기본 포트 return; } From bcff6dc127285fd6c0c8110ad1b623b0e8dbf222 Mon Sep 17 00:00:00 2001 From: namgigun Date: Mon, 29 Sep 2025 11:53:35 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Infra:=20AWS=20=EC=9D=B8=EC=8A=A4=ED=84=B4?= =?UTF-8?q?=EC=8A=A4=20Tags=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tags { Key = "Team" Value = "devcos-teamxx" Name = "인스턴스 name" } --- .gitignore | 3 +- infra/terraform/main.tf | 64 ++++++++++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 9fe0ab55..66ad2d9d 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,5 @@ db_dev.trace.db /infra/terraform/.terraform /infra/terraform/.terraform.lock.hcl /infra/terraform/terraform.tfstate -/infra/terraform/terraform.tfstate.backup \ No newline at end of file +/infra/terraform/terraform.tfstate.backup +/infra/terraform/secrets.tf \ No newline at end of file diff --git a/infra/terraform/main.tf b/infra/terraform/main.tf index a7d4af9b..f754fec0 100644 --- a/infra/terraform/main.tf +++ b/infra/terraform/main.tf @@ -19,7 +19,9 @@ resource "aws_vpc" "vpc_1" { enable_dns_hostnames = true tags = { - Name = "team5-vpc-1" + Key = "TEAM" + Value = "devcos-team05" + Name = "vpc-1" } } @@ -31,7 +33,9 @@ resource "aws_subnet" "subnet_1" { map_public_ip_on_launch = true # 퍼블릭 IP 자동 할당 tags = { - Name = "team5-subnet-1-public" + Key = "TEAM" + Value = "devcos-team05" + Name = "subnet-1-public" } } @@ -42,7 +46,9 @@ resource "aws_subnet" "subnet_2" { availability_zone = "ap-northeast-2a" tags = { - Name = "team5-subnet-2-private" + Key = "TEAM" + Value = "devcos-team05" + Name = "subnet-2-private" } } @@ -53,7 +59,9 @@ resource "aws_subnet" "subnet_3" { availability_zone = "ap-northeast-2b" tags = { - Name = "team5-subnet-3-private" + Key = "TEAM" + Value = "devcos-team05" + Name = "subnet-3-private" } } @@ -62,7 +70,9 @@ resource "aws_internet_gateway" "igw_1" { vpc_id = aws_vpc.vpc_1.id tags = { - Name = "team5-igw-1" + Key = "TEAM" + Value = "devcos-team05" + Name = "igw-1" } } @@ -77,7 +87,9 @@ resource "aws_route_table" "rt_1" { } tags = { - Name = "team5-rt-1" + Key = "TEAM" + Value = "devcos-team05" + Name = "rt-1" } } @@ -104,9 +116,15 @@ resource "aws_route_table_association" "association_3" { } resource "aws_security_group" "sg_1" { - name = "team5-sg-1" + name = "team5-sg-1" vpc_id = aws_vpc.vpc_1.id + tags = { + Key = "TEAM" + Value = "devcos-team05" + Name = "sg-1" + } + ingress { from_port = 0 to_port = 0 @@ -124,7 +142,11 @@ resource "aws_security_group" "sg_1" { # EC2 역할 생성 resource "aws_iam_role" "ec2_role_1" { - name = "team5-ec2-role-1" + tags = { + Key = "TEAM" + Value = "devcos-team05" + Name = "ec2-role-1" + } # 이 역할에 대한 신뢰 정책 설정. EC2 서비스가 이 역할을 가정할 수 있도록 설정 assume_role_policy = <> /etc/fstab' + END_OF_FILE } @@ -189,7 +217,9 @@ resource "aws_instance" "ec2_1" { iam_instance_profile = aws_iam_instance_profile.instance_profile_1.name tags = { - Name = "team5-ec2-1" + Key = "TEAM" + Value = "devcos-team05" + Name = "ec2-1" } # 루트 불륨 설정 @@ -206,7 +236,7 @@ EOF # RDS용 Security Group resource "aws_security_group" "rds_sg_1" { - name = "team5-rds-sg-1" + name = "team5-rds-sg-1" description = "Allow All" vpc_id = aws_vpc.vpc_1.id @@ -225,7 +255,9 @@ resource "aws_security_group" "rds_sg_1" { } tags = { - Name = "team5-rds-sg-1" + Key = "TEAM" + Value = "devcos-team05" + Name = "rds-sg-1" } } @@ -235,7 +267,9 @@ resource "aws_db_subnet_group" "db_subnet_group" { subnet_ids = [aws_subnet.subnet_2.id, aws_subnet.subnet_3.id] tags = { - Name = "team5-db-subnet-group" + Key = "TEAM" + Value = "devcos-team05" + Name = "db-subnet-group" } } @@ -264,6 +298,8 @@ resource "aws_db_instance" "mysql" { skip_final_snapshot = true tags = { - Name = "team5-rds-mysql" + Key = "TEAM" + Value = "devcos-team05" + Name = "mysql" } } \ No newline at end of file From ab1075aed4b869ca5982fe1b1ce2b7b95aff79c3 Mon Sep 17 00:00:00 2001 From: namgigun Date: Mon, 29 Sep 2025 15:42:28 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Infra:=20EC2=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Redis 설치 - NginX 설치 --- infra/terraform/main.tf | 108 +++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 39 deletions(-) diff --git a/infra/terraform/main.tf b/infra/terraform/main.tf index f754fec0..2360153e 100644 --- a/infra/terraform/main.tf +++ b/infra/terraform/main.tf @@ -19,9 +19,9 @@ resource "aws_vpc" "vpc_1" { enable_dns_hostnames = true tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "vpc-1" + Name = "team5-vpc-1" } } @@ -33,9 +33,9 @@ resource "aws_subnet" "subnet_1" { map_public_ip_on_launch = true # 퍼블릭 IP 자동 할당 tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "subnet-1-public" + Name = "team5-subnet-1-public" } } @@ -46,9 +46,9 @@ resource "aws_subnet" "subnet_2" { availability_zone = "ap-northeast-2a" tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "subnet-2-private" + Name = "team5-subnet-2-private" } } @@ -59,9 +59,9 @@ resource "aws_subnet" "subnet_3" { availability_zone = "ap-northeast-2b" tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "subnet-3-private" + Name = "team5-subnet-3-private" } } @@ -70,9 +70,9 @@ resource "aws_internet_gateway" "igw_1" { vpc_id = aws_vpc.vpc_1.id tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "igw-1" + Name = "team5-igw-1" } } @@ -87,9 +87,9 @@ resource "aws_route_table" "rt_1" { } tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "rt-1" + Name = "team5-rt-1" } } @@ -116,13 +116,13 @@ resource "aws_route_table_association" "association_3" { } resource "aws_security_group" "sg_1" { - name = "team5-sg-1" - vpc_id = aws_vpc.vpc_1.id + name = "team5-sg-1" + vpc_id = aws_vpc.vpc_1.id tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "sg-1" + Name = "team5-sg-1" } ingress { @@ -143,9 +143,9 @@ resource "aws_security_group" "sg_1" { # EC2 역할 생성 resource "aws_iam_role" "ec2_role_1" { tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "ec2-role-1" + Name = "team5-ec2-role-1" } # 이 역할에 대한 신뢰 정책 설정. EC2 서비스가 이 역할을 가정할 수 있도록 설정 @@ -175,9 +175,9 @@ resource "aws_iam_role_policy_attachment" "ec2_ssm" { # IAM 인스턴스 프로파일 생성 resource "aws_iam_instance_profile" "instance_profile_1" { tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "instance-profile-1" + Name = "team5-instance-profile-1" } role = aws_iam_role.ec2_role_1.name @@ -187,18 +187,48 @@ resource "aws_iam_instance_profile" "instance_profile_1" { locals { ec2_user_data_base = <<-END_OF_FILE #!/bin/bash -yum install docker -y -systemctl enable docker -systemctl start docker - -yum install git -y - +# 가상 메모리 4GB 설정 sudo dd if=/dev/zero of=/swapfile bs=128M count=32 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile sudo sh -c 'echo "/swapfile swap swap defaults 0 0" >> /etc/fstab' +# git 설치 +yum install git -y + +#도커 설치 및 실행/활성화 +yum install docker -y +systemctl enable docker +systemctl start docker + +# 도커 네트워크 생성 +docker network create common + +# redis 설치 +docker run -d \ + --name redis_1 \ + --network common \ + -p 6379:6379 \ + -e TZ=Asia/Seoul \ + -v /dockerProjects/redis_1/volumes/data:/data \ + redis --requirepass ${var.password_1} + +# NginX 설치 +docker run -d \ + --name npm_1 \ + --restart unless-stopped \ + --network common \ + -p 80:80 \ + -p 443:443 \ + -p 81:81 \ + -e TZ=Asia/Seoul \ + -e INITIAL_ADMIN_EMAIL=admin@npm.com \ + -e INITIAL_ADMIN_PASSWORD=${var.password_1} \ + -v /dockerProjects/npm_1/volumes/data:/data \ + -v /dockerProjects/npm_1/volumes/etc/letsencrypt:/etc/letsencrypt \ + jc21/nginx-proxy-manager:latest + END_OF_FILE } @@ -217,9 +247,9 @@ resource "aws_instance" "ec2_1" { iam_instance_profile = aws_iam_instance_profile.instance_profile_1.name tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "ec2-1" + Name = "team5-ec2-1" } # 루트 불륨 설정 @@ -236,14 +266,14 @@ EOF # RDS용 Security Group resource "aws_security_group" "rds_sg_1" { - name = "team5-rds-sg-1" + name = "team5-rds-sg-1" description = "Allow All" vpc_id = aws_vpc.vpc_1.id ingress { - from_port = 3306 - to_port = 3306 - protocol = "tcp" + from_port = 3306 + to_port = 3306 + protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } @@ -255,9 +285,9 @@ resource "aws_security_group" "rds_sg_1" { } tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "rds-sg-1" + Name = "team5-rds-sg-1" } } @@ -267,9 +297,9 @@ resource "aws_db_subnet_group" "db_subnet_group" { subnet_ids = [aws_subnet.subnet_2.id, aws_subnet.subnet_3.id] tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "db-subnet-group" + Name = "team5-db-subnet-group" } } @@ -294,12 +324,12 @@ resource "aws_db_instance" "mysql" { # 자동 백업 보관 기간 backup_retention_period = 1 - # 삭제 시 최종 스냅샷 생성 여부 (개발용은 true, 운영은 false 권장) + # 삭제 시 최종 스냅샷 생성 여부 skip_final_snapshot = true tags = { - Key = "TEAM" + Key = "TEAM" Value = "devcos-team05" - Name = "mysql" + Name = "team5-mysql" } } \ No newline at end of file