Railway

Deploy Instatic

Open-source Webflow alternative: canvas editor, CMS, collections, pages

Deploy Instatic

/var/lib/postgresql/data

Just deployed

/app/storage

Instatic official git

Deploy and Host Instatic on Railway

Instatic is an open-source, self-hosted visual CMS and website builder — the MIT-licensed alternative to Webflow, Framer and WordPress. One Bun server holds the canvas editor, content engine, media library, auth, forms, plugins and the publisher. Visitors get plain semantic HTML and compact CSS: a page published from this template's own deployment was a 487-byte document with a script-src 'none' CSP.

Self-host Instatic on Railway as two services. instatic runs ghcr.io/corebunch/instatic:0.0.14 on target port 8080 with the public domain, and mounts one volume at /app/storage for media, fonts, plugin packages and published artefacts. The private Postgres service holds pages, collections, users, form submissions and the audit log. Migrations run at container start, before the server binds — no migrate step, no pre-deploy command.

Instatic Railway architecture

Getting Started with Instatic on Railway

Open the generated Railway domain once the deploy goes green. There are no default credentials: the first visit shows a one-time Set Up CMS screen asking for a site name, owner email and a 12-character minimum password, then creates the site, owner account and a starter homepage. That setup endpoint is one-shot — 409 afterwards — so it is never an open sign-up. Open the editor at /admin/site, drop a text module on the canvas and press Publish site; the first publish of a session re-asks for your password (step-up auth, 15-minute default). Until you publish, the root returns 404 {"error":"Not found"} — expected, not a failed deploy: /health is 200 from boot and /admin always reachable. A 200 with your own markup means app, volume and Postgres all work:

curl -i https://your-app.up.railway.app/
curl -s https://your-app.up.railway.app/health

Instatic dashboard screenshot

About Hosting Instatic

Instatic is one container plus a database where a headless CMS would be four moving parts. Self-host it when SEO depends on clean markup, when client work must be handed over without lock-in, or when content cannot leave your servers.

  • Visual canvas editor — mobile, tablet and desktop breakpoints edited side by side, a layers tree, reusable components and templates.
  • Content, data and media — pages, posts and custom collections, a schema builder with repeaters, CMS-native forms writing to your own tables, Sharp-generated responsive images, whole-site import.
  • Security and extensibility — optional TOTP MFA, 38 access-control capabilities, login lockout, CSRF checks, step-up auth before publishing, audit log; plugins run in a QuickJS-WASM sandbox with no filesystem, env vars or network unless granted; the AI assistant (Anthropic, OpenAI, OpenRouter, Ollama) stays off until you add a key.

Why Deploy Instatic on Railway

Railway runs the image and database as one project, with no infrastructure work:

  • One-click deploy of ghcr.io/corebunch/instatic:0.0.14, pinned rather than latest.
  • A managed Postgres service wired in over private networking.
  • A persistent volume at /app/storage that survives every redeploy.
  • Automatic HTTPS on a generated domain, plus custom domains.
  • RAILWAY_RUN_UID=0 and the /health check preset, so media writes work first try.
  • Usage-based pricing, logs, metrics and one-click rollbacks.

Common Use Cases Instatic

  • Marketing sites that must rank — static semantic HTML, no framework payload, real visual editing.
  • Client sites an agency hands over — editor, content, media, forms and users in one container.
  • Docs, changelogs and structured blogs — define collections once, render with repeaters.
  • Lead capture without a form SaaS — build the form on the canvas, query submissions in Postgres.

Dependencies for Instatic

  • instaticghcr.io/corebunch/instatic:0.0.14. Prebuilt admin UI, Bun server, renderer, CMS API and migrations; port 8080, health check /health, volume at /app/storage.
  • Postgres — Railway's PostgreSQL template: all CMS state that is not a file, private, reached via ${{Postgres.DATABASE_URL}}.

Pin an explicit tag: Instatic is pre-1.0 and breaking changes can land in patch releases. Use 0.0.14 or later — it fixes a sanitizer bypass letting a javascript: URL behind a control character reach an href (GHSA-pqcp-872g-gmp8).

Instatic Environment Variables Reference

