🐳 Docker Deployment
Containerized sovereignty: Deploy Reforms Messenger with enterprise-grade Docker orchestration
Docker deployment offers the fastest path to sovereign communication infrastructure. This guide covers everything from single-container development to production-ready orchestration with high availability and security.
🚀 Quick Start (5 Minutes)
Single Container Deployment
Get running immediately:
# Pull and run the latest stable release
docker run -d \
--name reforms-messenger \
-p 8443:8443 \
-p 3478:3478/udp \
-v $(pwd)/data:/app/data \
-v $(pwd)/config:/app/config \
-e REFORMS_MODE=production \
reforms/messenger:latest
Access your instance:
- Web interface:
https://localhost:8443
- Admin panel:
https://localhost:8443/admin
- API endpoint:
https://localhost:8443/api
Quick Configuration
Create basic configuration:
# Create config directory
mkdir -p ./config ./data ./ssl
# Generate basic config
cat > ./config/production.yaml << EOF
server:
host: "0.0.0.0"
port: 8443
ssl:
enabled: true
selfSigned: true
signaling:
mode: "zero-knowledge"
crypto:
identityProvider: "self-sovereign"
encryptionLevel: "maximum"
logging:
level: "info"
destination: "stdout"
EOF
📦 Docker Compose Setup
Basic Production Stack
Complete stack with database and monitoring:
# docker-compose.yml
version: '3.8'
services:
reforms-server:
image: reforms/messenger:latest
container_name: reforms-server
restart: unless-stopped
ports:
- "8443:8443"
- "3478:3478/udp"
- "3478:3478/tcp"
- "5349:5349/tcp"
environment:
- REFORMS_MODE=production
- REFORMS_CONFIG_PATH=/app/config/production.yaml
- REFORMS_DB_URL=postgresql://reforms:${DB_PASSWORD}@postgres:5432/reforms
- REFORMS_REDIS_URL=redis://redis:6379
volumes:
- ./config:/app/config:ro
- ./ssl:/app/ssl:ro
- ./data:/app/data
- ./logs:/app/logs
depends_on:
- postgres
- redis
networks:
- reforms-network
healthcheck:
test: ["CMD", "curl", "-f", "https://localhost:8443/health"]
interval: 30s
timeout: 10s
retries: 3
postgres:
image: postgres:15-alpine
container_name: reforms-postgres
restart: unless-stopped
environment:
- POSTGRES_DB=reforms
- POSTGRES_USER=reforms
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
- ./backups:/backups
networks:
- reforms-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U reforms"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: reforms-redis
restart: unless-stopped
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redis-data:/data
networks:
- reforms-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
nginx:
image: nginx:alpine
container_name: reforms-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/ssl:ro
depends_on:
- reforms-server
networks:
- reforms-network
volumes:
postgres-data:
redis-data:
networks:
reforms-network:
driver: bridge
Environment Configuration
Create .env
file:
# .env
REFORMS_VERSION=latest
DB_PASSWORD=your_secure_db_password_here
REDIS_PASSWORD=your_secure_redis_password_here
DOMAIN=your-domain.com
SSL_EMAIL=admin@your-domain.com
NGINX Configuration
Create nginx.conf
for SSL termination:
events {
worker_connections 1024;
}
http {
upstream reforms-backend {
server reforms-server:8443;
}
server {
listen 80;
server_name ${DOMAIN};
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name ${DOMAIN};
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# Security headers
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass https://reforms-backend;
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;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
⚙️ Advanced Configuration
High Availability Setup
Multi-node cluster with load balancing:
# docker-compose.ha.yml
version: '3.8'
services:
# Load balancer
haproxy:
image: haproxy:alpine
ports:
- "80:80"
- "443:443"
- "8404:8404" # Stats page
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
- ./ssl:/etc/ssl:ro
depends_on:
- reforms-server-1
- reforms-server-2
- reforms-server-3
# Primary server nodes
reforms-server-1:
image: reforms/messenger:latest
environment:
- REFORMS_NODE_ID=node-1
- REFORMS_CLUSTER_MODE=true
- REFORMS_CLUSTER_NODES=node-1,node-2,node-3
volumes:
- ./config:/app/config:ro
- ./data-1:/app/data
networks:
- reforms-cluster
reforms-server-2:
image: reforms/messenger:latest
environment:
- REFORMS_NODE_ID=node-2
- REFORMS_CLUSTER_MODE=true
- REFORMS_CLUSTER_NODES=node-1,node-2,node-3
volumes:
- ./config:/app/config:ro
- ./data-2:/app/data
networks:
- reforms-cluster
reforms-server-3:
image: reforms/messenger:latest
environment:
- REFORMS_NODE_ID=node-3
- REFORMS_CLUSTER_MODE=true
- REFORMS_CLUSTER_NODES=node-1,node-2,node-3
volumes:
- ./config:/app/config:ro
- ./data-3:/app/data
networks:
- reforms-cluster
# Shared database cluster
postgres-primary:
image: postgres:15-alpine
environment:
- POSTGRES_REPLICATION_MODE=master
- POSTGRES_REPLICATION_USER=replicator
- POSTGRES_REPLICATION_PASSWORD=${REPLICATION_PASSWORD}
volumes:
- postgres-primary-data:/var/lib/postgresql/data
postgres-replica:
image: postgres:15-alpine
environment:
- POSTGRES_REPLICATION_MODE=slave
- POSTGRES_REPLICATION_USER=replicator
- POSTGRES_REPLICATION_PASSWORD=${REPLICATION_PASSWORD}
- POSTGRES_MASTER_HOST=postgres-primary
depends_on:
- postgres-primary
volumes:
- postgres-replica-data:/var/lib/postgresql/data
networks:
reforms-cluster:
driver: overlay
attachable: true
volumes:
postgres-primary-data:
postgres-replica-data:
Healthcare (HIPAA) Configuration
HIPAA-compliant deployment:
# docker-compose.hipaa.yml
version: '3.8'
services:
reforms-server:
image: reforms/messenger:hipaa
environment:
- REFORMS_COMPLIANCE_MODE=HIPAA
- REFORMS_ENCRYPTION_LEVEL=FIPS-140-2
- REFORMS_AUDIT_LOGGING=true
- REFORMS_DATA_RETENTION=never
- REFORMS_GEO_RESTRICTION=US-only
volumes:
- ./config/hipaa.yaml:/app/config/production.yaml:ro
- ./ssl:/app/ssl:ro
- ./audit-logs:/app/audit-logs
- type: tmpfs
target: /tmp
tmpfs:
noexec: true
nosuid: true
size: 1G
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
read_only: true
user: "1000:1000"
# Encrypted database
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256
volumes:
- type: volume
source: postgres-encrypted
target: /var/lib/postgresql/data
volume:
driver: local
driver_opts:
type: "tmpfs"
device: "tmpfs"
o: "encryption=aes256"
volumes:
postgres-encrypted:
driver: local
driver_opts:
type: "nfs"
o: "encryption=aes256,backup=daily"
📈 Scaling Strategies
Horizontal Scaling
Auto-scaling with Docker Swarm:
# Initialize swarm
docker swarm init
# Deploy stack
docker stack deploy -c docker-compose.swarm.yml reforms
# Scale services
docker service scale reforms_reforms-server=5
docker service scale reforms_postgres=3
Swarm configuration:
# docker-compose.swarm.yml
version: '3.8'
services:
reforms-server:
image: reforms/messenger:latest
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
networks:
- reforms-overlay
networks:
reforms-overlay:
driver: overlay
attachable: true
Kubernetes Deployment
Production-ready Kubernetes manifests:
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: reforms-messenger
labels:
name: reforms-messenger
---
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: reforms-server
namespace: reforms-messenger
spec:
replicas: 3
selector:
matchLabels:
app: reforms-server
template:
metadata:
labels:
app: reforms-server
spec:
containers:
- name: reforms
image: reforms/messenger:latest
ports:
- containerPort: 8443
env:
- name: REFORMS_MODE
value: "production"
- name: REFORMS_CONFIG_PATH
value: "/app/config/production.yaml"
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
- name: ssl
mountPath: /app/ssl
readOnly: true
- name: data
mountPath: /app/data
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
livenessProbe:
httpGet:
path: /health
port: 8443
scheme: HTTPS
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8443
scheme: HTTPS
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: config
configMap:
name: reforms-config
- name: ssl
secret:
secretName: reforms-ssl
- name: data
persistentVolumeClaim:
claimName: reforms-data
---
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: reforms-service
namespace: reforms-messenger
spec:
selector:
app: reforms-server
ports:
- name: https
port: 8443
targetPort: 8443
- name: stun
port: 3478
targetPort: 3478
protocol: UDP
type: LoadBalancer
---
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: reforms-ingress
namespace: reforms-messenger
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- reforms.your-domain.com
secretName: reforms-tls
rules:
- host: reforms.your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: reforms-service
port:
number: 8443
🔒 Security Hardening
Container Security
Secure container configuration:
services:
reforms-server:
image: reforms/messenger:latest
security_opt:
- no-new-privileges:true
- apparmor:docker-default
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
- CHOWN
- SETGID
- SETUID
read_only: true
user: "1000:1000"
tmpfs:
- /tmp:noexec,nosuid,size=1G
- /var/run:noexec,nosuid,size=100M
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
Network Security
Network isolation and security:
networks:
reforms-frontend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
reforms-backend:
driver: bridge
internal: true
ipam:
config:
- subnet: 172.21.0.0/24
Secrets Management
Using Docker secrets:
# Create secrets
echo "your_db_password" | docker secret create db_password -
echo "your_redis_password" | docker secret create redis_password -
echo "your_ssl_cert" | docker secret create ssl_cert -
# Use in compose
services:
reforms-server:
secrets:
- db_password
- redis_password
- ssl_cert
environment:
- REFORMS_DB_PASSWORD_FILE=/run/secrets/db_password
secrets:
db_password:
external: true
redis_password:
external: true
ssl_cert:
external: true
📊 Monitoring & Observability
Comprehensive Monitoring Stack
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
- ./grafana/datasources:/etc/grafana/provisioning/datasources
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml
- loki-data:/loki
promtail:
image: grafana/promtail:latest
volumes:
- ./promtail-config.yaml:/etc/promtail/config.yml
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
volumes:
prometheus-data:
grafana-data:
loki-data:
🚀 Deployment Scripts
Automated Deployment
Complete deployment script:
#!/bin/bash
# deploy.sh - Automated Reforms Messenger deployment
set -euo pipefail
# Configuration
DOMAIN="${1:-localhost}"
EMAIL="${2:-admin@localhost}"
ENVIRONMENT="${3:-production}"
echo "🚀 Deploying Reforms Messenger"
echo "Domain: $DOMAIN"
echo "Environment: $ENVIRONMENT"
# Create directories
mkdir -p {config,data,ssl,logs,backups}
# Generate configuration
cat > config/production.yaml << EOF
server:
host: "0.0.0.0"
port: 8443
domain: "$DOMAIN"
ssl:
enabled: true
certPath: "/app/ssl/fullchain.pem"
keyPath: "/app/ssl/privkey.pem"
signaling:
mode: "zero-knowledge"
retentionPolicy: "never"
crypto:
identityProvider: "self-sovereign"
encryptionLevel: "maximum"
logging:
level: "info"
destination: "file"
path: "/app/logs/reforms.log"
EOF
# Generate SSL certificates (Let's Encrypt)
if [ "$DOMAIN" != "localhost" ]; then
docker run --rm \
-v $(pwd)/ssl:/etc/letsencrypt \
-p 80:80 \
certbot/certbot certonly \
--standalone \
--email "$EMAIL" \
--agree-tos \
--no-eff-email \
-d "$DOMAIN"
cp ssl/live/$DOMAIN/fullchain.pem ssl/
cp ssl/live/$DOMAIN/privkey.pem ssl/
else
# Generate self-signed certificate for localhost
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/privkey.pem \
-out ssl/fullchain.pem \
-subj "/C=US/ST=CA/L=SF/O=Reforms/CN=localhost"
fi
# Generate environment file
cat > .env << EOF
REFORMS_VERSION=latest
DB_PASSWORD=$(openssl rand -base64 32)
REDIS_PASSWORD=$(openssl rand -base64 32)
DOMAIN=$DOMAIN
SSL_EMAIL=$EMAIL
EOF
# Deploy with Docker Compose
docker-compose up -d
# Wait for services to be ready
echo "⏳ Waiting for services to start..."
sleep 30
# Health check
if curl -k -f "https://localhost:8443/health" > /dev/null 2>&1; then
echo "✅ Deployment successful!"
echo "🌐 Access your instance at: https://$DOMAIN"
echo "🔧 Admin panel: https://$DOMAIN/admin"
else
echo "❌ Deployment failed - check logs:"
docker-compose logs
fi
Make it executable:
chmod +x deploy.sh
./deploy.sh your-domain.com admin@your-domain.com production
🔧 Troubleshooting
Common Issues
Container won't start:
# Check logs
docker logs reforms-server
# Check configuration
docker exec reforms-server cat /app/config/production.yaml
# Test connectivity
docker exec reforms-server curl -k https://localhost:8443/health
SSL certificate issues:
# Verify certificate
openssl x509 -in ssl/fullchain.pem -text -noout
# Test SSL connection
openssl s_client -connect localhost:8443 -servername your-domain.com
Performance issues:
# Check resource usage
docker stats
# Monitor application metrics
curl -k https://localhost:8443/metrics
Containerized sovereignty. Enterprise security. Zero compromise.
Deploy with confidence. Scale with purpose. Control with precision.