@serve.zone/onebox
Onebox is a self-hosted application platform for a single server. It combines Docker, CoreTraffic routing, a typed web control plane, app templates, platform services, and containerarchive-powered backups into one NodeNext TypeScript package and service.
Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.
What Onebox Does
Onebox turns a Linux host into a small PaaS that can run your own containers and curated app templates without a separate control plane. It is designed for the "one good server" use case: one machine, one local Docker runtime, one web dashboard, one operational surface.
- Deploys Docker workloads from external images or Onebox App Store templates.
- Uses the local Docker socket and creates the
onebox-networknetwork automatically. - Runs workloads as Docker Swarm services when Swarm is active, otherwise as standalone containers.
- Starts a CoreTraffic-backed reverse proxy for HTTP/S routing and WebSocket traffic.
- Serves the web UI and TypedRequest/TypedSocket API through
OpsServeron port3000by default. - Reports every App Store-managed service's platform OIDC eligibility through
getUsersAndAppRoles.response.platformOidcQualifications, including a stable qualification code/reason, declared roles, and an optional registration view. - Shows every App Store-managed service in Access, including the same stable qualification code/reason when platform OIDC is unavailable.
- Exposes an admin-authenticated read-only MCP endpoint at
/mcpfor safe service, domain, and platform-service summaries. - Stores platform state in a local SmartDB database.
- Provisions database and object-storage dependencies through one Corestore platform service. Database clients intentionally use the MongoDB wire protocol and standard
MONGODB_*connection variables. - Tracks domains, Cloudflare DNS records, ACME certificates, service logs, metrics, backup schedules, and app template metadata.
- Can sync routes and import certificates from an external
dcroutergateway when configured.
Architecture
browser / CLI
|
v
OpsServer :3000
- bundled web UI
- TypedRequest handlers
- TypedSocket dashboard events
|
v
Onebox coordinator
- SmartDB repositories
- Docker manager
- CoreTraffic route manager
- DNS and SSL managers
- platform service providers
- app store manager
- backup manager and scheduler
|
v
Docker host
- onebox-network
- CoreTraffic
- user services
- optional platform services
Onebox is the central class. It initializes the database, Docker, CoreTraffic, DNS, SSL, platform services, App Store, backup subsystem, optional external gateway integration, and the web/API server.
Installation
Install the latest released Linux binary:
curl -sSL 'https://code.foss.global/api/v1/repos/serve.zone/onebox/raw/install.sh?ref=main' | sudo bash
The installer downloads onebox-linux-x64 or onebox-linux-arm64 from the latest Gitea release, installs it under /opt/onebox, and links /usr/local/bin/onebox. Use --version vX.Y.Z to pin a release, --install-dir /path to change the target directory, or --source to clone the tag and build the NodeNext package locally.
curl -sSL 'https://code.foss.global/api/v1/repos/serve.zone/onebox/raw/install.sh?ref=main' | sudo bash -s -- --source
For source checkouts, install dependencies and build directly:
pnpm install
pnpm run build
node ./cli.js --help
This repository currently marks the npm package as private; use the installer or a source checkout until public npm release packaging is enabled.
Quick Start
Run a foreground development instance:
onebox server --ephemeral
Open the dashboard:
http://localhost:3000
On the first browser visit, Onebox asks you to create the administrator passkey. Enter the short-lived bootstrap code printed in the local Onebox service logs, then complete the browser passkey prompt. The code authorizes first-time enrollment only; Onebox never accepts a human password.
Production passkeys require a stable HTTPS hostname. While the Onebox coordinator is running, persist it from another terminal with onebox config set adminUiDomain onebox.example.com, then restart Onebox before opening the production UI and enrolling the passkey.
ONEBOX_ADMIN_UI_DOMAIN=onebox.example.com is an alternative only when added to the Onebox systemd service environment; exporting it in an interactive shell does not update the generated unit. After enrollment, the hostname is pinned to the passkey relying party.
If every passkey for the configured administrator is lost, use local host access to reset enrollment:
sudo onebox systemd stop
sudo onebox auth reset-passkeys --confirm
sudo onebox systemd start
sudo onebox systemd logs
The reset invalidates every passkey and session for the configured administrator. It never enables password authentication. The production database defaults to /var/lib/onebox/.nogit/smartdb; use --database-path only for a nonstandard installation.
Deploy a simple service:
onebox service add web --image nginx:latest --domain web.example.com --port 80
For production, install and run the systemd service:
sudo onebox systemd enable
sudo onebox systemd start
sudo onebox systemd logs
The systemd unit runs onebox systemd start-daemon with /var/lib/onebox as its working directory. From source or foreground runs, the default SmartDB path is ./.nogit/smartdb relative to the current working directory.
CLI Reference
onebox <command> [options]
Core commands:
| Command | Purpose |
|---|---|
selftest typed-rpc [--port <port>] |
Start and stop an isolated server to verify the packaged Typed RPC runtime graph. |
server [--ephemeral] [--port <port>] [--monitor] |
Start the web/API server in the foreground. |
service add <name> --image <image> [--domain <domain>] [--port <port>] [--env KEY=VALUE] |
Deploy a workload. |
service list |
List known services. |
service start <name> |
Start a stopped service. |
service stop <name> |
Stop a running service. |
service restart <name> |
Restart a service. |
service remove <name> |
Remove a service and its route. |
service logs <name> |
Print Docker logs for a service. |
appstore list |
List remote app templates. |
appstore config <app-id> [--version <version>] |
Print app metadata and version config. |
appstore install <app-id> --name <name> [--domain <domain>] [--version <version>] [--env KEY=VALUE] [--secrets-stdin] |
Install an app template. Pass declared secret overrides as one JSON object through stdin; --env accepts only non-secret values. |
appstore upgrade <service-name> [--version <version>] |
Upgrade an App Store-managed service through the forward-only catalog gate. |
registry add --url <url> --username <user> --password-stdin |
Store encrypted external registry credentials without exposing the password in process arguments. |
registry remove --url <url> |
Remove registry credentials. |
registry list |
List configured registries. |
dns add <domain> |
Add a DNS record through the configured DNS manager. |
dns sync |
Sync Cloudflare domains into Onebox. |
ssl renew [domain] |
Renew one certificate or expiring certificates. |
ssl list |
List stored certificates. |
ssl force-renew <domain> |
Force certificate renewal for a domain. |
proxy reload |
Reload routes and certificates into CoreTraffic. |
proxy test |
Check reverse proxy state. |
proxy status |
Print route/certificate counts and ports. |
systemd enable |
Install and enable the systemd unit. |
systemd disable |
Stop, disable, and remove the systemd unit. |
systemd start |
Start Onebox through systemd. |
systemd stop |
Stop Onebox through systemd. |
systemd status |
Show service status. |
systemd logs |
Follow journalctl logs. |
config show |
Show stored settings with secret values masked. |
config set <key> <value> |
Store a non-secret setting. |
config set <secret-key> --stdin |
Store one bounded, single-line secret without placing it in process arguments. |
backup create <service-name> |
Create a containerarchive backup through the running root-local coordinator. |
backup list [service-name] |
List completed backups, optionally for one service. |
cloudly-secrets-v2 <phase> <service-name> |
Inspect or operate the manually gated Cloudly Secrets v2 cutover, including WorkloadInit approval staging through bounded stdin. |
auth reset-passkeys --confirm [--database-path <path>] |
Locally invalidate every passkey for the configured administrator and prepare fresh enrollment. |
migration corestore-platform --status |
Read redacted cutover status without initializing or mutating SmartDB. |
migration corestore-platform --approve --checkpoint-reference <reference> [--allow-empty-legacy-mongodb] |
Offline, resumable cutover from split legacy storage/database services to one Corestore owner. |
status |
Print JSON system status. |
upgrade |
Install the latest released package build. Requires root. |
App Store upgrades fail closed unless the fresh index, app metadata, and target config agree. Semantic-version targets must be newer than the installed version. Branch and digest-tracked upgrades must use the fresh latest target. Onebox rejects stale operations when the service template or installed version changes before migration or apply.
The legacy nginx command name is still accepted as an alias for proxy, but CoreTraffic is the active proxy backend.
Corestore platform cutover
Fresh database and object-storage resources are owned by one pinned Corestore service. SmartDB replaces the MongoDB backend while deliberately retaining the MongoDB wire protocol, port 27017, driver compatibility, and MONGODB_* workload variables. Onebox does not run a standalone MongoDB platform service for new deployments.
Legacy split ownership is converted only by the explicit migration in ts_migration/. Before running it, stop Onebox and create a separately stored, verified, restorable full checkpoint of the authoritative Corestore volume. Pass the operator checkpoint identifier unchanged on every retry:
sudo onebox systemd stop
sudo onebox migration corestore-platform --status
sudo onebox migration corestore-platform --approve \
--checkpoint-reference <verified-checkpoint-reference>
sudo onebox migration corestore-platform --status
sudo onebox systemd start
The migration captures exact platform/resource ownership, fences affected workloads, renames the legacy object-storage owner to Corestore, provisions target resources, converts non-empty legacy databases with the pinned Corestore migration image, atomically replaces resource credentials, and restarts only workloads that were running before the cutover. Each phase is persisted and replay-safe. Database conversion temporarily leases the canonical onebox-mongodb name to the exact captured source container so its persisted replica-set identity remains valid. A stopped canonical-name holder is displaced and retained only when its exact command, networks, data volume, key-file bind, and mount topology prove it is a legacy twin of the captured source; running or unrelated owners fail closed without MongoDB mutation. The migration restores the exact captured recovery name before advancing the phase. Replaying an already-complete migration re-provisions and verifies the canonical credential tuple and reports repaired when persisted credentials or mapped service settings changed. A service held by a pending Cloudly Secrets v2 backup remains stopped; its environment and encrypted secret bundle are reconciled through the exact persisted backup fence without creating or starting a runtime. Other running services are restarted only when credential reconciliation changes their delivered settings. Recovery containers are renamed and retained; the command prints their names so an operator can remove them only after production verification and the agreed recovery window.
An empty legacy database is recorded as a persisted inspection proof and fails closed on the first run. After reviewing that proof, rerun the same command with --allow-empty-legacy-mongodb. This approval skips only databases re-inspected as empty; it does not disable verification for non-empty databases. Normal Onebox startup never performs this infrastructure cutover implicitly.
migration corestore-platform --status uses SmartDB's bounded Linux read-only management sidecar while Onebox is stopped. It reads only the exact migration-state string and does not start a database listener, initialize SmartData, run storage migrations, repair storage, or write files. The packaged SmartDB Rust sidecar must be available. Output is limited to the phase, SHA-256 hashes of the checkpoint reference and captured authority, resource/progress/recovery counts, and creation/update timestamps; checkpoint references, service and resource names, owner IDs, database names, and container identities are never emitted.
Cloudly Secrets v2 cutover
The Cloudly Secrets v2 transition is a manual, forward-only App Store cutover. The exact schema-4 target is App Store version 1.1.5 from @serve.zone/appstore 2.4.0, requires Onebox 7.5.0 or newer, and uses the released multiarch Cloudly 19.2.0 digest sha256:7aec3b1f553292cefd5fd421a70e6c50463af168b14b1e4b127597991efa30dd. An unreleased checkout, another App Store version, or a mutable image tag is not a valid target. The App Store version declares the target image and application configuration; Onebox owns the secret-file identities for the keyring, authorization, rehearsal receipt, and WorkloadInit approval artifact.
Run each gate through the active root-local Onebox coordinator and inspect status between phases:
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 begin cloudly --target-version 1.1.5
sudo onebox cloudly-secrets-v2 hold cloudly
sudo onebox cloudly-secrets-v2 backup cloudly
sudo onebox cloudly-secrets-v2 verify-backup cloudly
sudo onebox cloudly-secrets-v2 stage-workloadinit-approval cloudly --stdin \
< cloudly-workloadinit-approval.json
sudo onebox cloudly-secrets-v2 rehearse cloudly
sudo onebox cloudly-secrets-v2 prepare-keyring cloudly
sudo onebox cloudly-secrets-v2 apply-target cloudly
sudo onebox cloudly-secrets-v2 authorize cloudly
sudo onebox cloudly-secrets-v2 execute cloudly
sudo onebox cloudly-secrets-v2 verify cloudly
sudo onebox cloudly-secrets-v2 verify-restart cloudly
sudo onebox cloudly-secrets-v2 promote cloudly
An eligible schema-1 or schema-2 operation against App Store 1.1.2 or 1.1.3 must first resume through the existing schema-3 advance and rehearsal path:
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 advance-target cloudly
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 rehearse cloudly
sudo onebox cloudly-secrets-v2 status cloudly
That advance pins App Store 2.3.0 and Cloudly 17.1.0, preserves its existing encrypted keyring when present, and appends immutable target, compatibility-fence, backup, keyring, runtime-hold, package, and target-advance evidence. It does not start Cloudly, regenerate an existing keyring, or alter the verified backup.
An eligible schema-3 operation against App Store 1.1.4 may then move to schema 4 only from its exact backup-verified state with complete backup evidence, a persisted run-rehearsal intent and scratch lineage, and a proven zero-task runtime. Run the explicit supersession, stage the verified authority, and start a fresh rehearsal before preparing the production keyring:
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 advance-target cloudly
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 stage-workloadinit-approval cloudly --stdin \
< cloudly-workloadinit-approval.json
sudo onebox cloudly-secrets-v2 rehearse cloudly
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 prepare-keyring cloudly
The supersession pins the published App Store 2.4.0 index, manifest, config, OCI index, and platform identities in one revision-fenced schema-4 transition. It retains the complete canonical schema-3 predecessor in an immutable audit, preserves the verified backup and optional encrypted keyring digest, and clears the current run, scratch, and pending intent so predecessor scratch ownership remains historical and inert. It does not start Cloudly, regenerate an existing keyring, clean predecessor resources, or alter the verified backup. Any other predecessor shape fails closed.
stage-workloadinit-approval accepts one active or revoked v1 artifact only through the root-local control socket and bounded multiline stdin. @serve.zone/workloadinit is the sole parser and verifier. Onebox persists a durable intent, performs a generation-fenced encrypted reserved-secret CAS with digest readback, then checkpoints immutable authority history. The target receives the artifact only at /run/secrets/cloudly-workloadinit-approval.json, owned by root with mode 0400; it is excluded from environment and maintenance-container metadata. The initial authority must be active and is staged while schema 4 remains held at backup-verified. Rehearsal remains blocked until that checkpoint exists.
After promotion, an authority update or matching revocation must use a strictly higher generation. Onebox recreates the promoted runtime with the new Docker secret, restores its prior running or stopped state, verifies the exact read-only mapping, and only then advances the authority checkpoint. If replacement is interrupted, startup scales the pending runtime to zero; rerunning the exact same staging command resumes from the persisted intent and secret digest. Generic service-secret APIs cannot add, change, or remove the reserved approval key.
If backup remains pending because Corestore credentials require canonical migration repair, first require status to show phase held, pending intent create-backup, and zero desired, active, and running tasks. Then stop the sole Onebox coordinator and replay the original Corestore migration from the systemd working directory with the same verified checkpoint reference used for the first migration:
cd /var/lib/onebox
sudo onebox systemd stop
sudo onebox migration corestore-platform --status
sudo onebox migration corestore-platform --approve \
--checkpoint-reference <original-verified-checkpoint-reference>
sudo onebox systemd start
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 backup cloudly
Do not continue if the offline replay fails, if Onebox does not restart cleanly, or if the post-start cutover status and zero-runtime proof changed. The repair does not start the held Cloudly workload and the final backup command resumes the existing create-backup intent rather than creating a second cutover operation.
Before verify-backup, an existing installation must likewise replay the original Corestore migration so the persisted Corestore owner adopts the current Onebox-pinned image that provides canonical database digests and allocation-fenced scratch databases. Stop the sole Onebox coordinator, require migration corestore-platform --status to show the expected persisted migration phase and hashes, and rerun migration corestore-platform --approve with the original verified checkpoint reference. The replay accepts only known prior Corestore image digests, proves the old container stopped, persists the new immutable image before deployment, and leaves a held Cloudly workload stopped. After restarting Onebox, require the same cutover operation ID, phase, pending intent, backup evidence, and zero-runtime proof before rerunning verify-backup.
authorize records the explicit operator approval. execute separately mints the short-lived, single-run production authorization while the service is proven quiescent. Rehearsal and production authorizations are mounted only into their operation-owned maintenance containers and are removed after use; they are never delivered to the hosted Cloudly runtime. The encrypted rehearsal receipt exists only until it binds production preparation and is then removed. Onebox exposes plaintext maintenance material on the host only through operation-owned mode-0600 staging. The hosted target receives the encrypted-bundle keyring and verified WorkloadInit approval at their dedicated root-owned mode-0400 paths.
begin derives the historical source from the owned immutable Docker runtime and never pulls a mutable source tag. If a prior Onebox defect replaced a stopped runtime's digest reference with a tag, recovery requires --source-image code.foss.global/serve.zone/cloudly@sha256:<digest>. Onebox accepts that input only while the persisted service is stopped and the Swarm runtime has zero desired replicas and no active tasks. It verifies the exact local image, proves that every filtered task belongs to the exact service and is terminal, and pins the existing stopped service through Docker's version fence before persisting the cutover. The full recovery transition is serialized against Onebox service lifecycle mutations. If the persisted-service CAS fails after the runtime pin, the runtime remains stopped at the verified digest, but the operator must inspect the current service record before retrying begin; no cutover is claimed until that original snapshot is persisted successfully.
Every non-promoted operation is held at zero during Onebox startup before routes, gateway export, platform-secret reconciliation, App Store upgrades, or background work can reactivate it. A command interrupted with a persisted pending intent can be rerun for that phase. Maintenance attempts use deterministic identities so a completed result can be adopted after a lost response; Onebox persists terminal ownership before parsing output, records explicit completed zero-blocker proof, and removes the candidate only after proving its exact receipt and absence. Failed verification restores and proves the zero-runtime hold. Startup after restart-verified returns the operation to verified, requiring restart verification to run again before promotion.
A pending prepare-keyring replay reuses and validates the already encrypted Onebox-owned keyring instead of generating or replacing it. A fresh preparation fails closed if the reserved key already exists. Legacy non-inspect CUTOVER_BLOCKED failures display only validated blocker codes and include the total count when the bounded blocker list is truncated; references and malformed evidence are not echoed.
diagnose is available only after a rehearsal stops at the prepared scratch inspection checkpoint. It cannot persist a cutover transition or advance the rehearsal:
sudo onebox cloudly-secrets-v2 status cloudly
sudo onebox cloudly-secrets-v2 diagnose cloudly
sudo onebox cloudly-secrets-v2 status cloudly
Inspection runs from the released Cloudly 19.0.0 diagnostic image at exact multiarch digest sha256:f295d471628934e234ba9acd4db362c27e3d863b96f7cdcdcc7f04b11d7374c1; schema-3 maintenance remains pinned to Cloudly 17.1.0, while schema-4 maintenance and the hosted target use the exact Cloudly 19.2.0 release described above. Diagnosis also requires the persisted and running Corestore service to prove the exact released 5.0.0 image at digest sha256:e3e25e435b58d45408e1659a90a3f8de98390d6bbe9ed8b3f40d80d6aa92a567; Onebox does not upgrade that service implicitly. Corestore issues one fixed 12-minute read grant bound to the persisted scratch allocation, and Onebox sends its MongoDB URI only over attached stdin to a non-restarting, auto-removing diagnostic container. Onebox journals the grant and container identities before issuance, retains the journal until revocation and container absence both succeed, and reconciles retained journals before normal startup or another diagnosis continues. A coordinator-wide lock serializes issuance, reconciliation, and shutdown cleanup; reconciliation attempts every valid journal even when siblings are malformed or fail, and capacity is checked before any new journal is written. Docker attach and wait transports are cancelled at the lifecycle deadline, lost-create adoption must match the complete inspected execution identity, and Corestore control errors are read through the same 16 KiB bound as private grant responses. Onebox accepts only diagnostics schema 2, validates each finite code/reason pair and the complete aggregate counts, and rejects references, unknown fields, malformed output, and unapproved reasons without echoing their values. Run rehearse again only after the reported blockers have exact approved corrections.
Upgrading an existing Corestore 4.5.0 owner to this diagnostic runtime is an explicit offline replay, not a startup action. First prove every Corestore consumer quiescent, stop the sole Onebox coordinator, stop and prove the exact Corestore container stopped, then create and independently verify a fresh full-volume checkpoint outside the authoritative Docker volume. This fresh pre-5.0.0 checkpoint is recovery evidence; the replay command must still receive the original checkpoint reference already captured in the persisted migration state:
cd /var/lib/onebox
sudo onebox migration corestore-platform --status
sudo onebox migration corestore-platform --approve \
--checkpoint-reference <original-verified-checkpoint-reference>
sudo onebox migration corestore-platform --status
The replay accepts the exact known 4.5.0 image, durably selects 5.0.0, and keeps every non-promoted Cloudly cutover workload stopped. SmartDB 4.x then migrates persistent auth metadata to version 3 on first Corestore 5.0.0 startup. That transition is one-way: retry Corestore 5.0.0 after an interrupted start, or restore the fresh pre-5.0.0 checkpoint before selecting Corestore 4.5.0/SmartDB 3.x. Never start the older runtime against a volume that Corestore 5.0.0 has opened.
verify-backup performs full archive-integrity verification and validates the exact Corestore backup receipt. rehearse then provisions an expected-absent pinned Corestore scratch database, persists its allocation identity before restore, validates the restore response, and compares Corestore's bounded canonical source and restored content digests plus every scan counter. The same persisted rehearsal and allocation identity fences provisioning, restore, digest and status checks, and cleanup; completion requires a fenced absence proof. This proof streams the database scan without using the size-limited portable export payload. The scratch proof covers the selected database only; it does not prove restoration of application object-storage resources. The authenticated Onebox full-backup restore workflow remains responsible for restoring and verifying every supported resource represented by the backup. Named object-storage bindings and requests are currently unsupported by that workflow and make backup creation fail closed.
Rollback mode is exclusively full-restore-only. Once begin has persisted the cutover, there is no cancel command and no old-image rollback command. Recovery must use the authenticated Onebox full-backup restore workflow; replacing the image or metadata manually is not a supported rollback. Promotion is available only after the target starts successfully, reports a verified-completed rollback-fenced status, and passes a second restart without authorization.
Configuration Notes
Useful settings include:
| Setting | Purpose |
|---|---|
adminUiDomain |
Exact HTTPS hostname used as the WebAuthn relying-party ID. |
serverIP |
IP address used for DNS records. |
cloudflareToken |
Cloudflare API token. cloudflareAPIKey is accepted as a legacy alias. |
cloudflareZoneId |
Cloudflare zone identifier. |
acmeEmail |
ACME account email for certificate issuance. |
httpPort |
OpsServer/web UI port. Defaults to 3000. |
metricsInterval |
Metrics collection interval in milliseconds. |
backupPassword |
Secret passphrase for encrypted backup repositories. |
dcrouterGatewayUrl |
Optional external dcrouter API endpoint. |
dcrouterGatewayApiToken |
Optional external dcrouter API token. |
dcrouterGatewayClientId |
Optional stable external gateway client identity used for route ownership. |
dcrouterTargetHost |
Optional target host advertised to dcrouter. |
dcrouterTargetPort |
Optional target port advertised to dcrouter. |
Example:
onebox config set serverIP 203.0.113.10
onebox config set acmeEmail ops@example.com
onebox config set cloudflareToken --stdin
onebox config set cloudflareZoneId zone-id
For the stdin form, enter or pipe one secret line and then close stdin.
External registry credentials remain encrypted in Onebox and are decrypted only for the exact Docker image-pull request that needs them. Onebox does not persist them through docker login.
App Store
The App Store manager fetches metadata from serve.zone/appstore through @serve.zone/appstore and caches it briefly. Templates can declare public, secret, and generated environment inputs, container arguments, file-mounted secrets, and platform requirements. Installing an app can automatically provision Corestore database/object-storage, ClickHouse, Valkey, or MariaDB resources.
Service secrets and provisioned platform credentials are encrypted at rest. The browser seals each declared secret to Onebox's active X25519 recipient with install-specific authenticated context before the TypedRequest call. The root CLI accepts secrets only through bounded stdin over its mode-0600 local control socket; the daemon seals them before constructing the install request. Generated values are created inside Onebox. Plaintext install secrets never enter the public environment, browser request cache, process arguments, or persisted App Store metadata. Environment secrets work with standalone Docker containers and Swarm services. File-delivered secrets stay out of the environment and are mounted through Docker secrets, so Onebox rejects them when the host is not using Swarm mode.
Hosted apps authenticate to Onebox with signed, audience-scoped RS256 machine JWTs stored in the encrypted service-secret bundle. Onebox verifies both the signature and the exact currently active token, rotates legacy random tokens and near-expiry JWTs, and reconciles changed identities through the normal service update path. Bootstrap actions use typed message/setup-route variants and revision-fenced atomic transitions; concurrent lifecycle changes fail closed.
Named storage contracts
App Store versions can declare template-local storageClasses and stable storageRequests for filesystem and objectStorage resources. These declarations contain portable requirements only. Provider names, host paths, network shares, mount options, and authentication details remain Onebox operator configuration and never enter an app manifest.
Onebox normalizes every install through @serve.zone/appstore, negotiates the declared storage feature IDs, selects a compatible operator class deterministically, and persists the canonical resolved binding on the service. Filesystem requests become service-owned Docker volumes. Each object-storage request receives its own bucket, endpoint, and scoped credential material through the Corestore v2 binding API; multiple named bindings use disjoint environment keys and encrypted service-secret storage.
Legacy volumes and platformRequirements.s3: true declarations are normalized for new installs. Existing pre-binding services remain on their legacy resources during compatible upgrades. Adding or changing an explicit named request requires a storage migration instead of silently replacing data.
The current fulfillment adapter advertises only local/backup filesystem classes and the standard managed object-storage policy with environment delivery. Capacity requests, secret-file object delivery, hard quotas, snapshots, versioning, non-local filesystem targets, and Kerberos-authenticated NFS remain unadvertised and fail closed. Onebox does not fall back to local storage when a requested capability or mapped class is unavailable. Reclaim policy is honored as retain or delete during rollback and service removal.
Backups export and restore opted-in filesystem volume data by mount path while preserving the portable storage specification, together with supported legacy platform resources. Named object-storage bindings and requests remain unsupported; backup creation fails closed when either is present.
onebox appstore list
onebox appstore config cloudly
onebox appstore install cloudly --name cloudly --domain cloudly.example.com
Backups
Backups are built around @serve.zone/containerarchive. Onebox exports service configuration, encrypted service-secret ciphertext, platform resource metadata, supported platform data, and optionally Docker images into a content-addressed archive repository. Platform data is streamed as a fixed, bounded set of deterministic logical tar items rather than one archive item per file. Restore derives large-item limits from authenticated snapshot metadata and validates tar paths, entry types, sizes, and symlink boundaries before importing data.
S3-compatible resources store object bodies under SHA-256 identifiers and retain exact object keys in a validated versioned manifest, so an object key is never interpreted as a filesystem path. Host-side export of a Corestore-owned bucket requires the canonical internal endpoint http://onebox-corestore:9000, the exact onebox-corestore container identity, and its loopback-published S3 port. Stale onebox-smartstorage credentials, malformed Corestore endpoints, and missing host publications fail closed and require the explicit Corestore migration replay above; Onebox does not add a host alias or persist a loopback endpoint into workload credentials. Compatibility readers remain isolated for earlier untagged file-item snapshots and .tar.enc backups; new backups write only the logical-item format. Legacy .tar.enc restores migrate plaintext control and platform credentials into the current representation.
Image-inclusive backups always resolve the active Docker image ID and export by that immutable ID. A canonical digest or mutable tag is retained only while it resolves to the active image; an absent or moved mutable tag is discarded in favor of the verified image ID, while a conflicting immutable digest fails closed. Restore verifies the archived image ID before changing service state, never reassigns a mutable tag, and never replaces archived content with a registry pull.
Encrypted service-secret bundles can be decrypted only with the same credential-encryption key. Set the same 32-byte, base64-encoded ONEBOX_ENCRYPTION_KEY on another host before restoring there; without an explicit key, Onebox derives one from the hostname and /etc/machine-id, so ciphertext is portable only to a host with the same machine identity.
Backup and schedule operations are primarily exposed through the OpsServer/web UI handlers.
Root operators can also run onebox backup create <service-name> and
onebox backup list [service-name]; both commands execute inside the sole
coordinator through the root-only Unix control socket. Backup creation is
serialized per service across CLI, UI, and scheduled callers.
Development
Requirements:
- Node.js for the application runtime.
- pnpm for package scripts.
- Docker for any runtime path that initializes Onebox fully.
Common tasks:
pnpm run watch
pnpm run build
pnpm test
node ./cli.ts.js server --ephemeral --monitor
Source map:
| Path | Purpose |
|---|---|
cli.js |
Built CLI entry point. |
cli.ts.js |
Source CLI entry point for development. |
ts/cli.ts |
CLI router and command help. |
ts/classes/onebox.ts |
Main coordinator. |
ts/classes/docker.ts |
Docker client, networks, containers, and Swarm services. |
ts/classes/coretraffic.ts |
CoreTraffic Docker service and Admin API manager. |
ts/classes/reverseproxy.ts |
CoreTraffic route and certificate bridge. |
ts/classes/platform-services/ |
Local platform service providers. |
ts/classes/appstore.ts |
Remote App Store catalog and upgrade logic. |
ts_migration/cloudly-secrets-v2-cutover.ts |
Persisted, phase-gated Cloudly Secrets v2 cutover coordinator. |
ts/classes/storage-manager.ts |
Portable storage capability negotiation, class selection, binding fulfillment, and lifecycle. |
ts/classes/backup-manager.ts |
Backup and restore orchestration. |
ts/opsserver/ |
Web UI server and TypedRequest handlers. |
ts/database/ |
SmartDB repositories. |
ts_migration/ |
Versioned persisted-data and infrastructure migrations. |
ts_web/ |
Dashboard source. |
License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in license.md.
Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
Company Information
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.