Self-Hosted InsForge Now Supports S3 Storage

25 Jul 20263 minutes
Can Lyu

Can Lyu

Principal Software Engineer

Self-hosted InsForge Storage connected to MinIO, RustFS, and external S3-compatible object stores

Self-hosted InsForge now supports bundled MinIO, bundled RustFS, and any external S3-compatible object store as storage backends.

Run an object store next to InsForge with one Docker Compose overlay, or point InsForge at infrastructure you already operate. The existing Storage REST API, SDK, Dashboard, and S3-compatible gateway all use the same files. The full configuration matrix is in the self-hosted storage guide.

Three Storage Backends

Self-hosted deployments now have three storage paths:

  • Local filesystem: still the default. It needs no configuration and stores files in the storage-data Docker volume.
  • Bundled MinIO or RustFS: one Compose overlay starts the store, creates the backing bucket, and configures InsForge automatically.
  • External S3-compatible storage: set environment variables for AWS S3, Wasabi, Cloudflare R2, Tencent COS, Aliyun OSS, or a remote MinIO, RustFS, Garage, or Ceph deployment.

Setting S3_BUCKET selects the S3 storage provider. It also enables InsForge's S3-compatible gateway at /storage/v1/s3.

Run MinIO or RustFS with One Overlay

Start InsForge with MinIO:

bash
docker compose -f docker-compose.prod.yml -f docker-compose.minio.yml up -d

Or use RustFS:

bash
docker compose -f docker-compose.prod.yml -f docker-compose.rustfs.yml up -d

Each overlay starts the object store, waits for it to become ready, creates an insforge-storage bucket, and points the InsForge backend at it. The store stays on the internal Docker network with no host ports. Uploads and downloads stream through InsForge, so the object store does not need its own public domain or TLS certificate.

Both overlays include development defaults. Set MINIO_ROOT_USER and MINIO_ROOT_PASSWORD, or RUSTFS_ACCESS_KEY and RUSTFS_SECRET_KEY, to unique values before running them in production.

Bring Your Own S3-Compatible Store

For an existing object store, add its connection details to .env:

env
S3_BUCKET=my-insforge-bucket
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_ENDPOINT_URL=https://s3.my-provider.example
S3_FORCE_PATH_STYLE=true

Leave S3_ENDPOINT_URL empty for AWS S3. The backend then uses the standard AWS endpoint and can read credentials from an IAM role. The S3_* names are provider-neutral; legacy AWS_S3_BUCKET and AWS_REGION values still work as fallbacks.

Path-style addressing is the default and works with MinIO, RustFS, and Wasabi. Set S3_FORCE_PATH_STYLE=false for providers such as Tencent COS and Aliyun OSS that require virtual-hosted-style requests.

Why Bundled Stores Use Proxy Mode

The bundled MinIO and RustFS overlays intentionally keep the storage container on InsForge's internal Docker network. The backend can reach http://minio:9000 or http://rustfs:9000, but a browser outside that network cannot. A presigned URL containing either internal address would fail.

The overlays therefore set S3_USE_PRESIGNED_URLS=false. Uploads and downloads pass through the public InsForge endpoint while the storage container stays private.

This is a property of the bundled deployment, not a MinIO or RustFS limitation. If your object store has a browser-accessible endpoint and supports S3 POST policies, configure it as an external S3-compatible store and leave S3_USE_PRESIGNED_URLS=true. Clients then upload and download directly with the store.

Proxy mode is still required when an external endpoint is private or does not support S3 POST policies. Cloudflare R2 is the notable public-endpoint case: set S3_USE_PRESIGNED_URLS=false for browser uploads. Proxy downloads stream instead of buffering and support Range requests for media seeking.

Use the Same Storage from Any S3 Client

Once any S3 backend is configured, open Storage → Settings → S3 Configuration and create a project access key. Then point the AWS CLI, an AWS SDK, rclone, or Terraform at:

text
https://your-domain.example/storage/v1/s3

Gateway uploads appear immediately in the InsForge Dashboard and Storage API. The gateway uses project credentials and path-style addressing, while the backing store remains an implementation detail.

Moving from Local Storage

Changing the backend does not migrate files already stored in the local storage-data volume. Copy those objects to the new bucket with mc mirror, aws s3 sync, or another migration tool before switching, or start with an empty bucket.