This repo packages OpenClaw for Railway with a small /setup web wizard so users can deploy and onboard without running any commands.
- OpenClaw Gateway + Control UI (served at
/and/openclaw) - A friendly Setup Wizard at
/setup(protected by a password) - Persistent state via Railway Volume (so config/credentials/memory survive redeploys)
- One-click Export backup (so users can migrate off Railway later)
- Import backup from
/setup(advanced recovery)
- The container runs a wrapper web server.
- The wrapper protects
/setupwithSETUP_PASSWORD. - During setup, the wrapper runs
openclaw onboard --non-interactive ...inside the container, writes state to the volume, and then starts the gateway. - After setup,
/is OpenClaw. The wrapper reverse-proxies all traffic (including WebSockets) to the local gateway process.
In Railway Template Composer:
- Create a new template from this GitHub repo.
- Add a Volume mounted at
/data. - Set the following variables:
Required:
SETUP_PASSWORD— user-provided password to access/setup
Recommended:
OPENCLAW_STATE_DIR=/data/.openclawOPENCLAW_WORKSPACE_DIR=/data/workspace
Optional:
OPENCLAW_GATEWAY_TOKEN— if not set, the wrapper generates one (not ideal). In a template, set it using a generated secret.
Notes:
- This template pins OpenClaw to a released version by default via Docker build arg
OPENCLAW_GIT_REF(override if you wantmain).
- Enable Public Networking (HTTP). Railway will assign a domain.
- This service listens on Railway’s injected
PORTat runtime (recommended).
- This service listens on Railway’s injected
- Deploy.
Then:
- Visit
https://<your-app>.up.railway.app/setup - Complete setup
- Visit
https://<your-app>.up.railway.app/and/openclaw
- GitHub Issues: https://github.com/vignesh07/clawdbot-railway-template/issues
- Discord: https://discord.com/invite/clawd
If you’re filing a bug, please include the output of:
/healthz/setup/api/debug(after authenticating to /setup)
- Open Telegram and message @BotFather
- Run
/newbotand follow the prompts - BotFather will give you a token that looks like:
123456789:AA... - Paste that token into
/setup
- Go to the Discord Developer Portal: https://discord.com/developers/applications
- New Application → pick a name
- Open the Bot tab → Add Bot
- Copy the Bot Token and paste it into
/setup - Invite the bot to your server (OAuth2 URL Generator → scopes:
bot,applications.commands; then choose permissions)
Railway containers have an ephemeral filesystem. Only the mounted volume at /data persists across restarts/redeploys.
What persists cleanly today:
- Custom skills / code: anything under
OPENCLAW_WORKSPACE_DIR(default:/data/workspace) - Node global tools (npm/pnpm): this template configures defaults so global installs land under
/data:- npm globals:
/data/npm(binaries in/data/npm/bin) - pnpm globals:
/data/pnpm(binaries) +/data/pnpm-store(store)
- npm globals:
- Python packages: create a venv under
/data(example below). The runtime image includes Python + venv support.
What does not persist cleanly:
apt-get install ...(installs into/usr/*)- Homebrew installs (typically
/opt/homebrewor similar)
If /data/workspace/bootstrap.sh exists, the wrapper will run it on startup (best-effort) before starting the gateway.
Use this to initialize persistent install prefixes or create a venv.
Example bootstrap.sh:
#!/usr/bin/env bash
set -euo pipefail
# Example: create a persistent python venv
python3 -m venv /data/venv || true
# Example: ensure npm/pnpm dirs exist
mkdir -p /data/npm /data/npm-cache /data/pnpm /data/pnpm-storeThis is not a crash — it means the gateway is running, but no device has been approved yet.
Fix:
- Open
/setup - Use the Debug Console:
openclaw devices listopenclaw devices approve <requestId>
If openclaw devices list shows no pending request IDs:
- Make sure you’re visiting the Control UI at
/openclaw(or your native app) and letting it attempt to connect - Ensure your state dir is the Railway volume (recommended):
OPENCLAW_STATE_DIR=/data/.openclaw - Check
/setup/api/debugfor the active state/workspace dirs + gateway readiness
The Control UI connects using gateway.remote.token and the gateway validates gateway.auth.token.
Fix:
- Re-run
/setupso the wrapper writes both tokens. - Or set both values to the same token in config.
Most often this means the wrapper is up, but the gateway can’t start or can’t bind.
Checklist:
- Ensure you mounted a Volume at
/dataand set:OPENCLAW_STATE_DIR=/data/.openclawOPENCLAW_WORKSPACE_DIR=/data/workspace
- Ensure Public Networking is enabled (Railway will inject
PORT). - Check Railway logs for the wrapper error: it will show
Gateway not ready:with the reason.
If you see warnings about deprecated CLAWDBOT_* variables or state dir split-brain (e.g. ~/.openclaw vs /data/...):
- Use
OPENCLAW_*variables only - Ensure
OPENCLAW_STATE_DIR=/data/.openclawandOPENCLAW_WORKSPACE_DIR=/data/workspace - Redeploy after fixing Railway Variables
Building OpenClaw from source can exceed small memory tiers.
Recommendations:
- Use a plan with 2GB+ memory.
- If you see
Reached heap limit Allocation failed - JavaScript heap out of memory, upgrade memory and redeploy.
docker build -t clawdbot-railway-template .
docker run --rm -p 8080:8080 \
-e PORT=8080 \
-e SETUP_PASSWORD=test \
-e OPENCLAW_STATE_DIR=/data/.openclaw \
-e OPENCLAW_WORKSPACE_DIR=/data/workspace \
-v $(pwd)/.tmpdata:/data \
clawdbot-railway-template
# open http://localhost:8080/setup (password: test)-
Officially recommended by OpenClaw: https://docs.openclaw.ai/railway
-
Railway announcement (official): Railway tweet announcing 1‑click OpenClaw deploy
-
Endorsement from Railway CEO: Jake Cooper tweet endorsing the OpenClaw Railway template
-
Created and maintained by Vignesh N (@vignesh07)
-
1800+ deploys on Railway and counting Link to template on Railway