VariableValueWhat it does
PORT8080Public target port
DATABASE_URL${{Postgres.DATABASE_URL}}Internal Postgres URL
UPLOADS_DIR/app/storage/uploadsMedia path under the volume
STATIC_DIR/app/distCompiled admin UI in image
INSTATIC_SECRET_KEYbase64 32-byte keyEncrypts AI creds, TOTP seeds
PUBLIC_ORIGINhttps://${{RAILWAY_PUBLIC_DOMAIN}}CSRF origin check
RAILWAY_RUN_UID0Required for volume writes

STATIC_DIR stays in the image: build output, not user data. Keep INSTATIC_SECRET_KEY stable — rotating it invalidates stored AI credentials and TOTP seeds. Add a custom domain to PUBLIC_ORIGIN as a second comma-separated entry. Optional TRUSTED_PROXY_CIDRS only changes client-IP attribution in audit logs and rate-limit keys — not CSRF — and must never be 0.0.0.0/0.

Deployment Dependencies

github.com/corebunch/instatic (MIT) and its deployment docs; images on ghcr.io/corebunch/instatic.

Hardware Requirements for Self-Hosting Instatic

ResourceMinimumRecommended
CPU1 vCPU2 vCPU
RAM512 MB1–2 GB
Storage1 GB volume5–10 GB, plus the Postgres volume
RuntimeBun, in the imageBun, in the image

Idle on a live deployment: ~175 MB memory, negligible CPU, 83 MB of volume used. Headroom covers Sharp image variants and larger publishes. Back up the volume and the database — neither alone is complete.

Keep the app at one replica. Its 10-second scheduler loops elect a leader with Postgres session-scoped advisory locks, but the Bun SQL client is a pool, so an unlock can land on a different backend than the lock — harmless on one replica (a recurring log warning, a skipped tick that retries), unreliable across several.

Self-Hosting Instatic with Docker

Instatic runs anywhere Docker does and needs a persistent mount at /app/storage. With external Postgres:

docker run -d --name instatic --restart unless-stopped \
  -p 3001:3001 \
  -e PORT=3001 \
  -e DATABASE_URL="postgres://user:password@host:5432/instatic" \
  -e UPLOADS_DIR=/app/storage/uploads \
  -e STATIC_DIR=/app/dist \
  -e INSTATIC_SECRET_KEY="" \
  -v instatic-storage:/app/storage \
  ghcr.io/corebunch/instatic:0.0.14

The database is chosen purely by DATABASE_URL — same image, same migrations — so a single-service SQLite install swaps that value for sqlite:/app/storage/data/cms.db. The repository also ships Compose files:

INSTATIC_IMAGE=ghcr.io/corebunch/instatic:0.0.14 \
  docker compose -f compose.prod.yml -f compose.sqlite.yml up -d

Is Instatic Free? How Much Does It Cost to Self-Host?

Instatic is free and MIT-licensed — no paid tier, no open-core holdbacks, no per-seat or per-site fee. On Railway you pay for infrastructure only: CPU and memory for the Bun process, the Postgres service and the two volumes — a small footprint at the idle profile above. The one optional extra is your own AI key.

FAQ

What is Instatic?

An MIT-licensed, self-hosted visual CMS and website builder positioned against Webflow, Framer and WordPress. One Bun server runs the editor, content engine, media, auth, forms, plugins and publisher, emitting plain semantic HTML.

What does this Railway template deploy?

Two services: instatic on ghcr.io/corebunch/instatic:0.0.14 with a public domain on port 8080, a /health check and a volume at /app/storage, plus a private Postgres for CMS data.

Why does this Instatic template need both Postgres and a volume?

Postgres stores pages, collections, users, form submissions and the audit log; the volume stores media, fonts, plugins and published artefacts.

What are the default login credentials for self-hosted Instatic?

None exist. The first visit shows a one-time setup screen where you create the site and owner account; it returns 409 once used, so it cannot be replayed.

Why does my self-hosted Instatic site return 404 at the root?

Nothing has been published yet — Instatic serves published output only, so GET / responds 404 {"error":"Not found"} until you publish. /admin and /health work from boot.


Template Content

More templates in this category

View Template
Libredesk - Complete Setup
[Jul'26] Complete self-hosted omnichannel customer support desk.

codestorm
1
View Template
Instatic CMS - Postgres
Design, build and manage powerful static sites from state-of-the-art CMS

Instatic
124
View Template
Strapi
A popular self-hosted CMS

Milo
7.7K