@@ -85,11 +85,38 @@ curl -fsS http://localhost:8080/api/v1/health
8585Upgrades are atomic: replace the artifact file and restart the service. Roll
8686back by restoring the previous artifact.
8787
88- ## Option 2 — Docker
88+ ## Option 2 — Docker (official image)
8989
90- The artifact model maps cleanly onto containers: the image contains Node, the
91- CLI, and one JSON file. The Dockerfile below (plus the compose stack in the
92- next section and a ` .dockerignore ` ) also ships ready-to-copy in
90+ The artifact model maps cleanly onto containers, and ObjectStack ships an
91+ ** official runtime image** for exactly this:
92+ ` ghcr.io/objectstack-ai/objectstack ` — Node 22 + ` @objectstack/cli ` +
93+ ` os start ` , running as a non-root user with a built-in health check and
94+ ` OS_ARTIFACT_PATH ` / ` OS_PORT=8080 ` preset. Image tags mirror
95+ ` @objectstack/cli ` versions (` 14.8.0 ` , ` 14.8 ` , ` 14 ` , ` latest ` ) and the image
96+ is published multi-arch (amd64/arm64) on every framework release — ** pin the
97+ exact version in production** , matching the CLI version in your
98+ ` package.json ` .
99+
100+ The fastest path needs no image build at all — hand the official image your
101+ compiled artifact:
102+
103+ ``` bash
104+ os build # → dist/objectstack.json (or in CI)
105+
106+ docker run -p 8080:8080 \
107+ -v " $PWD /dist/objectstack.json:/srv/app/objectstack.json:ro" \
108+ -e OS_DATABASE_URL=" postgres://user:pass@db-host:5432/myapp" \
109+ -e OS_AUTH_SECRET \
110+ -e OS_SECRET_KEY \
111+ ghcr.io/objectstack-ai/objectstack:14.8.0
112+ ```
113+
114+ (` OS_ARTIFACT_PATH ` also accepts an ` https:// ` URL, so the artifact can come
115+ straight from release storage instead of a mount.)
116+
117+ For a self-contained deployable image, extend it. The Dockerfile below (plus
118+ the compose stack in the next section and a ` .dockerignore ` ) ships
119+ ready-to-copy in
93120[ ` examples/docker ` ] ( https://github.com/objectstack-ai/framework/tree/main/examples/docker )
94121— drop the files into your scaffolded project.
95122
@@ -102,11 +129,28 @@ RUN npm ci
102129COPY . .
103130RUN npx os build # → dist/objectstack.json
104131
105- # ── Runtime stage: CLI + artifact only ───────────────────────────────
132+ # ── Runtime: the official ObjectStack runtime image ──────────────────
133+ FROM ghcr.io/objectstack-ai/objectstack:14.8.0
134+ COPY --from=build --chown=node:node /app/dist/objectstack.json /srv/app/objectstack.json
135+ ```
136+
137+ ``` bash
138+ docker build -t my-app .
139+ docker run -p 8080:8080 \
140+ -e OS_DATABASE_URL=" postgres://user:pass@db-host:5432/myapp" \
141+ -e OS_AUTH_SECRET \
142+ -e OS_SECRET_KEY \
143+ my-app
144+ ```
145+
146+ Prefer to build the runtime yourself (air-gapped registry, custom base
147+ image)? The official image is nothing more than:
148+
149+ ``` dockerfile title="Dockerfile (self-built runtime, equivalent)"
106150FROM node:22-slim
107151WORKDIR /srv/app
108- RUN npm install -g @objectstack/cli
109- COPY --from=build /app/ dist/objectstack.json ./objectstack.json
152+ RUN npm install -g @objectstack/cli@14.8.0
153+ COPY dist/objectstack.json ./objectstack.json
110154
111155ENV NODE_ENV=production \
112156 OS_ARTIFACT_PATH=/srv/app/objectstack.json \
@@ -119,15 +163,6 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=15s \
119163CMD ["os" , "start" ]
120164```
121165
122- ``` bash
123- docker build -t my-app .
124- docker run -p 8080:8080 \
125- -e OS_DATABASE_URL=" postgres://user:pass@db-host:5432/myapp" \
126- -e OS_AUTH_SECRET \
127- -e OS_SECRET_KEY \
128- my-app
129- ```
130-
131166<Callout type = " warn" >
132167** Never bake ` OS_AUTH_SECRET ` / ` OS_SECRET_KEY ` into the image.** Pass them at
133168runtime from your orchestrator's secret store. And never rely on the
0 commit comments