Docker Swarm Deployment
🚧 Under Heavy Development​
OpenLift is currently under heavy development and we have not released any versions yet.
This installation document is a placeholder for future releases. Docker images are not yet published.
Deploy OpenLift on Docker Swarm for production-ready container orchestration with built-in load balancing, service discovery, and high availability.
Note: OpenLift container images are not yet published. To avoid implying availability, all image references are removed or commented. Replace placeholders with your own images when ready.
Prerequisites​
System Requirements​
- Docker Engine (20.10.0+ recommended)
- Docker Swarm initialized
- Multiple nodes (3+ recommended for production)
- Shared storage (NFS, GlusterFS, or similar for data persistence)
- Load balancer (optional, for external traffic distribution)
Network Requirements​
- Overlay network capability
- Ingress routing for external access
- Inter-node communication on required Docker Swarm ports
Quick Start​
Initialize Docker Swarm​
# On the manager node
docker swarm init --advertise-addr <MANAGER-IP>
# On worker nodes (use the command output from init)
docker swarm join --token <TOKEN> <MANAGER-IP>:2377
# Verify cluster status
docker node ls
Deploy OpenLift Stack​
# Download the Docker Swarm compose file
curl -o docker-swarm.yml https://raw.githubusercontent.com/openlift/openlift/main/docker-swarm.yml
# Deploy the stack
docker stack deploy -c docker-swarm.yml openlift
# Check services status
docker stack services openlift
Docker Swarm Compose Configuration​
Complete Stack File​
Create docker-swarm.yml:
version: '3.8'
services:
openlift:
# image: <to-be-published>
networks:
- openlift-network
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=mongodb://mongodb:27017/openlift
- REDIS_URL=redis://redis:6379
- MINIO_ENDPOINT=http://minio:9000
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
- MINIO_BUCKET_NAME=openlift
- JWT_SECRET=${JWT_SECRET}
- CORS_ORIGIN=https://openlift.yourdomain.com
secrets:
- jwt_secret
- db_password
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
placement:
constraints:
- node.role == worker
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
mongodb:
# image: <set-your-image>
networks:
- openlift-network
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/db_password
- MONGO_INITDB_DATABASE=openlift
secrets:
- db_password
volumes:
- mongodb_data:/data/db
- mongodb_config:/data/configdb
deploy:
replicas: 1
placement:
constraints:
- node.labels.storage == true
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 10s
retries: 5
start_period: 40s
redis:
# image: <set-your-image>
networks:
- openlift-network
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
deploy:
replicas: 1
placement:
constraints:
- node.labels.storage == true
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
minio:
# image: <set-your-image>
networks:
- openlift-network
ports:
- "9000:9000"
- "9001:9001"
command: server /data --console-address ":9001"
environment:
- MINIO_ROOT_USER=minioadmin
- MINIO_ROOT_PASSWORD=${MINIO_PASSWORD}
volumes:
- minio_data:/data
deploy:
replicas: 1
placement:
constraints:
- node.labels.storage == true
resources:
limits:
memory: 1G
cpus: '0.5'
reservations:
memory: 512M
cpus: '0.25'
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
nginx:
# image: <set-your-image>
networks:
- openlift-network
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- nginx_certs:/etc/nginx/certs
deploy:
replicas: 2
update_config:
parallelism: 1
delay: 10s
placement:
constraints:
- node.role == manager
depends_on:
- openlift
networks:
openlift-network:
driver: overlay
attachable: true
volumes:
mongodb_data:
driver: local
driver_opts:
type: nfs
o: addr=${NFS_SERVER},rw
device: ":/path/to/mongodb/data"
mongodb_config:
driver: local
driver_opts:
type: nfs
o: addr=${NFS_SERVER},rw
device: ":/path/to/mongodb/config"
redis_data:
driver: local
driver_opts:
type: nfs
o: addr=${NFS_SERVER},rw
device: ":/path/to/redis/data"
minio_data:
driver: local
driver_opts:
type: nfs
o: addr=${NFS_SERVER},rw
device: ":/path/to/minio/data"
nginx_certs:
driver: local
secrets:
jwt_secret:
external: true
db_password:
external: true
Environment Configuration​
Create .env file:
# Application settings
JWT_SECRET=your-super-secure-jwt-secret-here
REDIS_PASSWORD=secure-redis-password
MINIO_PASSWORD=secure-minio-password
# Storage settings
NFS_SERVER=192.168.1.100
# Domain settings
DOMAIN=openlift.yourdomain.com
Production Deployment Setup​
1. Prepare Swarm Cluster​
# Label nodes for specific services
docker node update --label-add storage=true node1
docker node update --label-add storage=true node2
# Create overlay network
docker network create --driver overlay --attachable openlift-network
2. Create Secrets​
# Create JWT secret
echo "your-super-secure-jwt-secret" | docker secret create jwt_secret -
# Create database password
echo "secure-database-password" | docker secret create db_password -
3. Set up Shared Storage​
# Example NFS setup (on NFS server)
sudo mkdir -p /nfs/openlift/{mongodb,redis,minio}
sudo chown -R nobody:nobody /nfs/openlift
sudo chmod -R 755 /nfs/openlift
# Configure NFS exports
echo "/nfs/openlift *(rw,sync,no_subtree_check,no_root_squash)" >> /etc/exports
sudo exportfs -a
4. Nginx Load Balancer Configuration​
Create nginx.conf:
events {
worker_connections 1024;
}
http {
upstream openlift_backend {
least_conn;
server openlift:3000 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name openlift.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name openlift.yourdomain.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
location / {
proxy_pass http://openlift_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";
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Health check endpoint
location /health {
access_log off;
proxy_pass http://openlift_backend/api/health;
}
}
}
Service Management​
Deploy and Update Services​
# Deploy the complete stack
docker stack deploy -c docker-swarm.yml openlift
# Update a specific service
# Example (placeholder): update service image when available
# docker service update --image <your-image>:<tag> openlift_openlift
# Scale services
docker service scale openlift_openlift=5
# Check service logs
docker service logs openlift_openlift --follow
Health Monitoring​
# Check stack services
docker stack services openlift
# Check service details
docker service inspect openlift_openlift
# Check service tasks
docker service ps openlift_openlift
# Monitor resource usage
docker stats
Rolling Updates​
# Update with zero downtime
docker service update \
--update-parallelism 1 \
--update-delay 30s \
--update-failure-action rollback \
openlift_openlift
# Monitor update progress
watch docker service ps openlift_openlift
High Availability Configuration​
Multi-Node Setup​
# Ensure proper node distribution
docker service update --constraint-add 'node.hostname!=node1' openlift_openlift
docker service update --placement-pref 'spread=node.hostname' openlift_openlift
Backup and Recovery​
# Backup database
docker exec $(docker ps -q -f name=openlift_mongodb) \
mongodump --out /backup/$(date +%Y%m%d_%H%M%S)
# Backup MinIO data
docker exec $(docker ps -q -f name=openlift_minio) \
tar czf /backup/minio_$(date +%Y%m%d_%H%M%S).tar.gz /data
Monitoring and Alerting​
# Set up health check monitoring
docker run -d --name monitoring \
--network openlift-network \
-v /var/run/docker.sock:/var/run/docker.sock \
<your-monitoring-image:tag>
Troubleshooting​
Common Issues​
# Check service status
docker stack services openlift
# View service logs
docker service logs openlift_openlift --tail 100
# Check node status
docker node ls
# Inspect service configuration
docker service inspect openlift_openlift --pretty
# Check network connectivity
docker network ls
docker network inspect openlift-network
Service Recovery​
# Force service recreation
docker service update --force openlift_openlift
# Remove and redeploy stack
docker stack rm openlift
sleep 30
docker stack deploy -c docker-swarm.yml openlift
Performance Optimization​
# Optimize container placement
docker service update \
--constraint-add 'node.labels.performance==high' \
openlift_openlift
# Adjust resource limits
docker service update \
--limit-memory 4G \
--limit-cpu 2 \
openlift_openlift
Security Considerations​
- Use Docker secrets for sensitive data
- Enable Docker security scanning for images
- Implement network segmentation with overlay networks
- Regular security updates for all services
- TLS encryption for all external communications
- Access control with proper user permissions
Docker Swarm provides a simpler alternative to Kubernetes while still offering production-ready container orchestration. This setup ensures high availability, automatic load balancing, and easy scaling for your OpenLift deployment.