Deployment Guide
This guide covers deployment strategies, production configurations, and operational best practices.
Table of Contents
- Pre-Deployment Checklist
- Production Deployment Options
- Systemd Service
- Docker Deployment
- Kubernetes
- Related Documentation
Pre-Deployment Checklist
Security
- ✅ API keys stored in environment variables (not hardcoded)
- ✅ Use IP whitelisting on Binance
- ✅ Enable withdrawal whitelist
- ✅ Use sub-account for trading
- ✅ Rotate API keys regularly
See: Security Guide for detailed credential management
Testing
- ✅ Test on testnet first
- ✅ Verify order placement/cancellation
- ✅ Test with small position sizes
- ✅ Monitor for 24 hours before scaling
See: Getting Started for testing procedures
Monitoring
- ✅ Set up log aggregation (Loki/Elasticsearch)
- ✅ Configure alerts for errors
- ✅ Monitor API response times
- ✅ Track position P&L
- ✅ Set up Grafana MCP for AI-powered monitoring
See: Monitoring Guide for comprehensive observability setup
Infrastructure
- ✅ Run on reliable server (not laptop)
- ✅ Use systemd for process management
- ✅ Configure automatic restarts
- ✅ Set up backup strategies
Production Deployment Options
Choose the deployment method that best fits your infrastructure:
graph LR
A[Deployment Options] --> B[Systemd Service]
A --> C[Docker Container]
A --> D[Kubernetes Pod]
B --> B1[Single Server<br/>Minimal Complexity<br/>systemctl management]
C --> C1[Docker Compose<br/>Local/Cloud<br/>With monitoring stack]
D --> D1[High Availability<br/>Auto-scaling<br/>Production scale]
style B fill:#90caf9
style C fill:#a5d6a7
style D fill:#ce93d8
Systemd Service (Recommended for Single Server)
Best for single-server deployments with minimal complexity.
Service Configuration
Create /etc/systemd/system/wealth.service:
[Unit]
Description=Wealth Trading Bot
After=network.target
[Service]
Type=simple
User=trader
WorkingDirectory=/home/trader
Environment="CREDENTIALS_PASSPHRASE=your-secure-passphrase"
Environment="WEALTH__EXECUTION__MODE=live"
Environment="WEALTH__LICENSING__LICENSE_KEY=your-license-key"
ExecStart=/usr/local/bin/wealth run
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and Start
# Reload systemd configuration
sudo systemctl daemon-reload
# Enable service to start on boot
sudo systemctl enable wealth
# Start the service
sudo systemctl start wealth
# Check service status
sudo systemctl status wealth
# View logs
sudo journalctl -u wealth -f
Management Commands
# Stop the service
sudo systemctl stop wealth
# Restart the service
sudo systemctl restart wealth
# Check service health
sudo systemctl is-active wealth
# View recent logs
sudo journalctl -u wealth -n 100
Docker Deployment
Best for containerized environments and cloud deployments.
Using Pre-built Image (Recommended)
# Pull the latest image
docker pull ghcr.io/thiras/wealth:latest
# Run with encrypted credentials
docker run -d --name wealth \
-v $(pwd)/config.toml:/app/config.toml \
-v $(pwd)/credentials.encrypted.json:/app/credentials.encrypted.json \
-e CREDENTIALS_PASSPHRASE=your-passphrase \
-e WEALTH__EXECUTION__MODE=live \
-e WEALTH__LICENSING__LICENSE_KEY=your-license-key \
ghcr.io/thiras/wealth:latest
Docker Compose (Recommended)
See compose.yml in the project root for a complete setup including OpenTelemetry Collector and Grafana.
# Download compose file
curl -LO https://raw.githubusercontent.com/thiras/wealth/main/compose.yml
# Start all services
docker compose up -d
# View logs
docker compose logs -f wealth
# Stop all services
docker compose down
Building Custom Image
Kubernetes (Advanced)
Best for production-scale deployments requiring high availability and orchestration.
Using the Helm Chart (Recommended)
The official Helm chart provides a complete Kubernetes deployment with security best practices:
# Login to GitHub Container Registry
helm registry login ghcr.io -u YOUR_GITHUB_USERNAME
# Install the chart
helm install wealth oci://ghcr.io/thiras/charts/wealth \
--version 0.52.3 \
--namespace wealth \
--create-namespace \
--set credentials.existingSecret=wealth-secrets \
--set wealth.executionMode=live
# Verify the installation
helm list -n wealth
kubectl get pods -n wealth
Create secrets first:
# Create namespace
kubectl create namespace wealth
# Create secrets for credentials
kubectl create secret generic wealth-secrets \
--namespace wealth \
--from-literal=CREDENTIALS_PASSPHRASE=your-passphrase \
--from-literal=BINANCE_API_KEY=xxx \
--from-literal=BINANCE_SECRET_KEY=yyy
Verify chart signature (recommended):
# Verify with Cosign
cosign verify oci://ghcr.io/thiras/charts/wealth:0.52.3 \
--certificate-identity-regexp="https://github.com/thiras/wealth/.github/workflows/helm-release.yml@.*" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
For chart configuration options, see:
helm show values oci://ghcr.io/thiras/charts/wealth --version 0.52.3
tmux Session (Optional)
For terminal-based access with detach support, enable tmux. The dashboard runs inside a tmux session, allowing you to detach (Ctrl+B D) and reattach without stopping the bot.
wealth:
command: dashboard # Required for tmux mode
tmux:
enabled: true
sessionName: wealth # Custom session name (optional)
Access the dashboard:
# Attach to the pod (connects to tmux session)
kubectl attach -it <pod-name>
# To detach: Press Ctrl+B, then D
# The bot continues running in the background
# To reattach later:
kubectl attach -it <pod-name>
Note: tmux and ttyd are mutually exclusive. If both are enabled, ttyd takes precedence.
ttyd Web Terminal (Optional)
The Helm chart supports browser-based access to the TUI dashboard via ttyd. When enabled, ttyd runs as the main process and spawns the wealth dashboard, allowing you to view and interact with the TUI from your browser. This provides proper detach support - just close the browser tab and the bot continues running.
# Enable ttyd web terminal for dashboard access
ttyd:
enabled: true
port: 7681
# Optional: Enable basic authentication (recommended for production)
auth:
enabled: true
username: "admin"
password: "secure-password" # Use --set or external secrets, not in VCS
# Optional: Expose via ingress (path added to all configured hosts)
ingress:
enabled: true
path: /terminal
pathType: Prefix
Access the dashboard:
# Port forward to the pod
kubectl port-forward pod/<pod-name> 7681:7681
# Open in browser
open http://localhost:7681
You can also access via ingress if configured: https://wealth.example.com/terminal
Security Note: ttyd provides full terminal access to the dashboard. Use authentication and network policies in production.
OpenTelemetry Collector Sidecar
The Helm chart includes an OTEL Collector sidecar for metrics, logs, and traces. With the Prometheus exporter enabled (default), metrics can be scraped by in-cluster Prometheus:
otelCollector:
enabled: true
# Prometheus exporter for ServiceMonitor scraping (default: enabled)
prometheus:
enabled: true # Exposes :8889/metrics for Prometheus
port: 8889
# In-cluster endpoints (no auth required)
lokiEndpoint: "http://loki-gateway.meta.svc.cluster.local:3100"
tempoEndpoint: "tempo.meta.svc.cluster.local:4317"
# OR Grafana Cloud (with auth)
grafanaCloud:
username: "123456"
apiToken: "glc_xxx..."
prometheusEndpoint: "https://prometheus-xxx.grafana.net/api/prom/push"
lokiEndpoint: "https://logs-xxx.grafana.net"
tempoEndpoint: "https://tempo-xxx.grafana.net:443"
Metrics flow:
App → OTLP → OTEL Collector → Prometheus Exporter (:8889) → ServiceMonitor scrape
Note: The app's
/metricsendpoint returns JSON config info, not Prometheus format. EnableotelCollector.prometheus.enabled=truefor Prometheus-compatible metrics.
See Monitoring Guide for details on the metrics architecture.
Manual Deployment (Without Helm)
For environments where Helm is not available:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wealth-trading-bot
spec:
replicas: 1
selector:
matchLabels:
app: wealth
template:
metadata:
labels:
app: wealth
spec:
containers:
- name: wealth
image: wealth:latest
env:
- name: CREDENTIALS_PASSPHRASE
valueFrom:
secretKeyRef:
name: wealth-secrets
key: credentials-passphrase
- name: WEALTH__LICENSING__LICENSE_KEY
valueFrom:
secretKeyRef:
name: wealth-secrets
key: license-key
- name: WEALTH__EXECUTION__MODE
value: "live"
volumeMounts:
- name: credentials
mountPath: /app/credentials.encrypted.json
subPath: credentials.encrypted.json
readOnly: true
- name: credentials
mountPath: /app/.credentials.salt
subPath: .credentials.salt
readOnly: true
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Secrets Management
# Create secret for API credentials
kubectl create secret generic exchange-credentials \
--from-literal=binance-api-key=xxx \
--from-literal=binance-secret-key=yyy
# Apply deployment
kubectl apply -f deployment.yaml
# Check pod status
kubectl get pods -l app=wealth
# View logs
kubectl logs -l app=wealth -f
Deployment Best Practices
1. Environment Separation
Maintain separate configurations for different environments:
# Development
export WEALTH__EXECUTION__MODE=paper
# Configure testnet in config.toml or use encrypted credentials with testnet keys
# Staging
export WEALTH__EXECUTION__MODE=paper
# Use production API endpoints with paper mode for testing
# Production
export WEALTH__EXECUTION__MODE=live
export WEALTH__LICENSING__LICENSE_KEY=your-license-key
# Use encrypted credentials with production API keys
2. Graceful Shutdown
The bot implements graceful shutdown (6-8 seconds typical):
What happens:
- Stop accepting - No new trades initiated
- Close positions - All active positions closed safely
- Cleanup - Statistics printed, connections closed
Trigger Options:
# Interactive mode
Ctrl+C
# Send graceful shutdown signal
kill -SIGTERM $(pidof wealth)
# Docker/Kubernetes (automatic on stop)
docker stop wealth # Sends SIGTERM, waits 10s, then SIGKILL
Monitoring Shutdown:
- Watch logs for "Shutdown signal received" messages
- Verify "All positions closed successfully" message
- Check final statistics in logs before exit
Configuration:
# Docker Compose
services:
wealth:
stop_grace_period: 10s
# Kubernetes
terminationGracePeriodSeconds: 10
3. Health Checks
Use the health endpoint for container orchestration:
# Check bot health
curl http://localhost:9090/health
# Kubernetes liveness probe
livenessProbe:
httpGet:
path: /health
port: 9090
initialDelaySeconds: 30
periodSeconds: 10
4. Log Rotation
Configure log rotation to prevent disk space issues:
# systemd journal rotation
sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=500M
5. Backup Strategies
- Backup configuration files regularly
- Document API key rotation procedures
Related Documentation
- Configuration Guide - Environment variables and settings
- Security Guide - Credential management and best practices
- Monitoring Guide - Observability and alerting
- Troubleshooting - Common deployment issues
- Getting Started - Initial setup and testing
Next Steps
After deployment:
- Monitor logs for the first 24 hours
- Verify metrics are being collected
- Test graceful shutdown and automatic restart
- Set up alerting for critical errors
- Document your deployment-specific configurations
For ongoing operations, see the Monitoring Guide.