S3
Since v0.22.0+Build a self-hosted Hot Updater server with S3-compatible object storage.
Installation
Install the AWS plugin.
npm install @hot-updater/server @hot-updater/aws dotenv
npm install @hot-updater/bare @hot-updater/standalone hot-updater --save-devSetup
Create a .env.hotupdater file with your S3 credentials.
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
S3_BUCKET_NAME=hot-updater
HOT_UPDATER_AUTH_TOKEN=replace-with-a-secretFor S3-compatible services like Cloudflare R2, MinIO, and DigitalOcean Spaces,
set S3_ENDPOINT and use the region expected by that provider.
Hot Updater Configuration
Create the Hot Updater instance:
import { createHotUpdater } from "@hot-updater/server";
import { s3Database, s3Storage } from "@hot-updater/aws";
import { config } from "dotenv";
config({ path: ".env.hotupdater" });
const s3Config = {
region: process.env.S3_REGION ?? "auto",
endpoint: process.env.S3_ENDPOINT,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
},
bucketName: process.env.S3_BUCKET_NAME!,
};
export const hotUpdater = createHotUpdater({
database: s3Database(s3Config),
storages: [s3Storage(s3Config)],
basePath: "/hot-updater",
routes: { updateCheck: true, bundles: true },
});Protect /hot-updater/api/* with fail-closed authentication before mounting
the management routes. See Security Settings.
Schema Management
No schema generation or migration command is required. s3Database stores
bundle metadata as JSON objects in your S3 bucket.
Make sure the server credentials can list, read, write, and delete objects in the metadata bucket.
CLI Configuration
Configure your CLI to use this self-hosted server.
import { bare } from "@hot-updater/bare";
import { s3Storage } from "@hot-updater/aws";
import { standaloneRepository } from "@hot-updater/standalone";
import { config } from "dotenv";
import { defineConfig } from "hot-updater";
config({ path: ".env.hotupdater" });
const managementToken = process.env.HOT_UPDATER_AUTH_TOKEN;
if (!managementToken) {
throw new Error("HOT_UPDATER_AUTH_TOKEN is required");
}
export default defineConfig({
build: bare({ enableHermes: true }),
storage: s3Storage({
region: process.env.S3_REGION ?? "auto",
endpoint: process.env.S3_ENDPOINT,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
},
bucketName: process.env.S3_BUCKET_NAME!,
}),
database: standaloneRepository({
baseUrl: "http://localhost:3000/hot-updater",
commonHeaders: { Authorization: `Bearer ${managementToken}` },
}),
updateStrategy: "appVersion",
});The storage plugin must match the storages in your server's createHotUpdater. Both use s3Storage in this example.
API Endpoints
With the route groups enabled above, the server creates these endpoints:
| Method | Endpoint | Description |
|---|---|---|
| GET | /hot-updater/version | Get server version |
| GET | /hot-updater/fingerprint/:platform/:fingerprintHash/:channel/:minBundleId/:bundleId | Check for updates by fingerprint |
| GET | /hot-updater/app-version/:platform/:version/:channel/:minBundleId/:bundleId | Check for updates by app version |
| GET | /hot-updater/api/bundles | List bundles (query: channel, platform, limit, page, after, before) |
| GET | /hot-updater/api/bundles/:id | Get bundle by ID |
| POST | /hot-updater/api/bundles | Create bundles |
| PATCH | /hot-updater/api/bundles/:id | Update a bundle |
| DELETE | /hot-updater/api/bundles/:id | Delete bundle |
| GET | /hot-updater/api/bundles/channels | List all channels |
See the standalone server contract for the complete list-query encoding.