Skip to content

Commit 9d3f229

Browse files
committed
Feat: Migrate static file storage to Cloudflare R2
1 parent 32af09e commit 9d3f229

File tree

8 files changed

+52
-103
lines changed

8 files changed

+52
-103
lines changed

.github/workflows/dev-deploy.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,12 @@ jobs:
6969
-e 'MONGODB_URI_DEV=${{ secrets.MONGODB_URI_DEV }}' \
7070
-e MONGODB_DATABASE_DEV=${{ secrets.MONGODB_DATABASE_DEV }} \
7171
-e S3_REGION=${{ secrets.S3_REGION }} \
72-
-e S3_STATIC_NAME=${{ secrets.S3_STATIC_NAME }} \
7372
-e S3_AI_INPUT_NAME=${{ vars.S3_AI_INPUT_NAME }} \
7473
-e S3_AI_OUTPUT_NAME=${{ vars.S3_AI_OUTPUT_NAME }} \
74+
-e CF_R2_ENDPOINT=${{ vars.CF_R2_ENDPOINT }} \
75+
-e CF_R2_ACCESS_KEY=${{ secrets.CF_R2_ACCESS_KEY }} \
76+
-e CF_R2_SECRET_KEY=${{ secrets.CF_R2_SECRET_KEY }} \
77+
-e CF_R2_STATIC_BUCKET=${{ vars.CF_R2_STATIC_BUCKET }} \
7578
-e IMPORT_API_KEY=${{ secrets.IMPORT_API_KEY }} \
7679
-e AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }} \
7780
-e AWS_SECRET_KEY=${{ secrets.AWS_SECRET_KEY }} \

.github/workflows/prod-deploy.yml

Lines changed: 0 additions & 75 deletions
This file was deleted.

src/main/java/com/linglevel/api/auth/filter/TestAuthFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import java.util.Optional;
2121

2222
@Component
23-
@Profile({"dev", "local"})
23+
@Profile({"local"})
2424
public class TestAuthFilter extends OncePerRequestFilter {
2525

2626
private final UserRepository userRepository;

src/main/java/com/linglevel/api/s3/config/S3Config.java

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
import software.amazon.awssdk.regions.Region;
99
import software.amazon.awssdk.services.s3.S3Client;
1010

11+
import java.net.URI;
12+
1113
@Configuration
1214
public class S3Config {
1315

16+
// AWS S3 Configuration (for AI buckets)
1417
@Value("${aws.s3.region}")
1518
private String region;
1619

@@ -20,23 +23,51 @@ public class S3Config {
2023
@Value("${aws.secret-key}")
2124
private String secretKey;
2225

23-
@Value("${aws.s3.static.bucket}")
24-
private String staticBucketName;
25-
2626
@Value("${aws.s3.ai.input.bucket}")
2727
private String aiInputBucketName;
2828

2929
@Value("${aws.s3.ai.output.bucket}")
3030
private String aiOutputBucketName;
3131

32+
// Cloudflare R2 Configuration (for Static files)
33+
@Value("${cf.r2.endpoint}")
34+
private String r2Endpoint;
35+
36+
@Value("${cf.r2.access-key}")
37+
private String r2AccessKey;
38+
39+
@Value("${cf.r2.secret-key}")
40+
private String r2SecretKey;
41+
42+
@Value("${cf.r2.static.bucket}")
43+
private String r2StaticBucketName;
44+
45+
/**
46+
* AWS S3 클라이언트 (AI Input/Output 버킷용)
47+
*/
3248
@Bean("s3AiClient")
3349
public S3Client s3AiClient() {
34-
return createS3Client();
50+
AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);
51+
52+
return S3Client.builder()
53+
.region(Region.of(region))
54+
.credentialsProvider(StaticCredentialsProvider.create(credentials))
55+
.build();
3556
}
3657

58+
/**
59+
* Cloudflare R2 클라이언트 (Static 파일용)
60+
* R2는 S3 호환 API를 제공하므로 endpoint만 변경하면 됩니다.
61+
*/
3762
@Bean("s3StaticClient")
3863
public S3Client s3StaticClient() {
39-
return createS3Client();
64+
AwsBasicCredentials credentials = AwsBasicCredentials.create(r2AccessKey, r2SecretKey);
65+
66+
return S3Client.builder()
67+
.endpointOverride(URI.create(r2Endpoint))
68+
.region(Region.of("auto")) // R2는 auto region 사용
69+
.credentialsProvider(StaticCredentialsProvider.create(credentials))
70+
.build();
4071
}
4172

4273
@Bean("aiInputBucketName")
@@ -51,15 +82,6 @@ public String aiOutputBucketName() {
5182

5283
@Bean("staticBucketName")
5384
public String staticBucketName() {
54-
return staticBucketName;
55-
}
56-
57-
private S3Client createS3Client() {
58-
AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);
59-
60-
return S3Client.builder()
61-
.region(Region.of(region))
62-
.credentialsProvider(StaticCredentialsProvider.create(credentials))
63-
.build();
85+
return r2StaticBucketName;
6486
}
6587
}

src/main/resources/application-dev.properties

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,3 @@ swagger.servers=https://dev.linglevel.com
2121
# Swagger Login Configuration
2222
api.docs.user.username=${SWAGGER_USERNAME}
2323
api.docs.user.password=${SWAGGER_PASSWORD}
24-
25-
# S3 URL
26-
aws.s3.static.url=https://s3.${S3_REGION}.amazonaws.com/${S3_STATIC_NAME}

src/main/resources/application-local.properties

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,3 @@ swagger.servers=http://localhost:8080
2323
# Swagger Login Configuration
2424
api.docs.user.username=${SWAGGER_USERNAME}
2525
api.docs.user.password=${SWAGGER_PASSWORD}
26-
27-
# S3 URL
28-
aws.s3.static.url=https://s3.${S3_REGION}.amazonaws.com/${S3_STATIC_NAME}

src/main/resources/application-prod.properties

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,3 @@ logging.level.root=INFO
1717
springdoc.swagger-ui.enabled=false
1818
springdoc.api-docs.enabled=false
1919
swagger.servers=https://api.linglevel.com
20-
21-
# S3 URL
22-
aws.s3.static.url=https://static.linglevel.com

src/main/resources/application.properties

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,19 @@ firebase.config=${FIREBASE_CONFIG_BASE64}
5151
# Redis
5252
spring.data.redis.ssl.enabled=false
5353

54-
# S3
54+
# AWS S3 (AI Input/Output buckets)
5555
aws.s3.region=${S3_REGION}
5656
aws.s3.ai.input.bucket=${S3_AI_INPUT_NAME}
5757
aws.s3.ai.output.bucket=${S3_AI_OUTPUT_NAME}
58-
aws.s3.static.bucket=${S3_STATIC_NAME}
58+
59+
# Cloudflare R2 (Static files)
60+
cf.r2.endpoint=${CF_R2_ENDPOINT}
61+
cf.r2.access-key=${CF_R2_ACCESS_KEY}
62+
cf.r2.secret-key=${CF_R2_SECRET_KEY}
63+
cf.r2.static.bucket=${CF_R2_STATIC_BUCKET}
64+
65+
# R2 Public URL (Common for all environments)
66+
aws.s3.static.url=https://static.linglevel.com
5967

6068
# Sentry
6169
sentry.dsn=${SENTRY_DSN}

0 commit comments

Comments
 (0)