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:
| Services | Image source |
|---|---|
web, worker-1, worker-2 | ghcr.io/grovs-io/backend:latest |
dashboard | ghcr.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.
-
Open Deploy on Railway and choose your workspace.
-
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_REGIONandAWS_S3_BUCKET. Use a private bucket and bucket-scoped credentials. For S3-compatible storage, also setS3_ENDPOINTandS3_FORCE_PATH_STYLEas needed. -
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.
-
Add your custom domains in Networking, all targeting port 3000. For
SERVER_HOST=grovs.example.com,DOMAIN_LIVE=links.example.comandDOMAIN_TEST=test.links.example.com, use:Service Custom domains dashboarddashboard.grovs.example.comwebapi.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 -
Add the DNS and certificate-verification records Railway provides. Sign in at your dashboard domain using the admin email and generated
BOOTSTRAP_ADMIN_PASSWORDfromweb's variables. Check the API/upendpoint, 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:
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-nameUse 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.
railway login
railway link
railway config plan
railway config applyVerify 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.