Docs

Railway

Run and operate Grovs Community: railway.

Deploy Grovs Community from the Railway template. It creates the API, dashboard, two workers and three private database services with persistent volumes.

Railway compute, volumes, network usage and your object storage are billable. Use a plan with capacity for seven services and the custom domains below.

Deploy on Railway (opens in a new tab)

Deploy from the template

The template stores image references separately from runtime variables. Check the application services' image sources and use these to follow the latest stable images from GHCR:

ServicesImage source
web, worker-1, worker-2ghcr.io/grovs-io/backend:latest
dashboardghcr.io/grovs-io/dashboard:latest

You can replace latest on all four services with the version from the latest completed release to keep a fixed pair. A GROVS_VERSION runtime variable alone does not update a template service's image source. Leave the database image versions as supplied.

  1. Open Deploy on Railway and choose your workspace.

  2. Fill in the eight required variables on web: SERVER_HOST, DOMAIN_LIVE, DOMAIN_TEST, BOOTSTRAP_ADMIN_EMAIL, AWS_S3_KEY_ID, AWS_S3_ACCESS_KEY, AWS_S3_REGION and AWS_S3_BUCKET. Use a private bucket and bucket-scoped credentials. For S3-compatible storage, also set S3_ENDPOINT and S3_FORCE_PATH_STYLE as needed.

  3. Review the services, storage and estimated usage, then deploy. Railway generates the database passwords, application secrets and admin password. Keep these values when redeploying or upgrading.

  4. Add your custom domains in Networking, all targeting port 3000. For SERVER_HOST=grovs.example.com, DOMAIN_LIVE=links.example.com and DOMAIN_TEST=test.links.example.com, use:

    ServiceCustom domains
    dashboarddashboard.grovs.example.com
    webapi.grovs.example.com, sdk.grovs.example.com, mcp.grovs.example.com, go.grovs.example.com, preview.grovs.example.com, *.links.example.com, *.test.links.example.com
  5. Add the DNS and certificate-verification records Railway provides. Sign in at your dashboard domain using the admin email and generated BOOTSTRAP_ADMIN_PASSWORD from web's variables. Check the API /up endpoint, create a project, test links and confirm analytics.

The API initializes PostgreSQL and ClickHouse before starting. If a database is still starting during the first attempt, wait until it is ready and redeploy web. Workers wait for API health. Keep worker-1 at exactly one instance.

Alternative: deploy with the CLI

For a configuration managed in files, use the native Railway infrastructure definition below. It also declares the custom domains automatically. Choose this flow instead of deploying a second copy from the template.

1. Prepare your configuration

Install Node.js 22 or later, the Railway CLI, and OpenSSL. Clone the self-host repository:

Bash
git clone https://github.com/grovs-io/self-host.git
cd self-host
npm --prefix .railway ci
GROVS_RELEASE_URL="$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/grovs-io/self-host/releases/latest)"
GROVS_VERSION="${GROVS_RELEASE_URL##*/}" \
  GROVS_DOMAIN=grovs.example.com GROVS_LINKS_DOMAIN=links.example.com \
  [email protected] \
  ./scripts/prepare-railway.sh "$HOME/grovs-railway"
export GROVS_CONFIG_FILE="$HOME/grovs-railway/.env"

The private file contains generated secrets and your first admin login. Keep it outside Git and back it up. Fresh setup selects the latest completed release; subsequent runs preserve the file. The CLI definition requires a numbered GROVS_VERSION in this file; use the lookup above when selecting an update.

Create a private S3 bucket and add these values to the same file (uncomment their example lines):

AWS_S3_KEY_ID=your-access-key
AWS_S3_ACCESS_KEY=your-secret-key
AWS_S3_REGION=your-bucket-region
AWS_S3_BUCKET=your-bucket-name

Use bucket-scoped access for listing, reading, writing and deleting Grovs objects. S3-compatible storage also accepts S3_ENDPOINT and S3_FORCE_PATH_STYLE. The API and workers share the bucket; they cannot share a Railway volume. Railway volumes

2. Review and apply

Create a new empty Railway project and environment, then link this directory to it. Keep all services and their volumes in one region.

Bash
railway login
railway link
railway config plan
railway config apply

Verify the linked project/environment and proposed resources. apply asks for confirmation. The private configuration is the source for managed variables; update that file when changing settings. Avoid --show-values, which can print secrets. This uses Railway's current project-level IaC, not the deprecated per-service railway.json format. Railway IaC

The three volumes mount at PostgreSQL's /var/lib/postgresql/data, Redis's /data and ClickHouse's /var/lib/clickhouse. Redis uses AOF and noeviction. Database services have no public domains or TCP proxies. Keep application services always running; do not enable serverless sleeping for workers.

The API pre-deploy command initializes PostgreSQL and ClickHouse. Workers wait for API health before starting. If a datastore is still starting when the first pre-deploy command runs, wait for it to be ready and redeploy the API. Inspect logs to distinguish readiness failures from migration errors.

3. Finish DNS and sign in

Open each service's Networking settings. The definition requests the dashboard host on dashboard, and API/SDK/MCP/go/preview plus production/test wildcard domains on web, all targeting port 3000. Add the exact DNS records Railway supplies, including certificate verification CNAMEs.

For the example above, project links use *.links.example.com and *.test.links.example.com. Both require their own domain and certificate setup. Keep verification records unproxied if using Cloudflare DNS. Railway wildcard domains

Open https://dashboard.grovs.example.com and use the login printed by setup. Check https://api.grovs.example.com/up, create a project, open both production and test links, and confirm analytics. Upload an image and verify it survives an API redeployment.

Updates and backups

Stop both workers before upgrading; worker-1 must have exactly one running scheduler, including during rollouts. Back up databases, uploads and the private configuration. For the CLI flow, look up the latest release, change GROVS_VERSION in the private file, and review/apply. For template deployments, update or pull the service image sources listed above. Deploy the API and confirm migrations, then restart workers and dashboard with the matching release. Moving :latest tags take effect on an image pull and deployment, not on already-running containers.

Deleting services or volumes can delete data. Export your databases and review the deletion plan. Removing a Railway project does not remove an external S3 bucket or its charges.

Edit this page on GitHubLast updated 2026-09-15