Skip to content

Commit 419e114

Browse files
authored
Merge pull request #7 from clawdbot/feature/railway
Add Railway deployment guide
2 parents d977997 + f65c48b commit 419e114

File tree

1 file changed

+230
-0
lines changed

1 file changed

+230
-0
lines changed

src/pages/railway.astro

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
---
2+
import Layout from '../layouts/Layout.astro';
3+
4+
const DEPLOY_URL = 'https://railway.com/deploy/clawdbot-railway-template';
5+
---
6+
7+
<Layout
8+
title="Deploy Clawdbot on Railway"
9+
description="One-click deploy Clawdbot on Railway with a browser-based setup wizard."
10+
>
11+
<div class="stars"></div>
12+
<div class="nebula"></div>
13+
14+
<main class="container">
15+
<header class="page-hero">
16+
<h1>Deploy Clawdbot on Railway</h1>
17+
<p class="subtitle">
18+
Run your own Clawdbot on a cheap VPS-like platform with a persistent volume, a friendly
19+
<code>/setup</code> wizard, and chat integrations (Telegram, Discord, Slack).
20+
</p>
21+
22+
<div class="cta-row">
23+
<a class="btn primary" href={DEPLOY_URL} target="_blank" rel="noreferrer">Deploy on Railway</a>
24+
<a class="btn" href="https://docs.railway.com/guides/public-networking" target="_blank" rel="noreferrer">
25+
Railway networking docs
26+
</a>
27+
</div>
28+
29+
<p class="muted">After deploy, open <code>https://&lt;your-domain&gt;/setup</code> to finish onboarding.</p>
30+
</header>
31+
32+
<section class="grid">
33+
<div class="card">
34+
<h2>What this template does</h2>
35+
<ul>
36+
<li>Deploys a Clawdbot Gateway + Control UI behind Railway HTTP Proxy</li>
37+
<li>Provides a password-protected setup wizard at <code>/setup</code> (no terminal commands)</li>
38+
<li>Mounts a Railway Volume at <code>/data</code> for persistence (config, credentials, sessions, workspace)</li>
39+
<li>Lets you export a backup to migrate off Railway later</li>
40+
</ul>
41+
</div>
42+
43+
<div class="card">
44+
<h2>Required setup on Railway</h2>
45+
<ol>
46+
<li><strong>Public Networking</strong>: enable <strong>HTTP Proxy</strong> (port <code>8080</code>).</li>
47+
<li><strong>Volume</strong>: attach a volume mounted at <code>/data</code>.</li>
48+
<li><strong>Variables</strong>:
49+
<ul>
50+
<li><code>SETUP_PASSWORD</code> (required)</li>
51+
<li><code>CLAWDBOT_STATE_DIR=/data/.clawdbot</code> (recommended)</li>
52+
<li><code>CLAWDBOT_WORKSPACE_DIR=/data/workspace</code> (recommended)</li>
53+
<li><code>CLAWDBOT_GATEWAY_TOKEN</code> (recommended; treat as an admin secret)</li>
54+
</ul>
55+
</li>
56+
</ol>
57+
</div>
58+
59+
<div class="card">
60+
<h2>Chat tokens (so you don’t scramble)</h2>
61+
62+
<h3>Telegram bot token</h3>
63+
<ol>
64+
<li>Open Telegram and message <code>@BotFather</code></li>
65+
<li>Run <code>/newbot</code> and follow the prompts</li>
66+
<li>Copy the token (looks like <code>123456789:AA...</code>)</li>
67+
<li>Paste it into <code>/setup</code></li>
68+
</ol>
69+
70+
<h3>Discord bot token</h3>
71+
<ol>
72+
<li>Open the Discord Developer Portal: <a href="https://discord.com/developers/applications" target="_blank" rel="noreferrer">discord.com/developers/applications</a></li>
73+
<li>Create a <strong>New Application</strong></li>
74+
<li>Open the <strong>Bot</strong> tab → <strong>Add Bot</strong></li>
75+
<li>Copy the <strong>Bot Token</strong> and paste it into <code>/setup</code></li>
76+
<li>Invite the bot to your server (OAuth2 URL Generator; scopes: <code>bot</code>, <code>applications.commands</code>)</li>
77+
</ol>
78+
79+
<p class="muted">
80+
Tip: if DMs are set to <code>pairing</code>, you’ll see a pairing code in chat and approve it in <code>/setup</code>.
81+
</p>
82+
</div>
83+
84+
<div class="card">
85+
<h2>After deployment</h2>
86+
<ul>
87+
<li>Control UI: <code>/clawdbot</code></li>
88+
<li>Setup wizard: <code>/setup</code></li>
89+
<li>Backup export: <code>/setup/export</code> (downloads a <code>.tar.gz</code> of state + workspace)</li>
90+
</ul>
91+
<p class="muted">
92+
Railway deploys are immutable; your state persists because it lives on the volume.
93+
</p>
94+
</div>
95+
</section>
96+
</main>
97+
98+
<style>
99+
.container {
100+
width: min(1100px, 92vw);
101+
margin: 0 auto;
102+
padding: 5rem 0 6rem;
103+
position: relative;
104+
z-index: 2;
105+
}
106+
107+
.page-hero h1 {
108+
font-family: var(--font-display);
109+
font-size: clamp(2.1rem, 4vw, 3.2rem);
110+
letter-spacing: -0.02em;
111+
margin-bottom: 0.75rem;
112+
}
113+
114+
.subtitle {
115+
color: var(--text-secondary);
116+
max-width: 70ch;
117+
margin-bottom: 1.25rem;
118+
font-size: 1.05rem;
119+
}
120+
121+
code {
122+
font-family: var(--font-mono);
123+
font-size: 0.95em;
124+
background: rgba(255, 255, 255, 0.06);
125+
border: 1px solid var(--border-subtle);
126+
padding: 0.1rem 0.35rem;
127+
border-radius: 0.5rem;
128+
}
129+
130+
.muted {
131+
color: var(--text-muted);
132+
margin-top: 0.75rem;
133+
}
134+
135+
.cta-row {
136+
display: flex;
137+
gap: 0.75rem;
138+
flex-wrap: wrap;
139+
margin: 1.25rem 0 0.5rem;
140+
}
141+
142+
.btn {
143+
display: inline-flex;
144+
align-items: center;
145+
justify-content: center;
146+
gap: 0.5rem;
147+
padding: 0.8rem 1.1rem;
148+
border-radius: 0.9rem;
149+
border: 1px solid var(--border-subtle);
150+
background: rgba(255, 255, 255, 0.05);
151+
color: var(--text-primary);
152+
text-decoration: none;
153+
font-weight: 700;
154+
transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease;
155+
}
156+
157+
.btn:hover {
158+
transform: translateY(-1px);
159+
border-color: rgba(255, 77, 77, 0.35);
160+
background: rgba(255, 255, 255, 0.07);
161+
}
162+
163+
.btn.primary {
164+
border-color: rgba(0, 229, 204, 0.35);
165+
background: linear-gradient(135deg, rgba(0, 229, 204, 0.22), rgba(255, 77, 77, 0.16));
166+
}
167+
168+
.grid {
169+
margin-top: 2.25rem;
170+
display: grid;
171+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
172+
gap: 1rem;
173+
}
174+
175+
.card {
176+
background: rgba(17, 24, 39, 0.55);
177+
border: 1px solid var(--border-subtle);
178+
border-radius: 1.25rem;
179+
padding: 1.25rem;
180+
backdrop-filter: blur(8px);
181+
}
182+
183+
.card h2 {
184+
font-family: var(--font-display);
185+
font-size: 1.35rem;
186+
margin-bottom: 0.75rem;
187+
}
188+
189+
.card h3 {
190+
font-family: var(--font-display);
191+
font-size: 1.05rem;
192+
margin: 1rem 0 0.5rem;
193+
color: var(--text-primary);
194+
}
195+
196+
.card ul, .card ol {
197+
margin-left: 1.25rem;
198+
color: var(--text-secondary);
199+
}
200+
201+
.card li { margin: 0.35rem 0; }
202+
203+
/* subtle background borrowed from home page */
204+
.stars {
205+
position: fixed;
206+
inset: 0;
207+
background-image:
208+
radial-gradient(2px 2px at 20px 30px, rgba(255,255,255,0.25), transparent),
209+
radial-gradient(1px 1px at 200px 150px, rgba(255,255,255,0.18), transparent),
210+
radial-gradient(1px 1px at 300px 250px, rgba(255,255,255,0.14), transparent),
211+
radial-gradient(2px 2px at 400px 100px, rgba(255,255,255,0.22), transparent);
212+
background-size: 500px 500px;
213+
opacity: 0.55;
214+
pointer-events: none;
215+
z-index: 0;
216+
}
217+
218+
.nebula {
219+
position: fixed;
220+
inset: 0;
221+
background:
222+
radial-gradient(circle at 20% 20%, rgba(0, 229, 204, 0.12), transparent 45%),
223+
radial-gradient(circle at 80% 30%, rgba(255, 77, 77, 0.10), transparent 50%),
224+
radial-gradient(circle at 50% 80%, rgba(20, 184, 166, 0.08), transparent 55%);
225+
pointer-events: none;
226+
z-index: 1;
227+
mix-blend-mode: screen;
228+
}
229+
</style>
230+
</Layout>

0 commit comments

Comments
 (0)