Railway deploy guide — P0.E5
Railway deploy guide — P0.E5
Step-by-step deploy XTalk server lên Railway staging. ~30 phút setup lần đầu.
Cost estimate
- Railway: $5 free credit/tháng (đủ test 1 service + Postgres + Redis ~500h/tháng) → sau hết: $5-15/tháng
- Sentry: free tier 5k events/tháng
- OpenRouter: pay-per-use (~$0.001/intent với Haiku)
- Domain xtalk.app (optional): $15/năm
Tổng: $0/tháng đầu, scale lên $20-30 khi vượt free tier.
Bước 1 — Tạo Railway account + CLI (5 phút)
- Đăng ký https://railway.app — sign in qua GitHub (recommend, dễ link repo)
- Cài CLI:
brew install railway # Mac # hoặc: npm i -g @railway/cli - Login:
railway loginBrowser sẽ mở → authorize.
Bước 2 — Tạo project + services (5 phút)
cd /Users/xuyenngo/Projects/AICode/XTalk
railway init
# → Choose "Empty Project", đặt tên "xtalk-staging"
Sau đó add 2 services qua web UI hoặc CLI:
Web UI (dễ hơn):
- Mở project trên railway.app dashboard
- Click “+ New” → “Database” → “PostgreSQL” → tự deploy
- Click “+ New” → “Database” → “Redis” → tự deploy
- Click “+ New” → “Empty Service” → đặt tên “api”
- Vào service “api” → Settings → Source → Connect repo
xuyenthanhngo/XTalk→ branchmain - Settings → Root Directory =
/(monorepo root — nixpacks tự detect)
Bước 3 — Set environment variables (5 phút)
Vào service api → tab Variables → add các biến:
# Database — Railway tự gen khi link Postgres service.
# Click "Add Reference" → chọn Postgres service → DATABASE_URL
DATABASE_URL=$
REDIS_URL=$
# Required secrets (anh tự gen — DÙNG 3 chuỗi KHÁC NHAU):
# openssl rand -base64 48 ← chạy 3 lần
JWT_SECRET=<chuỗi 1 — ≥ 32 ký tự>
JWT_REFRESH_SECRET=<chuỗi 2 — ≥ 32 ký tự>
DEVICE_SECRET_KMS_KEY=<chuỗi 3 — 32 byte base64>
# LLM (em đã có key)
OPENROUTER_API_KEY=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
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
LLM_MODEL_DEFAULT=anthropic/claude-haiku-4-5
LLM_MODEL_FALLBACK=anthropic/claude-sonnet-4-6
# Server
PORT=3000
NODE_ENV=production
# Optional — Sentry (em hướng dẫn dưới)
# SENTRY_DSN=
Tip: dùng railway variables set KEY=value từ CLI cũng được.
Bước 4 — Deploy lần đầu (~3 phút)
Railway sẽ tự deploy khi anh connect repo + push commit. Lần đầu sẽ:
- Detect
nixpacks.tomlở root - Run
pnpm install --frozen-lockfile - Build shared + server
- Start: migrate DB →
pnpm --filter @xtalk/server start
Theo dõi log: Service api → tab Deployments → click latest → View Logs.
Expected output cuối:
INFO Running migrations...
INFO Migrations completed.
INFO XTalk server v0.1.0 listening on :3000
Bước 5 — Tạo public domain (1 phút)
Service api → Settings → Networking → “Generate Domain” → Railway sinh URL kiểu xtalk-api-production.up.railway.app.
Test:
curl https://xtalk-api-production.up.railway.app/health
# {"status":"ok","timestamp":"2026-05-14T..."}
Bước 6 — Setup Sentry (10 phút, optional)
- Đăng ký https://sentry.io (free tier)
- Create project: platform = Node.js, name =
xtalk-server - Copy DSN từ Settings → Client Keys:
https://abc@xyz.ingest.sentry.io/123 - Railway → api service → Variables → add
SENTRY_DSN=...→ redeploy. - Test: vào
/auth/guestvới body sai → trigger 400 → check Sentry dashboard.
Cho Flutter client:
- Sentry → Create project, platform = Flutter, name =
xtalk-app - Copy DSN → build app với:
flutter run --dart-define=SENTRY_DSN=https://...@xyz.ingest.sentry.io/456
Bước 7 — Update Flutter client API_BASE
Build APK/AAB với production URL:
cd app
flutter build appbundle --release \
--dart-define=API_BASE=https://xtalk-api-production.up.railway.app \
--dart-define=SENTRY_DSN=https://...@sentry.io/456
AAB này upload lên Play Console internal track thay cho file Cloudflare tunnel.
Bước 8 — GitHub Actions auto-deploy (optional, 5 phút)
Railway tự deploy khi push lên branch đã connect (main). Nếu muốn manual control:
- Railway → Project Settings → Tokens → Create Token → copy
- Repo GitHub → Settings → Secrets → add
RAILWAY_TOKEN - Em đã có CI workflow ở
.github/workflows/ci.yml. Adddeployjob:deploy: needs: ci-pass if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm i -g @railway/cli - run: railway up --service api env: RAILWAY_TOKEN: $
Verify everything end-to-end
- Đóng Cloudflare tunnel (Mac terminal): Ctrl+C
- Mở app trên simulator/phone với API_BASE = Railway URL
- Chat tab → gõ “bật to lên” → server (Railway) → LLM → response
- Check Railway logs cho
POST /v1/intentlog entries - Check Sentry nếu có lỗi nào trigger
Rollback
Railway giữ 5 deployments cuối → vào Deployments → click old → Redeploy.
Cost monitoring
Railway → Project → Usage tab xem dollars/giờ.
Nếu vượt $5 free credit → setup billing limit ở Account → Billing → Usage Limits.
TLDR cho anh:
brew install railway && railway loginrailway init→ tạo project- Web UI: add Postgres + Redis + Empty service “api”
- Connect repo branch main + set env vars (em đã liệt kê ở trên)
- Đợi 3 phút → /health ok
- Gen public domain → update API_BASE Flutter build
- (Optional) Sentry account → DSN → redeploy
Stuck ở step nào báo em.