Self-host
Run the whole thing on your own box.
One Docker command brings up the full stack. Your data stays yours, every feature included, free forever under AGPL-3.0.
Prerequisites: Docker with Compose v2 · 1 GB RAM / 1 vCPU is plenty for a small team
git clone https://github.com/StoryFunnels/storyOS.git storyos && cd storyos
echo "BETTER_AUTH_SECRET=$(openssl rand -hex 32)" > .env
docker compose up -d Verify: docker compose ps shows postgres, api, web and caddy healthy → open http://localhost and sign up.
What gets copied
Help me self-host StoryOS (open-source, AGPL-3.0) with Docker. 1. Check prerequisites: Docker with Compose v2. 1 GB RAM / 1 vCPU is enough for a small team. 2. Run: git clone https://github.com/StoryFunnels/storyOS.git storyos && cd storyos echo "BETTER_AUTH_SECRET=$(openssl rand -hex 32)" > .env docker compose up -d 3. Verify: docker compose ps should show postgres, api, web and caddy healthy; then open http://localhost and sign up (first account creates a workspace). 4. For a real deployment: set API_URL and WEB_URL in .env to the SAME public URL (e.g. https://os.example.com) - auth validates request origins against WEB_URL, so a mismatch shows "Invalid origin" at login. Put the domain behind Cloudflare (proxied) or edit docker/Caddyfile for Caddy-managed TLS. 5. Backups: docker compose exec postgres pg_dump -U storyos storyos > backup.sql plus an archive of the storyos_attachments volume. 6. Full env matrix and upgrade steps: https://docs.storyos.dev
Clone and configure
One repo has everything — API, web app, MCP server, proxy. The only required setting is an auth secret.
docker compose up
Postgres, the API, the web app and a reverse proxy come up together on one origin (port 80). Migrations run automatically.
Sign up
Open http://localhost — the first account creates its own workspace. Install a template or start blank.
Configuration that matters
Set in .env next to docker-compose.yml. Only the auth secret is required.
| Variable | Default | Notes |
|---|---|---|
| BETTER_AUTH_SECRET | — (required) | openssl rand -hex 32 |
| POSTGRES_PASSWORD | storyos | change for anything internet-facing |
| API_URL / WEB_URL | localhost defaults | set BOTH to your public URL for real deployments |
| HTTP_PORT / HTTPS_PORT | 80 / 443 | host ports of the bundled proxy |
| SMTP_* , MAIL_FROM | unset | without SMTP, invite links are copyable in the UI; other emails are logged |
| STORAGE_DRIVER | local | s3 for MinIO / S3 / R2 (bundled MinIO profile included) |
Going to production
Set API_URL and WEB_URL to the same public URL — auth validates origins against WEB_URL. TLS: proxy the domain through Cloudflare, or edit docker/Caddyfile and let Caddy issue certificates.
Backup & upgrade
pg_dump the database plus an archive of the attachments volume — two commands, both in the docs. Upgrades are git pull && docker compose build && docker compose up -d; migrations run idempotently on boot.
Full matrix, MinIO storage, SMTP and Google-login setup: docs.storyos.dev →
Why teams self-host StoryOS
Your data never leaves
Records, files, and documents live on your box, in your Postgres. No third party sees them.
No feature caps
Self-host is the complete product. Every view, formula, automation and the MCP — included, with unlimited records.
Use your own AI
Connect your own Claude or ChatGPT. You control cost and provider — and we never meter it.
AGPL-3.0, auditable
The full source is public. Read it, fork it, run it. No hidden telemetry.
Rather not run servers?
The hosted plans start free — 30 days of Pro, no card — and it's the same product, same data model. Move between them any time.