Skip to content

REPLACE S3 storage from cloud AWS to self-hosted minIO #26

Merged
SergioNR merged 6 commits intonextfrom
refactor-aws-s3-to-minio
Dec 26, 2025
Merged

REPLACE S3 storage from cloud AWS to self-hosted minIO #26
SergioNR merged 6 commits intonextfrom
refactor-aws-s3-to-minio

Conversation

@SergioNR
Copy link
Copy Markdown
Member

Description

Deprecated the usage of AWS S3 in favor of a locally hosted S3 solution.

The purpose of this change is to optimise costs (due to the extreme costs of AWS provided solutions - specially AWS Transcribe) and to prepare for the upcoming local transcription feature

With cloud hosted, there is always a concern of credentials being leaked and racking up a nonsensical bill

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update (if applicable)
  • Refactor (non-breaking change that improves the code structure)

Related issue

Explanation of changes/Implementation

The S3 client has been updated to include the config for locally hosted minIO instead of previously-used AWS

The compose file has also been updated to include the minIO service

Screenshots (if applicable)

Pull Request Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Additional Notes

Copy link
Copy Markdown

@kilo-code-bot kilo-code-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: Missing function export

generateS3PutPresignedUrl is still imported and used in analysisController.js:131 but was removed from exports. This will cause runtime errors.

export const generateS3PutPresignedUrl = async (key) => {
  const command = new PutObjectCommand({
    Bucket: process.env.S3_BUCKET,
    Key: key,
    ContentType: 'video/mp4',
  });

  const analysisEntryPutPresignedUrl = await getSignedUrl(s3client, command, {
    expiresIn: 60 * 90, // 90 minute expiration
  });

  return analysisEntryPutPresignedUrl;
};

Copy link
Copy Markdown

@kilo-code-bot kilo-code-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ WARNING: Hardcoded MinIO endpoint

http://localhost:9000 is hardcoded instead of being configurable via environment variables. This prevents deployment in different environments.

export const s3client = new S3Client({
  region: process.env.S3_REGION, // irrelevant since  miniIO doesnt takei into account
  endpoint: process.env.MINIO_ENDPOINT || 'http://localhost:9000', // Container network endpoint
  forcePathStyle: true, // Required for MinIO path-style URLs
  credentials: {
    accessKeyId: process.env.MINIO_ROOT_USER,
    secretAccessKey: process.env.MINIO_ROOT_PASSWORD,
  },
});

Copy link
Copy Markdown

@kilo-code-bot kilo-code-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ WARNING: Server service commented out

The server service is commented out in the Docker Compose file, which will break the development environment. Uncomment it to restore full functionality.

  server:
    container_name: server
    build:
      context: .
      dockerfile: Dockerfile.dev
    environment:
      NODE_ENV: ${NODE_ENV}
      DEPLOY_ENVIRONMENT: ${DEPLOY_ENVIRONMENT}
      POSTHOG_API_KEY: ${POSTHOG_API_KEY}
      SESSION_SECRET: ${SESSION_SECRET}
      BREVO_API_KEY: ${BREVO_API_KEY}
      PRISMA_POSTGRES_DIRECT_URL: ${PRISMA_POSTGRES_DIRECT_URL}
      PRISMA_POSTGRES_CONNECTION_STRING: ${PRISMA_POSTGRES_CONNECTION_STRING}
      TELEGRAM_BOT_API_KEY: ${TELEGRAM_BOT_API_KEY}
      FRONT_WEB_APP_ORIGIN_URL: ${FRONT_WEB_APP_ORIGIN_URL}
      STRIPE_API_KEY: ${STRIPE_API_KEY}
      STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET}
      PORT: ${PORT}
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      S3_BUCKET: dev-analysis-entry-storage
      S3_REGION: ${S3_REGION}

    ports:
      - 3000:3000
    develop:
      watch:
        - path: .
          action: sync+restart #* Synchronize code changes and restart the server
          target: /usr/src/app/
    depends_on: #* References the SERVICE name - NOT the container_name
      database:
        condition: service_started
      minio:
        condition: service_started
    networks:
      - uxcaptain-network

Copy link
Copy Markdown

@kilo-code-bot kilo-code-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 SUGGESTION: Clean up deprecated AWS variables

The old AWS environment variables (AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID) are still in .env.example but no longer used. Remove them to avoid confusion.

NODE_ENV=development
DEPLOY_ENVIRONMENT=

POSTHOG_API_KEY=

SESSION_SECRET=

BREVO_API_KEY=

PRISMA_POSTGRES_DIRECT_URL=
PRISMA_POSTGRES_CONNECTION_STRING=

TELEGRAM_BOT_API_KEY=

FRONT_WEB_APP_ORIGIN_URL=

STRIPE_API_KEY=
STRIPE_WEBHOOK_SECRET=

PORT=3000

S3_REGION=
S3_BUCKET=

TRANSCRIPTION_ENABLED=

MINIO_ROOT_USER=
MINIO_ROOT_PASSWORD=
MINIO_ENDPOINT=

