Skip to content

Commit 531ce4b

Browse files
authored
Merge pull request #239 from prgrms-web-devcourse-final-project/deployment
✨ feat: GCP 배포 관련 설정
2 parents 5361ed7 + 3111526 commit 531ce4b

File tree

8 files changed

+228
-17
lines changed

8 files changed

+228
-17
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ bin/
4848
src/main/resources/application.yml
4949
src/main/resources/application-prod.yml
5050
src/main/resources/application-local.yml
51-
src/main/resources-env/
51+
src/main/resources-env/local

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM openjdk:21-ea-oraclelinux8
2+
ARG JAR_FILE=build/libs/*.jar
3+
COPY ${JAR_FILE} app.jar
4+
ENTRYPOINT ["java","-jar","/app.jar"]

docker-compose.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
services:
2+
mysql-container:
3+
image: mysql:8.0
4+
container_name: mysql-container
5+
restart: always
6+
environment:
7+
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
8+
MYSQL_DATABASE: ittaeok
9+
MYSQL_USER: ${MYSQL_USER}
10+
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
11+
ports:
12+
- "3306:3306"
13+
volumes:
14+
- mysql_data:/var/lib/mysql
15+
networks:
16+
- app-network
17+
healthcheck:
18+
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
19+
timeout: 20s
20+
retries: 10
21+
interval: 10s
22+
start_period: 30s
23+
24+
redis-container:
25+
image: redis:8.0.3
26+
container_name: redis-container
27+
restart: always
28+
command: redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes
29+
ports:
30+
- "6379:6379"
31+
volumes:
32+
- redis_data:/data
33+
networks:
34+
- app-network
35+
healthcheck:
36+
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
37+
timeout: 3s
38+
retries: 5
39+
interval: 10s
40+
start_period: 30s
41+
42+
ittaeok-container:
43+
image: # <도커 계정명/이미지 이름>/ittaeok-gcp:latest
44+
container_name: ittaeok
45+
restart: always
46+
depends_on:
47+
mysql-container:
48+
condition: service_healthy
49+
redis-container:
50+
condition: service_healthy
51+
ports:
52+
- "80:80"
53+
- "443:443"
54+
environment:
55+
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql-container:3306/ittaeok?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul
56+
- SPRING_DATASOURCE_USERNAME=ittaeok_user
57+
- SPRING_DATASOURCE_PASSWORD=1234
58+
59+
- SPRING_DATA_REDIS_HOST=redis-container
60+
- SPRING_DATA_REDIS_PORT=6379
61+
- SPRING_DATA_REDIS_PASSWORD=${REDIS_PASSWORD}
62+
- SPRING_DATA_REDIS_SSL_ENABLED=false
63+
64+
- GOOGLE_APPLICATION_CREDENTIALS=${GOOGLE_APPLICATION_CREDENTIALS}
65+
- GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT}
66+
67+
- SPRING_CLOUD_GCP_SECRETMANAGER_ENABLED="true"
68+
- SPRING_CLOUD_GCP_PROJECT_ID=${GOOGLE_CLOUD_PROJECT}
69+
volumes:
70+
- ./gcp-key.json:/app/gcp-key.json:ro
71+
networks:
72+
- app-network
73+
74+
volumes:
75+
mysql_data:
76+
redis_data:
77+
78+
networks:
79+
app-network:
80+
driver: bridge

gradlew

100644100755
File mode changed.

src/main/java/com/grepp/spring/infra/auth/oauth2/OAuth2SuccessHandler.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.List;
1616
import lombok.RequiredArgsConstructor;
1717
import lombok.extern.slf4j.Slf4j;
18+
import org.springframework.beans.factory.annotation.Value;
1819
import org.springframework.http.ResponseCookie;
1920
import org.springframework.security.core.Authentication;
2021
import org.springframework.security.oauth2.core.user.OAuth2User;
@@ -30,11 +31,20 @@ public class OAuth2SuccessHandler extends SimpleUrlAuthenticationSuccessHandler
3031
private final AuthService authService;
3132
private final CookieAuthorizationRequestRepository cookieAuthorizationRequestRepository;
3233

34+
@Value("${front-server.domain-A}")
35+
private String frontServerDomainA;
36+
37+
@Value("${url.backend}")
38+
private String backendServer;
39+
40+
@Value("${front-server.redirect-url}")
41+
private String DEFAULT_REDIRECT_URL;
42+
3343
// 허용 도메인
3444
private final List<String> ALLOWED_DOMAINS = Arrays.asList(
35-
"https://localhost:3000", // frontend 로컬 도메인
36-
"https://ittaeok.uk/" // 실제 배포 도메인
37-
45+
frontServerDomainA, // frontend 로컬 도메인
46+
backendServer,
47+
"https://localhost:3000"
3848
);
3949

4050
@Override
@@ -68,7 +78,6 @@ protected String determineTargetUrl(HttpServletRequest request, HttpServletRespo
6878

6979
// 'redirect_uri' 쿠키에서 uri를 가져오기
7080
// redirect uri 지정하지 않을 경우. 추후 실제 배포 도메인으로 변경해야 함.
71-
String DEFAULT_REDIRECT_URL = "https://localhost:3000/auth/callback";
7281
String redirectUri = CookieUtils.getCookie(request, CookieAuthorizationRequestRepository.REDIRECT_URI_PARAM_COOKIE_NAME)
7382
.map(Cookie::getValue)
7483
.orElse(DEFAULT_REDIRECT_URL); // 쿠키에 uri 없으면 default 로 이동

src/main/java/com/grepp/spring/infra/config/SwaggerConfig.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
package com.grepp.spring.infra.config;
22

33
import com.grepp.spring.infra.auth.CurrentUser;
4-
import io.swagger.v3.oas.models.Operation;
5-
import io.swagger.v3.oas.models.info.Info;
64
import io.swagger.v3.oas.models.Components;
75
import io.swagger.v3.oas.models.OpenAPI;
6+
import io.swagger.v3.oas.models.Operation;
7+
import io.swagger.v3.oas.models.info.Info;
88
import io.swagger.v3.oas.models.media.Content;
99
import io.swagger.v3.oas.models.media.MediaType;
1010
import io.swagger.v3.oas.models.media.Schema;
11-
import io.swagger.v3.oas.models.parameters.HeaderParameter;
1211
import io.swagger.v3.oas.models.responses.ApiResponse;
1312
import io.swagger.v3.oas.models.security.SecurityRequirement;
1413
import io.swagger.v3.oas.models.security.SecurityScheme;
14+
import io.swagger.v3.oas.models.servers.Server;
1515
import org.springdoc.core.customizers.OperationCustomizer;
16+
import org.springframework.beans.factory.annotation.Value;
1617
import org.springframework.context.annotation.Bean;
1718
import org.springframework.context.annotation.Configuration;
1819
import org.springframework.web.method.HandlerMethod;
@@ -21,6 +22,9 @@
2122
@Configuration
2223
public class SwaggerConfig {
2324

25+
@Value("${url.backend}")
26+
private String backendServer;
27+
2428
@Bean
2529
public OperationCustomizer customizeOperation() {
2630
return (Operation operation, HandlerMethod handlerMethod) -> {
@@ -62,7 +66,8 @@ public OpenAPI openApiSpec() {
6266
.description(
6367
"JWT 토큰을 입력하세요. Bearer 는 생략하세요")
6468
))
65-
.addSecurityItem(new SecurityRequirement().addList("bearerAuth"));
69+
.addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
70+
.addServersItem(new Server().url(backendServer));
6671

6772
}
6873

@@ -77,4 +82,4 @@ public OperationCustomizer operationCustomizer() {
7782
return operation;
7883
};
7984
}
80-
}
85+
}

src/main/java/com/grepp/spring/infra/config/WebConfig.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,28 @@ public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers)
2121
resolvers.add(currentUserArgumentResolver);
2222
}
2323

24-
// 2025.7.11 기준 Front Server 테스트 주소인 https://localhost:3000 이 들어가야 합니다.
25-
// 빌드 시 application.yml 를 확인해주세요.
26-
@Value("${front-server.domain}")
27-
private String frontServer;
24+
@Value("${front-server.domain-A}")
25+
private String frontServerDomainA;
26+
27+
@Value("${front-server.domain-B}")
28+
private String frontServerDomainB;
29+
30+
@Value("${url.backend}")
31+
private String backendServer;
2832

2933
@Override
3034
public void addCorsMappings(CorsRegistry registry) {
3135
registry.addMapping("/**")
32-
.allowedOrigins(frontServer,
33-
"http://localhost:8080")
34-
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
36+
.allowedOrigins(
37+
frontServerDomainA,
38+
frontServerDomainB,
39+
backendServer,
40+
"http://localhost:80",
41+
"http://localhost:8080",
42+
"http://localhost:3000",
43+
"https://localhost:3000"
44+
)
45+
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")
3546
.allowedHeaders("*")
3647
.allowCredentials(true)
3748
.maxAge(3600);
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
server:
2+
port: 80
3+
4+
spring:
5+
datasource:
6+
url: ${sm://db-url}
7+
username: ${sm://db-username}
8+
password: ${sm://db-password}
9+
hikari:
10+
connection-timeout: 30000
11+
maximum-pool-size: 10
12+
driver-class-name: com.mysql.cj.jdbc.Driver
13+
jpa:
14+
hibernate:
15+
ddl-auto: update
16+
open-in-view: false
17+
properties:
18+
hibernate:
19+
jdbc:
20+
lob:
21+
non_contextual_creation: true
22+
id:
23+
new_generator_mappings: true
24+
docker:
25+
compose:
26+
lifecycle-management: start-only
27+
data:
28+
redis:
29+
host: ${sm://redis-host}
30+
port: ${sm://redis-port}
31+
username: default
32+
password: ${sm://redis-password}
33+
ssl:
34+
enabled: true
35+
security:
36+
oauth2:
37+
client:
38+
registration:
39+
google:
40+
client-name: google
41+
client-id: ${sm://google-client-id}
42+
client-secret: ${sm://google-client-secret}
43+
redirect-uri: "https://api.ittaeok.com/login/oauth2/code/{registrationId}" # SM 붙이기
44+
authorization-grant-type: authorization_code
45+
scope:
46+
- openid
47+
- email
48+
- profile
49+
kakao:
50+
client-name: kakao
51+
client-id: ${sm://kakao-client-id}
52+
client-secret: ${sm://kakao-client-secret}
53+
redirect-uri: "https://api.ittaeok.com/login/oauth2/code/{registrationId}" # SM 붙이기
54+
authorization-grant-type: authorization_code
55+
client-authentication-method: client_secret_post
56+
scope:
57+
- profile_nickname
58+
- account_email
59+
provider:
60+
kakao:
61+
authorization-uri: https://kauth.kakao.com/oauth/authorize
62+
token-uri: https://kauth.kakao.com/oauth/token
63+
user-info-uri: https://kapi.kakao.com/v2/user/me
64+
user-name-attribute: id
65+
springdoc:
66+
pathsToMatch: /api/**
67+
jwt:
68+
expiration: 604800000
69+
refresh-expiration: 704800000
70+
secret: ${sm://jwt-secret}
71+
google:
72+
calendar:
73+
client-id: ${sm://google-client-id}
74+
client-secret: ${sm://google-client-secret}
75+
redirect-uri: "https://api.ittaeok.com/oauth2/callback/google-calendar" # SM 붙이기
76+
api:
77+
key: ${sm://google-api-key}
78+
zoom:
79+
client-id: ${sm://zoom-client-id}
80+
client-secret: ${sm://zoom-client-secret}
81+
redirect-uri: ${sm://zoom-redirect-uri}
82+
refresh-token: ${sm://zoom-refresh-token}
83+
kakao:
84+
middle-location:
85+
api-key: ${sm://kakao-api-key}
86+
logging:
87+
level:
88+
org.springframework.cloud.gcp.secretmanager: DEBUG
89+
root: info
90+
org:
91+
hibernate:
92+
SQL: info
93+
type:
94+
descriptor:
95+
sql: info
96+
97+
url:
98+
backend: https://api.ittaeok.com # SM 붙이기
99+
front-server:
100+
domain-A: https://ittaeok.com # SM 붙이기
101+
domain-B: https://www.ittaeok.com # SM 붙이기
102+
redirect-url: https://ittaeok.com/auth/callback # SM 붙이기

0 commit comments

Comments
 (0)