Release & Deployment
StarSpec deploys as two services: a static site served by nginx, and an MCP server serving TOON bundles. Both are built from a single multi-stage Dockerfile and orchestrated with Docker Compose.
Architecture
starspec.bitsquare.dev → site service (nginx, port 80)mcp.starspec.bitsquare.dev → mcp service (node, port 3000)Build pipeline inside Docker
pnpm install --frozen-lockfile │ ▼pnpm compile ← build compiler + mcp-server, run compiler │ generates: src/content/docs/**/*.mdx │ src/sidebar.json, src/summary.json │ dist/bundles/**/*.toon │ public/diagrams/ ▼ save bundles + summary.json ← preserved before astro build clears dist/ │ ▼pnpm build ← astro build → static site in dist/ │ ▼pnpm deploy --prod ← prune mcp-server to production deps only │ ┌────┴────┐ ▼ ▼ site mcp nginx node:alpine :80 :3000Build both images
pnpm docker:buildOr with tagged release images:
pnpm releaseThis tags both images using git describe (e.g. starspec-site:v1.2.3, starspec-mcp:v1.2.3) and also creates latest tags.
Override the image prefix for a remote registry:
IMAGE_PREFIX=ghcr.io/myorg/starspec pnpm releaseTest locally
Start both services:
docker compose -f build/docker-compose.yml upThen visit:
- Site: http://localhost:8080
- MCP health: http://localhost:3000/mcp/health
- MCP endpoint:
http://localhost:3000/mcp
To verify:
curl -s http://localhost:8080/ | head -1curl -s http://localhost:3000/mcp/healthStop with Ctrl-C or docker compose -f build/docker-compose.yml down.
Clean up
pnpm docker:cleanRemoves all built images and prunes the Docker build cache.
Deploy with Coolify
- Add a new resource in Coolify and point it at the Git repository.
- Select Docker Compose as the build pack.
- Set the Docker Compose location to
build/docker-compose.yml. - Map domains to services:
starspec.bitsquare.dev→site:80mcp.starspec.bitsquare.dev→mcp:3000
- Deploy.
No environment variables or volumes are required — both images are self-contained.
Journal mode
When starspec.config.js sets mode: "journal", the build extracts this at compile time and bakes it into the MCP image. The MCP server detects STARSPEC_MODE=journal at startup and exits immediately — no bundles, no API. The mcp service is configured with restart: no so Docker/Coolify leaves it stopped.
No configuration changes are needed in Coolify — the mode flag in starspec.config.js controls everything transparently.
Files
All build infrastructure lives in build/, except .dockerignore which Docker requires at the repo root.
| File | Purpose |
|---|---|
build/Dockerfile | Multi-stage: shared builder → site (nginx:alpine) + mcp (node:22-alpine) |
build/docker-compose.yml | Orchestrates both services |
build/nginx.conf | Gzip, caching headers, Astro-compatible path resolution |
build/release.sh | Builds and tags both images |
.dockerignore | Excludes node_modules, dist, .git from the build context |