[ADD] AWS 프로덕션 설정 파일 및 FileSystemStorageProvider 클래스 추가, EKS 배포를 위한 Kubernetes 매니페스트 생성

main
bjkim 2 months ago
parent 28aade2280
commit 92250f29d8

@ -0,0 +1,57 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: autoflow-server
namespace: autoflow
spec:
replicas: 1
selector:
matchLabels:
app: autoflow-server
template:
metadata:
labels:
app: autoflow-server
spec:
containers:
- name: autoflow-server
# [수정] 외부 레지스트리 주소를 제거하고 로컬 태그만 사용
image: autoflow-server:latest
# [추가] 외부에서 이미지를 다운로드하지 않고 로컬 이미지를 사용하도록 강제
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: RDS_HOSTNAME
# [수정 필요] Outpost 내부 RDS의 Private IP 또는 DNS를 입력하세요.
value: "INTERNAL_RDS_IP_HERE"
- name: RDS_USERNAME
value: "admin"
- name: RDS_PASSWORD
valueFrom:
secretKeyRef:
name: autoflow-secrets
key: rds-password
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: autoflow-secrets
key: jwt-secret
- name: S3_BUCKET_NAME
# [수정 필요] Outpost 내 생성한 S3 버킷 명을 입력하세요.
value: "autoflow-outpost-bucket"
---
apiVersion: v1
kind: Service
metadata:
name: autoflow-server-svc
namespace: autoflow
spec:
# Outpost EKS 환경에 따라 LoadBalancer 또는 NodePort를 선택하세요.
type: LoadBalancer
selector:
app: autoflow-server
ports:
- protocol: TCP
port: 80
targetPort: 8080

@ -0,0 +1,105 @@
package kr.re.etri.autoflow.service.storage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
@Service("storageProvider")
@ConditionalOnProperty(name = "storage.provider", havingValue = "filesystem")
public class FileSystemStorageProvider implements StorageProvider {
@Value("${storage.local.base-path:./storage}")
private String basePath;
@Value("${storage.local.default-bucket:mlpipeline}")
private String defaultBucket;
private String getTargetDir(String bucketName) {
String bucket = (bucketName == null || bucketName.isEmpty()) ? defaultBucket : bucketName;
return Paths.get(basePath, bucket).toString();
}
@Override
public void uploadFile(String bucketName, String objectName, InputStream is, String contentType, long size, String type) throws Exception {
String targetDir = getTargetDir(bucketName);
Path targetPath = Paths.get(targetDir, objectName);
Files.createDirectories(targetPath.getParent());
Files.copy(is, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
@Override
public void uploadFileToDefault(String objectName, InputStream is, String contentType, long size) throws Exception {
uploadFile(null, objectName, is, contentType, size, null);
}
@Override
public byte[] downloadFile(String bucketName, String objectName, String type) throws Exception {
String targetDir = getTargetDir(bucketName);
Path targetPath = Paths.get(targetDir, objectName);
return Files.readAllBytes(targetPath);
}
@Override
public byte[] downloadFileFromDefault(String objectName) throws Exception {
return downloadFile(null, objectName, null);
}
@Override
public File downloadFileToServer(String bucketName, String objectName, String localPath, String type) throws Exception {
String targetDir = getTargetDir(bucketName);
Path sourcePath = Paths.get(targetDir, objectName);
File localDir = new File(localPath);
if (!localDir.exists()) localDir.mkdirs();
String fileName = Paths.get(objectName).getFileName().toString();
Path destinationPath = Paths.get(localPath, fileName);
Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
return destinationPath.toFile();
}
@Override
public String readYamlText(String bucketName, String objectName, String type) throws Exception {
byte[] bytes = downloadFile(bucketName, objectName, type);
return new String(bytes, StandardCharsets.UTF_8);
}
@Override
public String readYamlTextFromDefault(String objectName) throws Exception {
return readYamlText(null, objectName, null);
}
@Override
public void deleteFile(String bucketName, String objectName, String type) throws Exception {
String targetDir = getTargetDir(bucketName);
Path targetPath = Paths.get(targetDir, objectName);
Files.deleteIfExists(targetPath);
}
@Override
public void deleteFileFromDefault(String objectName) throws Exception {
deleteFile(null, objectName, null);
}
@Override
public String getFileUrl(String bucketName, String objectName, String type) {
// 로컬 파일 경로를 URL로 반환하거나 상대 경로로 반환
// 프론트엔드에서 접근 가능한 경로여야 할 경우 추가적인 서블릿 설정이 필요할 수 있음
String targetDir = getTargetDir(bucketName);
return Paths.get(targetDir, objectName).toAbsolutePath().toUri().toString();
}
}

@ -0,0 +1,40 @@
# AWS Production Configuration
server.port = 8080
server.servlet.context-path=/autoflow-server-mgmt
spring.profiles.active=prod
# RDS MariaDB Configuration
# Replace with your RDS endpoint
spring.datasource.url=jdbc:mariadb://${RDS_HOSTNAME}:3306/autoflow
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.username=${RDS_USERNAME}
spring.datasource.password=${RDS_PASSWORD}
spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
spring.jpa.hibernate.ddl-auto=none
spring.sql.init.mode=never
# App Properties (JWT) - Should be injected via env variables in K8s
cuuva.app.jwtCookieName=cuuva-jwt
cuuva.app.jwtRefreshCookieName=cuuva-jwt-refresh
cuuva.app.jwtSecret=${JWT_SECRET}
# Storage Provider (S3)
storage.provider=s3
cloud.aws.region.static=ap-northeast-2
cloud.aws.s3.bucket=${S3_BUCKET_NAME}
# IAM Role should be used instead of hardcoded keys in EKS
# cloud.aws.credentials.access-key=${AWS_ACCESS_KEY}
# cloud.aws.credentials.secret-key=${AWS_SECRET_KEY}
# Swagger UI
springdoc.swagger-ui.path=/swagger-ui
springdoc.swagger-ui.config-url=/autoflow-server-mgmt/v3/api-docs/swagger-config
springdoc.swagger-ui.url=/autoflow-server-mgmt/v3/api-docs
springdoc.swagger-ui.doc-expansion=none
springdoc.swagger-ui.disable-swagger-default-url=true
# Multipart limit
spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB

@ -50,9 +50,13 @@ spring.servlet.multipart.max-request-size=500MB
springdoc.swagger-ui.tags-sorter=alpha
# Storage Provider (minio or s3)
# Storage Provider (minio, s3, or filesystem)
storage.provider=minio
# Local FileSystem ??
storage.local.base-path=./storage
storage.local.default-bucket=mlpipeline
# MinIO ??
minio.endpoint=http://192.168.10.135:31795
minio.access-key=minio

Loading…
Cancel
Save