Skip to main content
NekoHub supports multiple storage backends through storage provider profiles. You can create several profiles (for example, a local profile for development and an S3 profile for production) and designate one as the default. When you upload an asset without specifying a storage provider, NekoHub uses the default profile.

Add a storage provider via the admin console

1

Open the Providers page

Navigate to /providers in the admin console.
2

Click New Provider

Click the New Provider button.
3

Choose a provider type and configure it

Select one of the supported provider types (Local, S3, or GitHub Repo) and fill in the required fields. See Provider configuration below for the fields specific to each type.
4

Save

Click Create. The profile is now available for use when uploading assets.
5

Set as default (optional)

To make this the default provider, open the profile and click Set as Default, or use the API endpoint described in Setting the default provider.

Create a storage provider via the API

Send a POST request to /api/v1/system/storage/providers. Pass provider-specific configuration in the configuration and secretConfiguration objects.
curl -X POST https://your-api-host/api/v1/system/storage/providers \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-s3",
    "displayName": "Production S3",
    "providerType": "s3",
    "isEnabled": true,
    "isDefault": false,
    "configuration": {
      "endpoint": "https://s3.amazonaws.com",
      "bucket": "my-nekohub-bucket",
      "region": "us-east-1",
      "forcePathStyle": false,
      "publicBaseUrl": "https://my-nekohub-bucket.s3.amazonaws.com"
    },
    "secretConfiguration": {
      "accessKey": "AKIAIOSFODNN7EXAMPLE",
      "secretKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    }
  }'

Provider configuration

Local

Stores files on the server’s local filesystem. Suitable for single-server deployments and development.
FieldDescription
rootPathAbsolute path on the server where asset files are stored (e.g. /app/storage/assets)
{
  "providerType": "local",
  "configuration": {
    "rootPath": "/app/storage/assets"
  }
}

S3-compatible

Stores files in any S3-compatible object storage service, including Amazon S3, MinIO, Cloudflare R2, and others.
FieldDescription
endpointThe S3 API endpoint URL
bucketThe bucket name
regionThe AWS region (e.g. us-east-1)
accessKeyThe access key ID (treat as a secret)
secretKeyThe secret access key (treat as a secret)
forcePathStyleSet to true for MinIO and other path-style endpoints
publicBaseUrlBase URL for constructing public asset URLs (e.g. https://my-bucket.s3.amazonaws.com)
{
  "providerType": "s3",
  "configuration": {
    "endpoint": "http://minio:9000",
    "bucket": "nekohub",
    "region": "us-east-1",
    "forcePathStyle": true,
    "publicBaseUrl": "http://localhost:9000/nekohub"
  },
  "secretConfiguration": {
    "accessKey": "minioadmin",
    "secretKey": "minioadmin"
  }
}

GitHub Repo

GitHub Repo storage is experimental. It is better suited as a secondary or archive store rather than primary object storage. Prefer Local or S3 for high-volume or production use.
Stores assets as files committed directly to a GitHub repository. Useful for public static asset hosting via raw.githubusercontent.com.
FieldDescription
ownerGitHub organization or user that owns the repository
repoRepository name
refBranch or tag to commit to (e.g. main)
basePathDirectory path within the repository where assets are stored
tokenGitHub personal access token with repo write permission (treat as a secret)
visibilityPolicyControls public URL behavior — use public-only for public repos
{
  "providerType": "github-repo",
  "configuration": {
    "owner": "your-org",
    "repo": "your-assets-repo",
    "ref": "main",
    "basePath": "assets/images",
    "visibilityPolicy": "public-only"
  },
  "secretConfiguration": {
    "token": "ghp_yourGitHubPersonalAccessToken"
  }
}

Setting the default provider

To designate a provider profile as the default, send a POST request to /api/v1/system/storage/providers/{id}/set-default:
curl -X POST https://your-api-host/api/v1/system/storage/providers/<profile-id>/set-default \
  -H "Authorization: Bearer <access_token>"
The default storage provider is used automatically when you upload an asset without specifying a storageProviderProfileId. You can still route individual uploads to a different provider by passing the profile’s UUID in the upload request.