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:

ServicePurposePortURL
pisovereignMain application server3000 (internal)http://localhost/ via Traefik
traefikReverse proxy + TLS80, 443http://localhost:80
vaultSecret management8200 (internal)Internal only
ollamaLLM inference engine11434 (internal)Internal only
signal-cliSignal messenger daemonUnix socketInternal only
whisperSpeech-to-text (STT)8081 (internal)Internal only
piperText-to-speech (TTS)8082 (internal)Internal only

Monitoring Stack (profile: monitoring)

ServicePurposePortURL
prometheusMetrics collection & alerting9090http://localhost:9090
grafanaDashboards & visualization3000 (internal)http://localhost/grafana via Traefik
lokiLog aggregation3100 (internal)Internal only
promtailLog shipping agentInternal only
node-exporterHost metrics exporter9100 (internal)Internal only
otel-collectorOpenTelemetry Collector4317/4318 (internal)Internal only

CalDAV Server (profile: caldav)

ServicePurposePortURL
baikalCalDAV/CardDAV server80 (internal)http://localhost/caldav via Traefik

Key Endpoints

EndpointDescription
http://localhost/healthApplication health check
http://localhost/metrics/prometheusPrometheus metrics scrape target
http://localhost/grafanaGrafana dashboards (monitoring profile)
http://localhost/caldavBaïkal CalDAV web UI (caldav profile)
http://localhost:9090Prometheus web UI (monitoring profile)
http://localhost:9090/targetsPrometheus 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:

  1. config.toml[signal] phone_number = "..."
  2. Environment variablePISOVEREIGN_SIGNAL__PHONE_NUMBER (set via .env)
  3. Vaultsecret/pisovereign/signalphone_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_URL in .env
  • Linux (NVIDIA): Use docker compose -f compose.yml -f compose.gpu-nvidia.yml up -d
  • Linux (AMD/ROCm): Create a compose.override.yml with the ROCm image

See the full GPU Acceleration guide for setup instructions.