Skip to content

Commit

Permalink
feat: integrate MinIO for file storage
Browse files Browse the repository at this point in the history
- Add MinIO support in FilesService
- Update docker-compose.yml to include MinIO service
- Implement environment variable switching between S3 and MinIO
- Add MinIO endpoint configuration
- Update documentation for MinIO setup and usage
  • Loading branch information
minai621 committed Oct 4, 2024
1 parent e184d24 commit 662d796
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 8 deletions.
11 changes: 8 additions & 3 deletions backend/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,14 @@ LANGCHAIN_PROJECT=your_langsmith_project_name_here


# FILE_UPLOAD: Whether to enable file upload to storage
# Set to true if file upload is required.
# If set to false, AWS_S3_BUCKET_NAME is not required.
# Set to true if file upload is required.
FILE_UPLOAD=false
# AWS_S3_BUCKET_NAME: S3 Bucket name
# S3 or MinIO configuration
BUCKET_TYPE="S3 or MINIO"
# This is the name of the S3 Bucket
AWS_S3_BUCKET_NAME="your_s3_bucket_name"
BUCKET_NAME="your_bucket_name"
AWS_REGION="your_aws_region"
MINIO_ENDPOINT="your_minio_endpoint"
MINIO_ACCESS_KEY="your_minio_access_key"
MINIO_SECRET_KEY="your_minio_secret_key"
28 changes: 27 additions & 1 deletion backend/docker/docker-compose-full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,21 @@ services:
LANGCHAIN_API_KEY: "your_langsmith_api_key_here"
LANGCHAIN_PROJECT: "your_langsmith_project_name_here"
FILE_UPLOAD: false
AWS_S3_BUCKET_NAME: "your_s3_bucket_name"
BUCKET_TYPE: "S3 or MINIO"
BUCKET_NAME: "your_s3_bucket_name_here"
MINIO_ENDPOINT: "your_minio_endpoint_here"
MINIO_ACCESS_KEY: "your_minio_access_key_here"
MINIO_SECRET_KEY: "your_minio_secret_key_here"
ports:
- "3000:3000"
depends_on:
- mongo
- minio
restart: unless-stopped
links:
- "mongo:mongo"
- "yorkie:yorkie"
- "minio:minio"

yorkie:
image: "yorkieteam/yorkie:latest"
Expand Down Expand Up @@ -59,3 +65,23 @@ services:
interval: 5s
timeout: 2s
retries: 20

minio:
image: minio/minio
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_data:/data
environment:
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
command: server --console-address ":9001" /data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3

volumes:
minio_data:
32 changes: 28 additions & 4 deletions backend/src/files/files.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GetObjectCommand, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { GetObjectCommand, PutObjectCommand, S3Client, S3ClientConfig } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import {
BadRequestException,
Expand All @@ -13,6 +13,7 @@ import * as htmlPdf from "html-pdf-node";
import * as MarkdownIt from "markdown-it";
import { PrismaService } from "src/db/prisma.service";
import { generateRandomKey } from "src/utils/functions/random-string";
import { StorageType } from "src/utils/types/storage.type";
import { CreateUploadPresignedUrlResponse } from "./types/create-upload-url-response.type";
import { ExportFileRequestBody, ExportFileResponse } from "./types/export-file.type";

Expand All @@ -25,7 +26,7 @@ export class FilesService {
private configService: ConfigService,
private prismaService: PrismaService
) {
this.s3Client = new S3Client();
this.s3Client = new S3Client(this.getStorageConfig());
this.markdown = new MarkdownIt({
html: true,
breaks: true,
Expand Down Expand Up @@ -55,7 +56,7 @@ export class FilesService {

const fileKey = `${workspace.slug}-${generateRandomKey()}.${contentType.split("/")[1]}`;
const command = new PutObjectCommand({
Bucket: this.configService.get("AWS_S3_BUCKET_NAME"),
Bucket: this.configService.get("BUCKET_NAME"),
Key: fileKey,
StorageClass: "INTELLIGENT_TIERING",
ContentType: contentType,
Expand All @@ -70,7 +71,7 @@ export class FilesService {
async createDownloadPresignedUrl(fileKey: string) {
try {
const command = new GetObjectCommand({
Bucket: this.configService.get("AWS_S3_BUCKET_NAME"),
Bucket: this.configService.get("BUCKET_NAME"),
Key: fileKey,
});
return getSignedUrl(this.s3Client, command, { expiresIn: 3600 });
Expand Down Expand Up @@ -125,4 +126,27 @@ export class FilesService {
fileName: `${fileName}.pdf`,
};
}

private getStorageConfig = (): S3ClientConfig => {
const bucketType: StorageType = this.configService.get("BUCKET_TYPE") || "S3";
const region = this.configService.get("AWS_REGION") || "us-east-1";
if (bucketType === "MINIO") {
const endpoint = this.configService.get("MINIO_ENDPOINT");
const accessKeyId = this.configService.get("MINIO_ACCESS_KEY");
const secretAccessKey = this.configService.get("MINIO_SECRET_KEY");
return {
region,
endpoint,
forcePathStyle: true,
credentials: {
accessKeyId,
secretAccessKey,
},
};
}

return {
region,
};
};
}
1 change: 1 addition & 0 deletions backend/src/utils/types/storage.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type StorageType = "S3" | "MINIO";

0 comments on commit 662d796

Please sign in to comment.