@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot Bot commented Dec 26, 2025

⚠️ 3 Issues Found

Severity Issue Location
CRITICAL Missing function import breaking participant flow server/controllers/analysisEntryController.js
WARNING Server container commented out in compose.yaml compose.yaml:1
WARNING Hardcoded volume path for MinIO storage compose.yaml:28

Recommendation: Address critical issue before merge - participant uploads will fail

Review Details (6 files)

Files: .env.example, .kilocode/rules/memory-bank/tech.md, compose.yaml, server/controllers/analysisEntryController.js, server/integrations/aws/ server/integrations/aws/s3.jsTranscribe.js,

Checked: Security, bugs, performance, error handling

Fix these issues in Kilo Cloud

@SergioNR
Copy link
Copy Markdown
Member Author

💡 SUGGESTION: Clean up deprecated AWS variables

The old AWS environment variables (AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID) are still in .env.example but no longer used. Remove them to avoid confusion.

NODE_ENV=development
DEPLOY_ENVIRONMENT=

POSTHOG_API_KEY=

SESSION_SECRET=

BREVO_API_KEY=

PRISMA_POSTGRES_DIRECT_URL=
PRISMA_POSTGRES_CONNECTION_STRING=

TELEGRAM_BOT_API_KEY=

FRONT_WEB_APP_ORIGIN_URL=

STRIPE_API_KEY=
STRIPE_WEBHOOK_SECRET=

PORT=3000

S3_REGION=
S3_BUCKET=

TRANSCRIPTION_ENABLED=

MINIO_ROOT_USER=
MINIO_ROOT_PASSWORD=
MINIO_ENDPOINT=

These are being used in AWS Transcribe - this is intentional

@SergioNR
Copy link
Copy Markdown
Member Author

⚠️ WARNING: Server service commented out

The server service is commented out in the Docker Compose file, which will break the development environment. Uncomment it to restore full functionality.

  server:
    container_name: server
    build:
      context: .
      dockerfile: Dockerfile.dev
    environment:
      NODE_ENV: ${NODE_ENV}
      DEPLOY_ENVIRONMENT: ${DEPLOY_ENVIRONMENT}
      POSTHOG_API_KEY: ${POSTHOG_API_KEY}
      SESSION_SECRET: ${SESSION_SECRET}
      BREVO_API_KEY: ${BREVO_API_KEY}
      PRISMA_POSTGRES_DIRECT_URL: ${PRISMA_POSTGRES_DIRECT_URL}
      PRISMA_POSTGRES_CONNECTION_STRING: ${PRISMA_POSTGRES_CONNECTION_STRING}
      TELEGRAM_BOT_API_KEY: ${TELEGRAM_BOT_API_KEY}
      FRONT_WEB_APP_ORIGIN_URL: ${FRONT_WEB_APP_ORIGIN_URL}
      STRIPE_API_KEY: ${STRIPE_API_KEY}
      STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET}
      PORT: ${PORT}
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      S3_BUCKET: dev-analysis-entry-storage
      S3_REGION: ${S3_REGION}

    ports:
      - 3000:3000
    develop:
      watch:
        - path: .
          action: sync+restart #* Synchronize code changes and restart the server
          target: /usr/src/app/
    depends_on: #* References the SERVICE name - NOT the container_name
      database:
        condition: service_started
      minio:
        condition: service_started
    networks:
      - uxcaptain-network

This is intentional - it is a placeholder for the compose file

@SergioNR
Copy link
Copy Markdown
Member Author

CRITICAL: Missing function export

generateS3PutPresignedUrl is still imported and used in analysisController.js:131 but was removed from exports. This will cause runtime errors.

export const generateS3PutPresignedUrl = async (key) => {
  const command = new PutObjectCommand({
    Bucket: process.env.S3_BUCKET,
    Key: key,
    ContentType: 'video/mp4',
  });

  const analysisEntryPutPresignedUrl = await getSignedUrl(s3client, command, {
    expiresIn: 60 * 90, // 90 minute expiration
  });

  return analysisEntryPutPresignedUrl;
};

This is incorrect - it is being exported correctly

@SergioNR
Copy link
Copy Markdown
Member Author

⚠️ WARNING: Hardcoded MinIO endpoint

http://localhost:9000 is hardcoded instead of being configurable via environment variables. This prevents deployment in different environments.

export const s3client = new S3Client({
  region: process.env.S3_REGION, // irrelevant since  miniIO doesnt takei into account
  endpoint: process.env.MINIO_ENDPOINT || 'http://localhost:9000', // Container network endpoint
  forcePathStyle: true, // Required for MinIO path-style URLs
  credentials: {
    accessKeyId: process.env.MINIO_ROOT_USER,
    secretAccessKey: process.env.MINIO_ROOT_PASSWORD,
  },
});

updated to be used as an env variable

@SergioNR SergioNR merged commit 9ebe505 into next Dec 26, 2025
@SergioNR SergioNR deleted the refactor-aws-s3-to-minio branch December 26, 2025 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant