Docker
Run ObjectOS in a container — for evaluation, staging, or production.
Docker
Docker is the path most teams take to production. It matches the way the runtime is meant to be operated: one stateless container per instance, an external database, an external object store for files, secrets injected at runtime.
Pull the pre-built image
We publish the runtime image to GitHub Container Registry on every
push to main and on tagged releases:
docker pull ghcr.io/objectstack-ai/objectos:latestAvailable tags:
| Tag | Channel |
|---|---|
latest | Latest build of main (recommended for first-time evaluation) |
main | Same as latest, but explicit |
sha-<short> | Pinned to a specific commit (recommended for production) |
vX.Y.Z, X.Y, X | Tagged releases |
For production, pin to sha-<short> or a semver tag — latest will
drift.
Run with the bundled sample
docker run --rm -p 3000:3000 \
-e OS_AUTH_SECRET="$(openssl rand -hex 32)" \
ghcr.io/objectstack-ai/objectos:latestThen open http://localhost:3000. The image ships with an empty sample app so you can verify the runtime boots and Console/Account render before pointing it at your own artifact.
OS_AUTH_SECRET is required to start. Rotating it invalidates existing
sessions.
Run with your own artifact
Your app definition is a single file: dist/objectstack.json. It's
produced by:
| Source | How |
|---|---|
| Your own project | pnpm exec objectstack compile after editing objectstack.config.ts |
| A template | Clone from templates repo, run pnpm install && pnpm exec objectstack compile |
| App marketplace | Provided as part of the published app |
Mount the file at /artifacts/objectstack.json and point the runtime
at it:
docker run --rm -p 3000:3000 \
-e OS_AUTH_SECRET="$(openssl rand -hex 32)" \
-e OS_ARTIFACT_FILE=/artifacts/objectstack.json \
-v "$PWD/dist:/artifacts:ro" \
-v objectos-data:/var/lib/objectos \
ghcr.io/objectstack-ai/objectos:latestThe objectos-data volume holds the SQLite database (when no external
DB is configured) and any locally-stored uploaded files.
Use Postgres instead of SQLite
docker run --rm -p 3000:3000 \
-e OS_AUTH_SECRET="$(openssl rand -hex 32)" \
-e OS_ARTIFACT_FILE=/artifacts/objectstack.json \
-e OS_DATA_DRIVER=postgres \
-e OS_DATA_URL='postgres://user:pass@db.internal:5432/myapp' \
-v "$PWD/dist:/artifacts:ro" \
ghcr.io/objectstack-ai/objectos:latestSee Runtime Configuration for the full matrix of drivers and connection options.
Docker Compose
A reference docker-compose.yml lives in the repo under docker/:
git clone https://github.com/objectstack-ai/objectos.git
cd objectos
mkdir -p docker/artifacts
cp /path/to/your/objectstack.json docker/artifacts/
export OS_AUTH_SECRET="$(openssl rand -hex 32)"
docker compose -f docker/docker-compose.yml upDefault port is 3000; override with OBJECTOS_PORT=3200 docker compose ....
Build your own image
If you need to embed an artifact, custom plugins, or your own SSL/CA bundle:
git clone https://github.com/objectstack-ai/objectos.git
cd objectos
docker build -f docker/Dockerfile -t myorg/objectos:custom .The shipped Dockerfile is a multi-stage build that produces a slim runtime image (~150 MB) on Node 22 Alpine.
What you need to keep separate
| Asset | Where it should live |
|---|---|
Artifact (objectstack.json) | Image (immutable) or mounted volume |
| Business database | Externally-managed Postgres / MySQL / Mongo |
| Identity & sessions | Same database |
| Uploaded files | Externally-managed S3 / R2 / disk volume |
Secrets (OS_AUTH_SECRET, DB URL, API keys) | Your secret manager, injected as env vars |
| Logs | stdout — collected by your log driver |
Verify
After startup:
curl -fsS http://localhost:3000/health
# {"status":"ok",...}Then sign in at http://localhost:3000/_account/register and confirm the API responds:
curl http://localhost:3000/api/v1/data/<your-object>Next
- Kubernetes — production-grade orchestration
- Air-gapped — running without internet egress
- Production Readiness — pre-flight checklist
- Observability — logs, metrics, audit