Production Deployment
Deploy PiSovereign for production use with TLS, monitoring, and hardened configuration
Overview
PiSovereign is deployed via Docker Compose. The stack includes Traefik for automatic TLS via Let’s Encrypt, Vault for secrets, Ollama for inference, and all supporting services.
Internet
│
▼
┌─────────────┐
│ Traefik │ ← TLS termination, Let's Encrypt
│ (Reverse │
│ Proxy) │
└─────────────┘
│ HTTP (internal)
▼
┌─────────────┐ ┌─────────────┐
│ PiSovereign │ ──▶ │ Ollama │
│ Server │ │ (isolated) │
└─────────────┘ └─────────────┘
│
▼
┌─────────────┐ ┌─────────────┐
│ Prometheus │ ──▶ │ Grafana │
│ Metrics │ │ Dashboard │
└─────────────┘ └─────────────┘
Pre-Deployment Checklist
- Docker Engine 24+ with Compose v2 installed
- Vault initialized and secrets stored (Vault Setup)
- Domain name with DNS A record pointing to your server
- Firewall allows ports 80 and 443 (inbound)
- Backup strategy defined (Backup & Restore)
Deployment
Refer to the Docker Setup guide for the step-by-step deployment process. The key commands are:
cd PiSovereign/docker
cp .env.example .env
nano .env # Set PISOVEREIGN_DOMAIN and TRAEFIK_ACME_EMAIL
docker compose up -d
docker compose exec vault /vault/init.sh
Enable All Profiles
docker compose --profile monitoring --profile caldav up -d
Multi-Architecture Builds
PiSovereign images support both ARM64 (Raspberry Pi) and AMD64 (x86 servers):
docker pull --platform linux/arm64 ghcr.io/twohreichel/pisovereign:latest
docker pull --platform linux/amd64 ghcr.io/twohreichel/pisovereign:latest
TLS Configuration
Traefik with Let’s Encrypt
TLS is handled automatically by Traefik. The Docker Compose stack includes Traefik with HTTP challenge for Let’s Encrypt certificates. Key requirements:
- DNS A record pointing to your server’s public IP
- Ports 80 and 443 open in your firewall
- Valid email for Let’s Encrypt notifications (set in
.envasTRAEFIK_ACME_EMAIL)
Certificate auto-renewal is handled by Traefik — no manual intervention required.
TLS Hardening
For stricter TLS settings, edit docker/traefik/dynamic.yml:
tls:
options:
default:
minVersion: VersionTLS13
cipherSuites:
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
curvePreferences:
- X25519
- CurveP384
sniStrict: true
Production Configuration
Key settings for production in docker/config/config.toml:
environment = "production"
[server]
host = "0.0.0.0"
port = 3000
log_format = "json"
cors_enabled = true
allowed_origins = ["https://your-domain.example.com"]
shutdown_timeout_secs = 30
[inference]
base_url = "http://ollama:11434"
default_model = "gemma3:12b"
timeout_ms = 120000
[security]
rate_limit_enabled = true
rate_limit_rpm = 120
min_tls_version = "1.3"
tls_verify_certs = true
[database]
url = "postgres://pisovereign:pisovereign@postgres:5432/pisovereign"
max_connections = 10
run_migrations = true
[cache]
enabled = true
ttl_short_secs = 300
ttl_medium_secs = 3600
ttl_long_secs = 86400
l1_max_entries = 10000
[vault]
address = "http://vault:8200"
mount_path = "secret"
timeout_secs = 5
[degraded_mode]
enabled = true
unavailable_message = "Service temporarily unavailable. Please try again."
failure_threshold = 3
success_threshold = 2
[health]
global_timeout_secs = 5
See the Configuration Reference for all available options.
Deployment Verification
After deployment, verify everything is working:
# 1. Check all containers are running
docker compose ps
# 2. Check health endpoint
curl https://your-domain.example.com/health
# 3. Check all services are ready
curl https://your-domain.example.com/ready/all | jq
# 4. Test chat endpoint
curl -X POST https://your-domain.example.com/v1/chat \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "Hello"}' | jq
# 5. Check TLS certificate
openssl s_client -connect your-domain.example.com:443 -brief
# 6. Check metrics
curl http://localhost:3000/metrics/prometheus | head -20
Expected results:
- Health returns
{"status": "ok"} - Ready shows all services healthy
- Chat returns an AI response
- TLS shows a valid certificate
Advanced: Non-Docker Deployment
For advanced users who prefer running PiSovereign without Docker, you can build the binary directly:
cargo build --release
# Binaries: target/release/pisovereign-server, target/release/pisovereign-cli
You are responsible for managing Ollama, Vault, Signal-CLI, Whisper, Piper, and reverse proxy setup yourself. The Docker Compose stack in docker/compose.yml serves as the reference architecture.
Next Steps
- Monitoring — Grafana dashboards and alerting
- Backup & Restore — Automated backups
- Security Hardening — Application and network security