---
title: "Deploy OpenClaw (Self-Hosted)"
description: "Self-host OpenClaw with Chromium, persistent memory and API key setup."
category: "AI/ML"
url: https://railway.com/deploy/openclaw-self-hosted
---

# Deploy OpenClaw (Self-Hosted)

Self-host OpenClaw with Chromium, persistent memory and API key setup.

**[Deploy OpenClaw (Self-Hosted) on Railway](https://railway.com/template/openclaw-self-hosted)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/openclaw-self-hosted/manifest.json

- **Creator:** Hosmel Quintana's Projects
- **Category:** AI/ML
- **Total deploys:** 1

## Template content

### OpenClaw https://openclaw.ai/favicon.svg

- **Image:** ghcr.io/openclaw/openclaw:latest-browser
- **Start command:** `/bin/sh -ec 'set -eu; cd /app; mkdir -p "$OPENCLAW_STATE_DIR" "$OPENCLAW_WORKSPACE_DIR"; chown 1000:1000 /data "$OPENCLAW_STATE_DIR" "$OPENCLAW_WORKSPACE_DIR"; if [ ! -s "$OPENCLAW_STATE_DIR/openclaw.json" ]; then choice="$OPENCLAW_AUTH_CHOICE"; if [ "$choice" = auto ]; then set --; [ -z "${ANTHROPIC_API_KEY:-}" ] || set -- "$@" apiKey; [ -z "${GEMINI_API_KEY:-}" ] || set -- "$@" gemini-api-key; [ -z "${OPENAI_API_KEY:-}" ] || set -- "$@" openai-api-key; [ -z "${OPENROUTER_API_KEY:-}" ] || set -- "$@" openrouter-api-key; [ "$#" -le 1 ] || { echo "Set OPENCLAW_AUTH_CHOICE when supplying multiple API keys." >&2; exit 1; }; choice="${1:-skip}"; fi; if [ "$choice" != skip ]; then runuser -u node -- openclaw onboard --non-interactive --accept-risk --auth-choice "$choice" --secret-input-mode ref --gateway-auth token --gateway-token-ref-env OPENCLAW_GATEWAY_TOKEN --gateway-bind lan --gateway-port "$PORT" --workspace "$OPENCLAW_WORKSPACE_DIR" --skip-daemon --skip-channels --skip-health --skip-skills --skip-hooks --skip-search --skip-ui --suppress-gateway-token-output; fi; fi; browser_path=$(node -p "require(\"playwright-core\").chromium.executablePath()"); runuser -u node -- openclaw config set --batch-json "[{\"path\":\"browser.executablePath\",\"value\":\"$browser_path\"},{\"path\":\"browser.noSandbox\",\"value\":$OPENCLAW_BROWSER_NO_SANDBOX},{\"path\":\"gateway.allowRealIpFallback\",\"value\":false},{\"path\":\"gateway.auth.allowTailscale\",\"value\":false},{\"path\":\"gateway.bind\",\"value\":\"lan\"},{\"path\":\"gateway.controlUi.allowedOrigins\",\"value\":$OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS},{\"path\":\"gateway.mode\",\"value\":\"local\"},{\"path\":\"gateway.port\",\"value\":$PORT},{\"path\":\"gateway.trustedProxies\",\"value\":$OPENCLAW_TRUSTED_PROXIES}]"; if [ -n "${OPENCLAW_MODEL:-}" ]; then runuser -u node -- openclaw models set "$OPENCLAW_MODEL"; fi; exec runuser -u node -- node openclaw.mjs gateway --bind lan --port "$PORT" --auth token'`
- **Health check:** /healthz
- **Public domain:** Yes

## Documentation

# Deploy and Host OpenClaw on Railway

OpenClaw is a personal AI assistant with persistent conversations, tools, browser automation, and integrations with messaging channels. This template deploys the official stable image with Chromium and the native OpenClaw Control UI.

## About Hosting OpenClaw

The service uses `ghcr.io/openclaw/openclaw:latest-browser`, a persistent `/data` volume, an HTTPS domain, and a `/healthz` health check. Bootstrap prepares volume permissions, then runs OpenClaw and Chromium as the image’s non-root `node` user. No separate setup application is required.

### Quick start

1. Add **one** optional API key before deploying: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, or `OPENROUTER_API_KEY`. Leave `OPENCLAW_AUTH_CHOICE=auto`; the first start configures that provider and its recommended model. Set `OPENCLAW_MODEL` if you prefer a particular model available to your account.
2. Alternatively, leave the keys blank. Connect a supported provider, subscription OAuth, or custom endpoint later from **Models → Connect provider** in OpenClaw.
3. If you add or change a custom domain, redeploy OpenClaw to apply it before opening the Control UI. For multiple domains, list their full HTTPS origins in `OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS`, then redeploy. Your login, model selection, and data stay on `/data`.
4. Once Railway reports a successful deployment, open the service’s **Console** and run the following **once for your first browser**:

```bash
runuser -u node -- openclaw dashboard --json | node -e 'let s="";process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{const u=new URL(JSON.parse(s).browserUrl);u.protocol="https:";u.hostname=process.env.RAILWAY_PUBLIC_DOMAIN;u.port="";const f=new URLSearchParams(u.hash.slice(1));f.set("gatewayUrl","wss://"+u.host);u.hash=f.toString();console.log(u.href)})'
```

Open the printed HTTPS link within ten minutes. It contains a single-use owner pairing credential; keep it private. This pairs that browser with administrator access without disabling device authentication. After pairing, use the normal service domain for chat, Models, channels, settings, and device approvals. A new browser profile needs its own pairing link or approval from an existing administrator.

API keys added after initial setup can be connected through Models. Existing provider, model, channel, and authentication configuration survives restarts; onboarding never resets an existing configuration.

If you supply several API keys on the first deployment, select `OPENCLAW_AUTH_CHOICE` explicitly: `openai-api-key`, `apiKey` (Anthropic), `gemini-api-key`, or `openrouter-api-key`. Use `skip` to configure through the UI. Each deployer supplies their own credentials. API usage is billed by the provider separately from Railway; subscription OAuth follows the connected account’s access and limits.

## Common Use Cases

- A personal assistant with persistent context and files.
- Research and browser tasks using bundled headless Chromium.
- Connecting supported chat channels and managing them from the native UI.
- Trying supported model providers with your own credentials.

## Dependencies for OpenClaw Hosting

- A Railway account with enough memory and storage for the Gateway and optional browser workloads.
- Your own model-provider credentials or supported subscription login.

### Deployment Dependencies

- [Official OpenClaw source](https://github.com/openclaw/openclaw)
- [Official Docker images](https://docs.openclaw.ai/install/docker)
- [Control UI and browser pairing](https://docs.openclaw.ai/web/control-ui/connect-and-pair)
- [Model providers](https://docs.openclaw.ai/providers)

### Implementation Details

Configuration, credentials, sessions, browser profiles, and memory live in `/data/.openclaw`; agent files live in `/data/workspace`. Configure Railway volume backups before relying on important data. A volume survives a deployment, but deleting it deletes the stored state. Use one replica with this attached volume.

The public listener uses port `8080`. The default UI origin follows `RAILWAY_PUBLIC_DOMAIN` on startup. Redeploy after adding or changing a custom domain; include every full HTTPS origin in `OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS` if using multiple domains.

Gateway token authentication and device pairing remain enabled. OpenClaw listens directly on port `8080`, using its native proxy configuration. No custom HTTP server, WebSocket proxy, or image build is added. The startup command uses the official CLI to prepare first-time provider setup, allowed origins, and browser settings without resetting existing configuration.

The default trusted proxy range is `100.64.0.0/10`, which covered the Railway ingress peers observed during deployment tests. Railway overwrote supplied `X-Forwarded-For`, `X-Real-IP`, and forwarded host/protocol headers in those tests. This range is an observed runtime default, not a published Railway guarantee; revisit it if Railway changes its ingress network. Trusting the ingress does not bypass Gateway token authentication or device pairing.

The startup command obtains the bundled Chromium executable path from Playwright and configures it through the official CLI. Chromium requires `OPENCLAW_BROWSER_NO_SANDBOX=true` in the tested Railway runtime. This disables Chromium’s internal process sandbox; it still runs without root inside the Railway service container. Use this as a trusted personal assistant, and review what access and tools you grant it.

New installations resolve the official stable browser image. Existing services require an image update deployment to receive a newer image; restarting the same deployment does not upgrade it. Back up the volume before upgrading. Validation used OpenClaw **2026.9.6**, including a real OpenAI reply, public UI access, Chromium, and persistent state.

### Variables

All template variables include descriptions in Railway. The reference below is alphabetical; Railway controls the order displayed in its editor.

| Variable | Default | Purpose |
|---|---|---|
| `ANTHROPIC_API_KEY` | `Optional / blank` | Optional Anthropic API key. On a fresh deployment, supply one provider key to configure its recommended model automatically. Leave blank to connect a provider from OpenClaw’s Models screen. Provider usage is billed separately. |
| `GEMINI_API_KEY` | `Optional / blank` | Optional Google Gemini API key. On a fresh deployment, supply one provider key to configure its recommended model automatically. Leave blank to use the Models screen. Provider usage is billed separately. |
| `OPENAI_API_KEY` | `Optional / blank` | Optional OpenAI Platform API key for metered API usage. A single supplied key configures a fresh deployment automatically. Leave blank to connect OpenAI with OAuth or another provider from Models. ChatGPT subscriptions and API billing are separate. |
| `OPENCLAW_AUTH_CHOICE` | `auto` | First-deployment provider setup: auto detects a single supplied API key. If supplying multiple keys, select openai-api-key, apiKey (Anthropic), gemini-api-key or openrouter-api-key. Use skip for setup in the Models screen. Existing configuration is preserved. |
| `OPENCLAW_BROWSER_HEADLESS` | `1` | Run the bundled Chromium browser without a graphical display. |
| `OPENCLAW_BROWSER_NO_SANDBOX` | `true` | Disable Chromium’s internal sandbox, required by the tested Railway runtime. Chromium still runs as the non-root node user inside the service container. Set false only on infrastructure that supports Chromium sandboxing. |
| `OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS` | `["https://${{RAILWAY_PUBLIC_DOMAIN}}"]` | HTTPS origins allowed to open the Control UI. The default follows Railway's public domain on startup. Redeploy after adding or changing a custom domain. For multiple domains, include each full HTTPS origin in this JSON array before redeploying. |
| `OPENCLAW_GATEWAY_PORT` | `${{PORT}}` | Gateway HTTP and WebSocket port. Keep this reference equal to PORT; OpenClaw serves Railway traffic directly. |
| `OPENCLAW_GATEWAY_TOKEN` | `Generated per service` | Unique generated administrator token for the Gateway and Control UI. Copy it from your deployed service variables when connecting; keep it private. |
| `OPENCLAW_MODEL` | `Optional / blank` | Optional provider/model identifier to apply at startup, such as openai/gpt-6-astra. Leave blank to keep the onboarding recommendation or your model chosen in the UI. Account model access can vary. |
| `OPENCLAW_STATE_DIR` | `/data/.openclaw` | Persistent directory for configuration, credentials, sessions, agent state, and memory. Keep it inside the /data volume. |
| `OPENCLAW_TRUSTED_PROXIES` | `["100.64.0.0/10"]` | Trusted Railway ingress range observed in deployment tests. Railway overwrote client forwarding headers in those tests. Review this range if its ingress network changes. Gateway token authentication and device pairing remain enabled. |
| `OPENCLAW_WORKSPACE_DIR` | `/data/workspace` | Persistent workspace for agent files and artifacts. Keep it inside the /data volume. |
| `OPENROUTER_API_KEY` | `Optional / blank` | Optional OpenRouter API key. A single supplied key configures a fresh deployment automatically. Set OPENCLAW_MODEL to your preferred OpenRouter model if desired, or leave blank for the provider recommendation. Provider usage is billed separately. |
| `PORT` | `8080` | Public HTTP and WebSocket listener port used by Railway. The generated domain targets this port. |
| `RAILWAY_RUN_UID` | `0` | Start the bootstrap as root so it can prepare volume permissions. The startup command then runs OpenClaw as the image's non-root node user. |

## Why Deploy OpenClaw on Railway?

Railway provides the HTTPS endpoint, persistent volume, deployment health checks, logs, and service console in one project. This template keeps the OpenClaw runtime official and makes first-time provider setup optional and automatic when one API key is supplied.


## Similar templates

- [Chat Chat](https://railway.com/deploy/-WWW5r) — Chat Chat, your own unified chat and search to AI platform.
- [stella](https://railway.com/deploy/stella) — Self-host stella with web, API, Postgres, Redis, and object storage.
- [Hermes Agent | OpenClaw Alternative with Dashboard](https://railway.com/deploy/hermes-agent-or-openclaw-alternative-wit) — Self-Hosted Hermes AI Agent for Telegram, Discord & Slack

Open this page in a browser: https://railway.com/deploy/openclaw-self-hosted
