Skip to content

Commit 8e0a5a7

Browse files
committed
feat(create-objectstack): scaffolded projects ship container-ready
The blank template now includes the docker trio from examples/docker, adapted for in-project use (no 'copy these files' indirection): - Dockerfile — two-stage build onto the official runtime image ghcr.io/objectstack-ai/objectstack - docker-compose.yml — app + Postgres single-host stack - .dockerignore Plus a Deploy section in the template README and a production one-liner in the framework README Quick Start. Verified: package build copies the trio (incl. the dotfile) into dist/templates; a real scaffold run (--skip-install) lands all three files with the official-image FROM line intact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0162o68e5w3bpUBEVRQboUGG
1 parent e7d5291 commit 8e0a5a7

6 files changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"create-objectstack": minor
3+
---
4+
5+
Scaffolded projects are now container-ready out of the box: the `blank` template ships a `Dockerfile` (two-stage build onto the official `ghcr.io/objectstack-ai/objectstack` runtime image), a `docker-compose.yml` (app + Postgres single-host stack), and a `.dockerignore`, plus a Deploy section in the project README. `docker build -t my-app .` works immediately after `npm create objectstack`.

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ pnpm dev
124124

125125
Alternatively, with the CLI installed: `os init my-app && cd my-app && os dev`.
126126

127+
Ready for production? The scaffolded project is container-ready:
128+
129+
```bash
130+
docker build -t my-app . && docker compose up -d # app + Postgres on the official runtime image
131+
```
132+
133+
See [Self-Hosted Deployment](https://docs.objectstack.ai/docs/deployment/self-hosting) for bare Node, Kubernetes, and the secrets you must pin.
134+
127135
### For Framework Contributors
128136

129137
```bash
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules
2+
dist
3+
.git
4+
*.log
5+
.env
6+
cookies.txt
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Container build for this ObjectStack app.
2+
#
3+
# docker build -t my-app .
4+
# docker run -p 8080:8080 \
5+
# -e OS_DATABASE_URL="postgres://user:pass@db-host:5432/myapp" \
6+
# -e OS_AUTH_SECRET -e OS_SECRET_KEY \
7+
# my-app
8+
#
9+
# Or run the full app + Postgres stack: see docker-compose.yml.
10+
# Docs: https://docs.objectstack.ai/docs/deployment/self-hosting
11+
12+
# ── Build stage: compile TypeScript metadata to the artifact ─────────
13+
FROM node:22-slim AS build
14+
WORKDIR /app
15+
COPY package*.json ./
16+
RUN npm ci
17+
COPY . .
18+
RUN npx os build # → dist/objectstack.json
19+
20+
# ── Runtime: the official ObjectStack runtime image ──────────────────
21+
# Ships Node + @objectstack/cli with `os start`, a non-root user, the
22+
# /api/v1/health HEALTHCHECK, and OS_ARTIFACT_PATH/OS_PORT preset (port 8080)
23+
# — see docker/README.md in the framework repo. Pin the tag to the
24+
# @objectstack/cli version in your package.json so the runtime matches the
25+
# CLI that built the artifact.
26+
FROM ghcr.io/objectstack-ai/objectstack:latest
27+
COPY --from=build --chown=node:node /app/dist/objectstack.json /srv/app/objectstack.json
28+
29+
# OS_DATABASE_URL, OS_AUTH_SECRET, and OS_SECRET_KEY are injected at runtime —
30+
# never bake them into the image.

packages/create-objectstack/src/templates/blank/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,29 @@ otherwise fail *silently at runtime* — e.g. a bare `done` (instead of
4040
`record.done`) in an action predicate that would hide the action on every
4141
record. See `AGENTS.md` for the full convention.
4242

43+
## Deploy
44+
45+
The project ships container-ready — the `Dockerfile` builds your metadata into
46+
an artifact and runs it on the official ObjectStack runtime image
47+
(`ghcr.io/objectstack-ai/objectstack`):
48+
49+
```bash
50+
# Image only
51+
docker build -t my-app .
52+
53+
# Or the full app + Postgres stack
54+
cat > .env <<EOF
55+
POSTGRES_PASSWORD=$(openssl rand -hex 16)
56+
OS_AUTH_SECRET=$(openssl rand -hex 32)
57+
OS_SECRET_KEY=$(openssl rand -hex 32)
58+
EOF
59+
docker compose up -d
60+
curl -fsS http://localhost:8080/api/v1/health
61+
```
62+
63+
Bare Node, Kubernetes, reverse-proxy wiring, and the required secrets are
64+
covered in [Self-Hosted Deployment](https://docs.objectstack.ai/docs/deployment/self-hosting).
65+
4366
## Next steps
4467

4568
- Add an object: see the `objectstack-data` skill.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Single-host production stack: this app + Postgres.
2+
#
3+
# Create a .env file next to this compose file (never committed) with
4+
# POSTGRES_PASSWORD / OS_AUTH_SECRET / OS_SECRET_KEY (generate secrets with
5+
# `openssl rand -hex 32`), then `docker compose up -d`.
6+
#
7+
# Docs: https://docs.objectstack.ai/docs/deployment/self-hosting
8+
9+
services:
10+
app:
11+
build: .
12+
ports:
13+
- "8080:8080"
14+
environment:
15+
OS_DATABASE_URL: postgres://objectstack:${POSTGRES_PASSWORD}@db:5432/myapp
16+
OS_AUTH_SECRET: ${OS_AUTH_SECRET}
17+
OS_SECRET_KEY: ${OS_SECRET_KEY}
18+
depends_on:
19+
db:
20+
condition: service_healthy
21+
restart: unless-stopped
22+
23+
db:
24+
image: postgres:17
25+
environment:
26+
POSTGRES_USER: objectstack
27+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
28+
POSTGRES_DB: myapp
29+
volumes:
30+
- pgdata:/var/lib/postgresql/data
31+
healthcheck:
32+
test: ["CMD-SHELL", "pg_isready -U objectstack -d myapp"]
33+
interval: 5s
34+
timeout: 3s
35+
retries: 10
36+
restart: unless-stopped
37+
38+
volumes:
39+
pgdata:

0 commit comments

Comments
 (0)