Getting Started
Self-Hosting Guide
Run TradeClaw in production on your own server with Docker, nginx, SSL certificates, and proper monitoring. This guide covers a production-grade deployment from scratch.
Architecture Overview
A production TradeClaw deployment consists of:
Web App
Next.js standalone server on port 3000
Reverse Proxy
nginx handling TLS termination and compression
Data Store
File-based JSON in /data directory (no external DB required)
SSE Stream
Server-Sent Events for live price feed on /api/prices/stream
Server Requirements
Docker Production Setup
The recommended approach. Uses the multi-stage Dockerfile with a minimal production image.
1. Clone and configure
git clone https://github.com/naimkatiman/tradeclaw.git
cd tradeclaw
cp .env.example .env2. Edit environment variables
# Required
NODE_ENV=production
NEXT_PUBLIC_APP_URL=https://your-domain.com
# Optional — enable features
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_WEBHOOK_URL=https://your-domain.com/api/telegram/webhook
# Alpha Screener (SaaS upsell, optional)
NEXT_PUBLIC_ALPHA_SCREENER_URL=https://alpha-screener.com
ALPHA_SCREENER_API_KEY=your_key3. Build and run
docker compose up -d --build
# Verify health
curl http://localhost:3000/api/healthNginx Reverse Proxy
Place nginx in front of TradeClaw for TLS termination, compression, and caching.
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Gzip compression
gzip on;
gzip_types text/plain application/json application/javascript text/css;
gzip_min_length 1000;
# SSE support — disable buffering for stream endpoints
location /api/prices/stream {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400s;
}
# All other requests
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Cache static assets
location /_next/static/ {
proxy_pass http://127.0.0.1:3000;
expires 365d;
add_header Cache-Control "public, immutable";
}
}
}SSL with Let's Encrypt
# Install certbot
sudo apt install certbot python3-certbot-nginx
# Get certificate
sudo certbot --nginx -d your-domain.com
# Auto-renewal (certbot adds a systemd timer automatically)
sudo certbot renew --dry-runHealth Monitoring
TradeClaw exposes a /api/health endpoint that returns uptime, version, and build status. Use it for uptime checks.
{
"status": "ok",
"version": "0.5.0",
"uptime": 86400,
"node": "v22.0.0",
"build": "standalone",
"timestamp": "2026-03-27T10:00:00.000Z"
}Pair with services like UptimeRobot, Better Uptime, or a simple cron curl:
# crontab -e
*/5 * * * * curl -sf https://your-domain.com/api/health || echo "TradeClaw down" | mail -s "Alert" [email protected]Updating TradeClaw
cd tradeclaw
git pull origin main
docker compose down
docker compose up -d --build
# Verify
curl http://localhost:3000/api/healthData persistence: Signal history, paper trading positions, and plugin configurations are stored in data/. This directory is volume-mounted in Docker and survives rebuilds.
Running Without Docker
# Install dependencies
pnpm install
# Build production
pnpm build
# Start (uses Next.js standalone output)
cd apps/web
node .next/standalone/apps/web/server.jsUse a process manager like PM2 or systemd to keep the process alive:
[Unit]
Description=TradeClaw Trading Platform
After=network.target
[Service]
Type=simple
User=tradeclaw
WorkingDirectory=/opt/tradeclaw/apps/web
ExecStart=/usr/bin/node .next/standalone/apps/web/server.js
Restart=on-failure
RestartSec=10
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.target