Railway

Deploy Webstudio

Advanced Open Source Website Builder

Deploy Webstudio

Just deployed

Just deployed

Just deployed

Just deployed

Deploy and Host Webstudio on Railway

Webstudio is an open-source visual development platform and Webflow alternative. Designers and developers build sites in a full CSS canvas, connect any headless CMS, and publish static or SSR projects they actually own. This template self-hosts the full builder stack on Railway — Remix builder, PostgREST, Postgres, MinIO asset storage, and the community publisher.

About Hosting Webstudio

Hosting Webstudio means running five containers on Railway’s private network: a public builder (Remix visual editor), a public publisher (one-click Publish output), Postgres for projects and users, PostgREST as the REST API over that database, and MinIO as S3-compatible asset storage. Railway terminates TLS, so every container speaks HTTP internally and binds 0.0.0.0:${PORT}. You attach volumes for Postgres, MinIO, and the publisher’s publish/work directories, generate secrets once on the webstudio service, and let each entrypoint wait over IPv6 private DNS, run Prisma migrations, then exec the main process. First boot can take a few minutes while images pull and migrations apply. After that, sign in with DEV_LOGIN (password = AUTH_SECRET) and start a project.

The official ghcr.io/webstudio-is/webstudio registry only has two-year-old sha tags and no current latest builder. This kit wraps the production self-host images from webstudio-community/webstudio-self-host: ghcr.io/webstudio-community/builder:latest and ghcr.io/webstudio-community/webstudio-publisher:latest.

Common Use Cases

  • Run a private Webstudio builder for an agency or product team instead of Webstudio Cloud
  • Keep project data, assets, and published HTML on infrastructure you control (AGPL-3.0 core)
  • Publish marketing sites and landing pages from the visual canvas to a Railway domain or your own wildcard
  • Give developers a self-hosted target for webstudio link / the Webstudio CLI
  • Pair the builder with GitHub or Google OAuth when you outgrow the single shared DEV_LOGIN password

Dependencies for Webstudio Hosting

  • Builder image: ghcr.io/webstudio-community/builder:latest (Remix visual editor, Prisma, /health)
  • Publisher image: ghcr.io/webstudio-community/webstudio-publisher:latest (build API :4000 + site proxy :4001)
  • PostgreSQL 15 (postgres:15-alpine) — projects, users, sessions. PGDATA=/var/lib/postgresql/data
  • PostgREST 12.2 (postgrest/postgrest:v12.2.0) — REST API over Postgres, IPv6 listen (PGRST_SERVER_HOST=*)
  • MinIO (minio/minio) — S3-compatible object storage for canvas assets
  • Railway private networkingpostgres.railway.internal:5432, postgrest.railway.internal:3000, minio.railway.internal:${{minio.PORT}}, webstudio.railway.internal:${{webstudio.PORT}}, publisher.railway.internal:4000
  • Three persistent volumes (drives) — see Implementation Details

Name the services exactly postgres, postgrest, minio, webstudio, and publisher. Set each service Root Directory to its folder. Keep postgres and postgrest private. Give webstudio, publisher, and minio public domains (MinIO must be public so browser asset URLs resolve).

Upstream: Webstudio · Docs · Self-host compose · Source · License AGPL-3.0-or-later

Implementation Details

Clone the template to see how it works:

webstudio/      # public builder
  Dockerfile    # FROM ghcr.io/webstudio-community/builder:latest
  entrypoint.sh # IPv6 wait, prisma migrate deploy, exec node /app/server.js
  wait-for.cjs  # dual-stack TCP/HTTP probe
  railway.toml  # healthcheck /health, 300s timeout
publisher/      # public published sites
  Dockerfile    # FROM ghcr.io/webstudio-community/webstudio-publisher:latest
  gateway.mjs   # $PORT → API :4000 + site proxy :4001
  entrypoint.sh # wait for builder /health, exec gateway
  railway.toml  # healthcheck /health, 300s timeout
postgres/
  Dockerfile    # postgres:15-alpine, listen_addresses=*
  init.sql      # uuid-ossp, anon role, default privileges
minio/
  Dockerfile    # minio + mc on debian-slim (scratch upstream has no shell)
  entrypoint.sh # create public-read bucket, exec minio on $PORT
postgrest/
  Dockerfile    # postgrest v12.2 + psql + python wait
  entrypoint.sh # wait for Prisma migrations, GRANT anon, exec postgrest

