Docker Setup
Production deployment guide using Docker Compose
PiSovereign runs as a set of Docker containers orchestrated by Docker Compose. This is the recommended and only supported deployment method.
Prerequisites
- Docker Engine 24+ and Docker Compose v2
- 4 GB+ RAM (8 GB recommended)
- 20 GB+ free disk space
Install Docker if not already installed:
# Raspberry Pi / Debian / Ubuntu
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
# Log out and back in
# macOS
brew install --cask docker
Quick Start
# 1. Clone the repository
git clone https://github.com/twohreichel/PiSovereign.git
cd PiSovereign/docker
# 2. Configure environment
cp .env.example .env
# Edit .env with your domain and email for TLS certificates
nano .env
# 3. Start core services
docker compose up -d
# 4. Initialize Vault (first time only)
docker compose exec vault /vault/init.sh
# Save the unseal key and root token printed to stdout!
# 5. Wait for Ollama model download
docker compose logs -f ollama-init
PiSovereign is now running at https://your-domain.example.com.
Architecture
The deployment consists of these core services:
| Service | Purpose | Port | URL |
|---|---|---|---|
| pisovereign | Main application server | 3000 (internal) | http://localhost/ via Traefik |
| traefik | Reverse proxy + TLS | 80, 443 | http://localhost:80 |
| vault | Secret management | 8200 (internal) | Internal only |
| ollama | LLM inference engine | 11434 (internal) | Internal only |
| signal-cli | Signal messenger daemon | Unix socket | Internal only |
| whisper | Speech-to-text (STT) | 8081 (internal) | Internal only |
| piper | Text-to-speech (TTS) | 8082 (internal) | Internal only |
Monitoring Stack (profile: monitoring)
| Service | Purpose | Port | URL |
|---|---|---|---|
| prometheus | Metrics collection & alerting | 9090 | http://localhost:9090 |
| grafana | Dashboards & visualization | 3000 (internal) | http://localhost/grafana via Traefik |
| loki | Log aggregation | 3100 (internal) | Internal only |
| promtail | Log shipping agent | — | Internal only |
| node-exporter | Host metrics exporter | 9100 (internal) | Internal only |
| otel-collector | OpenTelemetry Collector | 4317/4318 (internal) | Internal only |
CalDAV Server (profile: caldav)
| Service | Purpose | Port | URL |
|---|---|---|---|
| baikal | CalDAV/CardDAV server | 80 (internal) | http://localhost/caldav via Traefik |
Key Endpoints
| Endpoint | Description |
|---|---|
http://localhost/health | Application health check |
http://localhost/metrics/prometheus | Prometheus metrics scrape target |
http://localhost/grafana | Grafana dashboards (monitoring profile) |
http://localhost/caldav | Baïkal CalDAV web UI (caldav profile) |
http://localhost:9090 | Prometheus web UI (monitoring profile) |
http://localhost:9090/targets | Prometheus scrape target status |
Configuration
Environment Variables
Edit docker/.env before starting:
# Your domain (required for TLS)
PISOVEREIGN_DOMAIN=pi.example.com
# Email for Let's Encrypt certificates
TRAEFIK_ACME_EMAIL=you@example.com
# Vault root token (set after vault init)
VAULT_TOKEN=hvs.xxxxx
# Container image version
PISOVEREIGN_VERSION=latest
# Email provider preset: proton (default), gmail, or custom
EMAIL_PROVIDER=proton
Note: On first startup, PiSovereign automatically populates 32 default system commands and validates Vault credentials, logging warnings for any missing or invalid secrets. Check the container logs after first startup to verify all integrations are configured correctly.
Application Config
The main application config is at docker/config/config.toml.
All service hostnames use Docker network names (e.g., ollama:11434).
See Configuration Reference for all options.
Storing Secrets in Vault
After Vault initialization, store your integration secrets:
# Enter Vault container
docker compose exec vault sh
# Store WhatsApp credentials
vault kv put secret/pisovereign/whatsapp \
access_token="your-meta-token" \
app_secret="your-app-secret"
# Store Brave Search API key
vault kv put secret/pisovereign/websearch \
api_key="your-brave-api-key"
# Store CalDAV credentials
vault kv put secret/pisovereign/caldav \
password="your-caldav-password"
# Store email credentials (IMAP/SMTP)
vault kv put secret/pisovereign/email \
password="your-email-password"
Docker Compose Profiles
Additional services are available via profiles (see tables above for URLs):
Monitoring Stack
docker compose --profile monitoring up -d
CalDAV Server
docker compose --profile caldav up -d
All Profiles
docker compose --profile monitoring --profile caldav up -d
Signal Registration (Docker)
Signal requires a one-time registration before messages can be sent/received.
1. Set your phone number
Edit docker/.env and set your phone number in E.164 format:
SIGNAL_CLI_NUMBER=+491701234567
This automatically configures both the PiSovereign application and can be stored in Vault for secure persistence.
2. Register with Signal
# Register via SMS
docker compose exec signal-cli signal-cli -a +491701234567 register
# Or register via voice call
docker compose exec signal-cli signal-cli -a +491701234567 register --voice
3. Verify the code
# Enter the verification code received via SMS/voice
docker compose exec signal-cli signal-cli -a +491701234567 verify 123-456
4. Store in Vault (optional)
For production, store the phone number in Vault so it’s managed centrally:
docker compose exec vault vault kv put secret/pisovereign/signal \
phone_number="+491701234567"
The application loads the phone number in this priority order:
- config.toml —
[signal] phone_number = "..." - Environment variable —
PISOVEREIGN_SIGNAL__PHONE_NUMBER(set via.env) - Vault —
secret/pisovereign/signal→phone_number
5. Restart and verify
docker compose restart pisovereign
docker compose logs pisovereign | grep -i signal
For the full Signal setup guide, see Signal Setup.
Operations
Updating
cd docker
# Pull latest images
docker compose pull
# Recreate containers with new images
docker compose up -d
Vault Management
# Check Vault status
docker compose exec vault vault status
# Unseal after restart (use key from init)
docker compose exec vault vault operator unseal <UNSEAL_KEY>
# Read a secret
docker compose exec vault vault kv get secret/pisovereign/whatsapp
Logs
# Follow all logs
docker compose logs -f
# Specific service
docker compose logs -f pisovereign
# Last 100 lines
docker compose logs --tail=100 pisovereign
Backup
# Stop services
docker compose down
# Backup volumes
docker run --rm -v pisovereign-data:/data -v $(pwd):/backup \
alpine tar czf /backup/pisovereign-backup-$(date +%Y%m%d).tar.gz /data
# Restart
docker compose up -d
Troubleshooting
See the Troubleshooting guide for common issues.
GPU Acceleration
By default, Ollama runs CPU-only inside Docker. For GPU-accelerated inference:
- macOS (Metal): Run Ollama natively and set
OLLAMA_BASE_URLin.env - Linux (NVIDIA): Use
docker compose -f compose.yml -f compose.gpu-nvidia.yml up -d - Linux (AMD/ROCm): Create a
compose.override.ymlwith the ROCm image
See the full GPU Acceleration guide for setup instructions.