- Railway deploys OpenClaw from a GitHub repo or Docker image in under 5 minutes with zero server config
- You must mount a persistent Volume at /data or OpenClaw loses all agent state on every redeploy
- Set all secrets in Railway's Variables tab — never in your repo or Dockerfile
- Railway's auto-generated HTTPS URL works out of the box for webhook integrations with no reverse proxy needed
- The Hobby plan ($5/month) is sufficient for personal OpenClaw use; Pro plan adds always-on uptime guarantees
Most people spending 3 hours configuring an EC2 instance for OpenClaw don't need that much control. They need a running agent with a stable URL, persistent state, and automatic restarts. Railway delivers all three in the time it takes to push a Git commit.
Why Railway for OpenClaw
Railway's architecture maps almost perfectly to what OpenClaw needs. You get a persistent process (not a serverless function that sleeps), a stable public URL with automatic HTTPS, volume mounts for agent memory, and environment variable injection for secrets. That's the entire OpenClaw hosting checklist.
The tradeoff versus a raw VPS is control. You can't configure kernel parameters, choose your Linux distro, or run privileged containers. For the vast majority of OpenClaw deployments, that control isn't needed and the Railway approach is strictly faster.
Here's where most people stop: they deploy OpenClaw to Railway, the bot responds for a few hours, then mysteriously forgets everything. The cause is always the same — no persistent volume configured, so every redeploy resets OpenClaw's data directory. We'll fix that in step 3.
Project Setup
You need a Railway account and either a GitHub repo containing your OpenClaw config, or you can use Railway's Docker image deployment to pull OpenClaw directly. The Docker approach requires no repo and is the fastest path.
Log into railway.app, click New Project, and choose "Deploy from Docker Image." Enter the OpenClaw Docker image: openclaw/openclaw:latest. Railway will pull the image and prepare your service.
In your service's Settings tab, set the Start Command to openclaw serve --config /data/config.yaml --port $PORT. The $PORT variable is injected by Railway automatically — OpenClaw must bind to this port for Railway's routing to work.
Railway dynamically assigns a port and injects it as the PORT environment variable. If you hardcode port 3000 or 8080 in your start command, Railway's health checks will fail and your deployment will never go live.
Deploy OpenClaw
Before adding environment variables, do a first deploy to confirm the image pulls correctly. Railway will show the build logs in real time. A successful first deploy ends with something like:
# Expected Railway deploy log output
Pulling image: openclaw/openclaw:latest
Image pulled successfully
Starting service on port 8432
OpenClaw v1.6.2 starting...
Config file not found at /data/config.yaml — using defaults
Listening on 0.0.0.0:8432
The "config file not found" message is expected on the first deploy — you haven't mounted your volume or set your config yet. Railway will show the service as running but OpenClaw will be in default mode.
Before troubleshooting anything else, always look at Railway's deploy logs. The most common issue — a wrong start command or missing PORT binding — shows up immediately in the first 5 lines of output.
Persistent Volume — The Critical Step
This is the step that every "Railway OpenClaw" tutorial skips, and it's why agents on Railway forget everything every time you redeploy.
In your service's Storage tab, click Add Volume and configure it:
- Mount Path:
/data - Size: 5 GB (increase later if needed)
After adding the volume, redeploy the service. Now create your OpenClaw config file on the volume:
# SSH into your Railway service shell (via the Railway CLI)
railway shell
# Create the OpenClaw config
mkdir -p /data
cat > /data/config.yaml <<'EOF'
data_dir: /data
server:
port: ${PORT}
host: 0.0.0.0
model:
provider: openai
api_key: ${OPENAI_API_KEY}
logging:
level: info
file: /data/openclaw.log
EOF
# Initialise the data directory
openclaw init --data-dir /data --skip-if-exists
Everything OpenClaw writes to /data now persists across deploys, restarts, and Railway maintenance windows.
Environment Variables
Railway's Variables tab is where all secrets live. Add these before your final deploy:
OPENAI_API_KEY— your model provider API keyOC_SECRET— a random 32-character string for signing webhook payloadsOC_ADMIN_TOKEN— a strong token for OpenClaw's admin APIRAILWAY_RUN_UID— set to1000to avoid file permission issues on the volume
Railway injects these as environment variables at runtime. They're never written to disk or visible in deploy logs. As of early 2025, Railway also supports secret references between services — useful if you're running a PostgreSQL service alongside OpenClaw for agent memory storage.
Custom Domain and HTTPS
Railway gives every service a *.up.railway.app subdomain with HTTPS automatically. That's enough for most webhook integrations.
For a custom domain, go to your service's Settings → Networking → Add Custom Domain. Enter your domain, then add a CNAME record pointing your domain to Railway's provided target. Railway provisions a Let's Encrypt certificate automatically — no certbot, no nginx config.
Update your OpenClaw webhook URLs after adding the custom domain:
# Update webhook URL in config or via CLI
openclaw config set webhook.base_url https://your-domain.com
Common Mistakes
- No persistent volume — OpenClaw resets on every deploy. Mount /data before doing anything else.
- Hardcoded port number — always use
$PORT. Railway assigns the port dynamically. - Secrets in Dockerfile or railway.toml — use the Variables tab. Files in your repo are visible to anyone with repo access.
- Using the free tier for production — Railway's free tier sleeps inactive services after 30 minutes. Any agent that needs to receive webhooks needs a paid plan to stay awake.
- Not setting RAILWAY_RUN_UID — OpenClaw may write files as root on the volume, causing permission errors when Railway restarts under a different UID. Set it to 1000 explicitly.
Frequently Asked Questions
Does Railway support persistent storage for OpenClaw?
Railway Volumes provide persistent storage that survives deploys and restarts. Mount a volume at /data and point OpenClaw's data-dir there. Without a volume, OpenClaw's agent memory and config reset on every deploy — which breaks any stateful agent workflow.
How much does Railway cost for running OpenClaw?
Railway's Hobby plan ($5/month) gives 8 GB RAM and shared CPU — enough for a personal OpenClaw instance. The Pro plan ($20/month) adds dedicated resources and better uptime SLAs. Usage-based billing means you only pay for what you actually run.
Can I use a custom domain with OpenClaw on Railway?
Yes. Railway generates a subdomain automatically, and you can add a custom domain in the service settings. Point a CNAME record at your Railway subdomain, enable HTTPS (it's one click), and update your OpenClaw webhook URLs to use the new domain.
How do I set environment variables for OpenClaw on Railway?
Use the Railway dashboard's Variables tab, or the Railway CLI with railway variables set KEY=value. Variables are injected at runtime. Never commit secrets to your repository or Railway's source configuration.
Does Railway automatically redeploy OpenClaw when I push to GitHub?
Yes, if you connect your GitHub repository. Every push to your configured branch triggers a new build and deploy. You can set a specific branch for production and use preview environments for testing changes before they go live.
What happens to OpenClaw if Railway restarts my service?
If you've mounted a persistent volume for /data, nothing is lost. OpenClaw's state is on the volume. Without a volume, any local-disk state is gone. Railway's restart policy retries failed services automatically with exponential backoff.
Can Railway handle OpenClaw webhooks from external services?
Yes. Every Railway service gets a public HTTPS URL. Point your webhook provider at your Railway URL. Railway handles TLS termination. No reverse proxy or certificate management needed — one of Railway's main advantages over raw VPS hosting.
T. Chen has deployed OpenClaw across Railway, Render, and Fly.io, and benchmarked cold start times and volume I/O performance across all three. The persistent volume mistake documented in this guide comes from a production incident that cost two days of agent conversation history.