Topology

Name the services exactly as written. Private DNS is .railway.internal. If you rename them, the builder cannot find Postgres, PostgREST, MinIO, or the publisher.

ServiceRoleRoot DirectoryVolumeMemoryPublic
postgresProject databasepostgres/var/lib/postgresql1 GBNo
postgrestREST API over PostgrespostgrestNone512 MBNo
minioS3 asset storageminio/data512 MBYes
webstudioVisual builderwebstudioNone1 GB floor, 2 GB betterYes
publisherPublish API + site proxypublisher/var/publish and /var/work1 GB floor, 2 GB betterYes
Volumes (drives) — what to mount

Attach before the first successful start. Skip this and init lands on ephemeral disk; the next deploy wipes projects, assets, and published sites.

ServiceMount pathWhat is storedStart size
postgres/var/lib/postgresqlUsers, projects, builds, sessions. PGDATA is already /var/lib/postgresql/data.1 GB
minio/dataUploaded canvas assets (images, fonts, files) and the bucket-init marker.1 GB
publisher/var/publishGenerated static sites, one directory per publish domain.1 GB
publisher/var/workPublisher working copies and state.json per domain.1 GB
webstudiodo not mount anythingStateless. Assets live in MinIO. Railway terminates TLS.
postgrestdo not mount anythingStateless API.

Do not mount /etc/letsencrypt, Traefik dynamic config, or SSL certificates. Those are VPS/Coolify paths. Railway already terminates TLS in front of every public service.

Railway: each service → SettingsVolumesAdd Volume → paste the mount path exactly. The publisher needs two volumes.

Traps

Ways this still fails:

  • Do not use Railway’s Postgres plugin. The builder expects user postgres, database webstudio, the anon role, and uuid-ossp in schema extensions. The kit’s postgres service is the matching pair. Pointing DATABASE_URL at a plugin instance skips init.sql and PostgREST cannot read tables.
  • Attach volumes before the first successful start. Postgres init SQL, the MinIO bucket, and published sites all live on those mounts. A first boot without volumes writes to ephemeral disk; the next deploy looks like an empty install.
  • Private DNS is IPv6. localhost, 127.0.0.1, and ::1 are wrong for cross-service traffic. Use postgres.railway.internal, postgrest.railway.internal, minio.railway.internal, webstudio.railway.internal, publisher.railway.internal. PostgREST is forced to PGRST_SERVER_HOST=* so it actually listens on IPv6. If the builder waits forever, redeploy the app — do not restart Postgres to “fix” DNS.
  • Do not put TLS inside the container. Railway terminates HTTPS. The builder already sets Express trust proxy, so req.protocol is https and __Host- cookies work. Setting ALLOW_INSECURE_COOKIES=true in production crashes the process.
  • DEPLOYMENT_URL must match the live domain. Generate the webstudio public domain first, set DEPLOYMENT_URL=https://${{RAILWAY_PUBLIC_DOMAIN}} with no trailing slash, then deploy. If you add a custom domain later, update DEPLOYMENT_URL and redeploy or login/OAuth callbacks miss.
  • MinIO must be public. S3_ENDPOINT is the public https:// MinIO domain so canvas <img> tags load in the browser. A private MinIO makes uploads succeed and previews break. Do not point S3_ENDPOINT at http://minio.railway.internal.
  • Published sites need a wildcard custom domain. PUBLISHER_HOST defaults to the publisher’s *.up.railway.app hostname. Nested hosts like myproject..up.railway.app will not resolve. Add a custom domain (for example sites.example.com) plus a DNS wildcard *.sites.example.com on the publisher service, then set PUBLISHER_HOST=sites.example.com on both webstudio and publisher.
  • Canvas preview iframes need a wildcard on the builder. Self-hosted Webstudio serves the canvas at *.your-builder-domain. Add *.builder.example.com as a wildcard custom domain on webstudio if project iframes stay blank.
  • Do not generate a second POSTGRES_PASSWORD on the postgres service. Use ${{webstudio.POSTGRES_PASSWORD}}. A new secret(32) on postgres desyncs the URI and every connection fails authentication.

Why Deploy Webstudio on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Webstudio on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.


Template Content

More templates in this category

View Template
Libredesk - Complete Setup
Complete self-hosted omnichannel customer support desk.

codestorm
1
View Template
Paperless-ngx
Paperless-ngx — document management with OCR and full-text search

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

Instatic
147