Files
homelab-optimized/docs/getting-started/30-Deployment-Guide.md
Gitea Mirror Bot 93ca229fd5
Some checks failed
Documentation / Deploy to GitHub Pages (push) Has been cancelled
Documentation / Build Docusaurus (push) Has been cancelled
Sanitized mirror from private repository - 2026-04-06 01:59:54 UTC
2026-04-06 01:59:54 +00:00

743 lines
15 KiB
Markdown

# Deployment Guide
## Overview
This guide provides comprehensive instructions for deploying services in the homelab environment using GitOps principles with Docker Compose and Portainer. All deployments follow infrastructure-as-code practices with version control and automated workflows.
## Deployment Architecture
### GitOps Workflow
```
Developer ──▶ Git Repository ──▶ Portainer ──▶ Docker Compose ──▶ Running Services
│ │ │ │
│ │ │ └─▶ Health Checks
│ │ └─▶ Stack Management
│ └─▶ Configuration Validation
└─▶ Documentation Updates
```
### Repository Structure
```
homelab/
├── hosts/
│ ├── atlantis/ # Atlantis server configs
│ ├── calypso/ # Calypso server configs
│ ├── concord_nuc/ # Concord NUC configs
│ ├── homelab_vm/ # Homelab VM configs
│ └── raspberry-pi-5-vish/ # Raspberry Pi configs
├── common/ # Shared configurations
├── docs/ # Documentation
└── scripts/ # Automation scripts
```
## Prerequisites
### Required Access
- **Git Repository**: Read access to homelab repository
- **Portainer Access**: Admin credentials for container management
- **SSH Access**: Server administration capabilities
- **Network Access**: Internal network connectivity
### Required Tools
```bash
# Install required tools
sudo apt update && sudo apt install -y \
git \
docker.io \
docker-compose \
curl \
wget \
vim
# Verify installations
git --version
docker --version
docker-compose --version
```
### Environment Setup
```bash
# Clone repository
git clone https://git.vish.gg/Vish/homelab.git
cd homelab
# Set up environment variables
export HOMELAB_ENV="production"
export DOCKER_HOST="tcp://atlantis.vish.local:2376"
export PORTAINER_URL="http://atlantis.vish.local:9000"
```
## Deployment Methods
### Method 1: Portainer Stack Deployment (Recommended)
#### Step 1: Access Portainer
1. Navigate to [Portainer](http://atlantis.vish.local:9000)
2. Login with admin credentials
3. Select the appropriate endpoint
#### Step 2: Create New Stack
1. Go to **Stacks****Add Stack**
2. Choose deployment method:
- **Git Repository** (recommended)
- **Upload** (for local files)
- **Web Editor** (for quick edits)
#### Step 3: Configure Git Repository
```yaml
Repository URL: https://git.vish.gg/Vish/homelab.git
Reference: refs/heads/main
Compose Path: hosts/atlantis/service-name.yml
```
#### Step 4: Set Environment Variables
```bash
# Common variables
PUID=1000
PGID=1000
TZ=America/New_York
DOMAIN=vish.local
# Service-specific variables
SERVICE_PORT=8080
SERVICE_DATA=/mnt/storage/service-name
```
#### Step 5: Deploy Stack
1. Click **Deploy the Stack**
2. Monitor deployment logs
3. Verify service health
### Method 2: Command Line Deployment
#### Direct Docker Compose
```bash
# Navigate to service directory
cd hosts/atlantis
# Deploy service
docker-compose -f service-name.yml up -d
# Check status
docker-compose -f service-name.yml ps
# View logs
docker-compose -f service-name.yml logs -f
```
#### Using Deployment Scripts
```bash
# Run deployment script
./scripts/deploy-service.sh atlantis service-name
# Bulk deployment
./scripts/deploy-all.sh atlantis
# Update existing service
./scripts/update-service.sh atlantis service-name
```
### Method 3: Ansible Automation
#### Playbook Deployment
```bash
# Deploy single service
ansible-playbook -i inventory.ini ansible/deploy-service.yml \
-e target_host=atlantis \
-e service_name=plex
# Deploy full stack
ansible-playbook -i inventory.ini ansible/deploy-full-stack.yml \
-e target_host=atlantis
# Update all services
ansible-playbook -i inventory.ini ansible/update-all.yml
```
## Service Configuration
### Docker Compose Template
```yaml
version: '3.8'
services:
service-name:
image: organization/service:latest
container_name: service-name
restart: unless-stopped
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-UTC}
- SERVICE_CONFIG=${SERVICE_CONFIG}
volumes:
- ${DATA_PATH}/config:/config
- ${DATA_PATH}/data:/data
- /etc/localtime:/etc/localtime:ro
ports:
- "${SERVICE_PORT}:8080"
networks:
- homelab
labels:
- "traefik.enable=true"
- "traefik.http.routers.service.rule=Host(`service.${DOMAIN}`)"
- "traefik.http.services.service.loadbalancer.server.port=8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
homelab:
external: true
volumes:
service-config:
driver: local
service-data:
driver: local
```
### Environment Variables
```bash
# Create .env file
cat > .env << EOF
# User Configuration
PUID=1000
PGID=1000
TZ=America/New_York
# Network Configuration
DOMAIN=vish.local
SUBNET=192.168.10.0/24
# Storage Configuration
DATA_ROOT=/mnt/storage
CONFIG_ROOT=/mnt/config
BACKUP_ROOT=/mnt/backup
# Service Configuration
SERVICE_PORT=8080
SERVICE_NAME=example-service
SERVICE_VERSION=latest
# Security Configuration
SSL_CERT_PATH=/etc/ssl/certs
SSL_KEY_PATH=/etc/ssl/private
ADMIN_EMAIL=admin@vish.local
EOF
```
## Server-Specific Deployments
### Atlantis (Primary Server)
```bash
# Media services
./deploy-service.sh atlantis plex
./deploy-service.sh atlantis sonarr
./deploy-service.sh atlantis radarr
# Storage services
./deploy-service.sh atlantis nextcloud
./deploy-service.sh atlantis syncthing
# Monitoring services
./deploy-service.sh atlantis grafana
./deploy-service.sh atlantis prometheus
```
### Calypso (Secondary Server)
```bash
# Development services
./deploy-service.sh calypso gitea
./deploy-service.sh calypso portainer
# Authentication services
./deploy-service.sh calypso authentik
./deploy-service.sh calypso nginx-proxy-manager
# Game servers
./deploy-service.sh calypso minecraft
./deploy-service.sh calypso satisfactory
```
### Concord NUC (Edge Server)
```bash
# Network services
./deploy-service.sh concord adguard
./deploy-service.sh concord pihole
# IoT services
./deploy-service.sh concord homeassistant
./deploy-service.sh concord node-exporter
# Media streaming
./deploy-service.sh concord invidious
./deploy-service.sh concord piped
```
### Homelab VM (Development)
```bash
# AI/ML services
./deploy-service.sh homelab-vm ollama
./deploy-service.sh homelab-vm openhands
# Communication services
./deploy-service.sh homelab-vm mattermost
./deploy-service.sh homelab-vm signal-api
# Testing services
./deploy-service.sh homelab-vm test-environment
```
### Raspberry Pi (Monitoring)
```bash
# Monitoring services
./deploy-service.sh raspberry-pi uptime-kuma
./deploy-service.sh raspberry-pi glances
# Lightweight services
./deploy-service.sh raspberry-pi immich
./deploy-service.sh raspberry-pi syncthing
```
## Network Configuration
### Docker Networks
```bash
# Create homelab network
docker network create \
--driver bridge \
--subnet=172.20.0.0/16 \
--gateway=172.20.0.1 \
homelab
# Create monitoring network
docker network create \
--driver bridge \
--subnet=172.21.0.0/16 \
--gateway=172.21.0.1 \
monitoring
# List networks
docker network ls
```
### Reverse Proxy Configuration
```yaml
# Nginx Proxy Manager
version: '3.8'
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
environment:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
```
## Storage Configuration
### Volume Mapping
```yaml
# Standard volume structure
volumes:
- ${DATA_ROOT}/service-name/config:/config
- ${DATA_ROOT}/service-name/data:/data
- ${MEDIA_ROOT}:/media:ro
- ${DOWNLOAD_ROOT}:/downloads
- /etc/localtime:/etc/localtime:ro
```
### Backup Integration
```yaml
# Backup-aware service
services:
service-name:
# ... service configuration ...
volumes:
- service-data:/data
- backup-volume:/backup
labels:
- "backup.enable=true"
- "backup.schedule=0 2 * * *"
- "backup.retention=30d"
volumes:
backup-volume:
driver: local
driver_opts:
type: nfs
o: addr=backup-server.local,rw
device: ":/mnt/backup/service-name"
```
## Security Configuration
### Container Security
```yaml
services:
secure-service:
# ... other configuration ...
# Security options
security_opt:
- no-new-privileges:true
# Read-only root filesystem
read_only: true
# Temporary filesystem for writable areas
tmpfs:
- /tmp
- /var/tmp
# User namespace
user: "${PUID}:${PGID}"
# Capabilities
cap_drop:
- ALL
cap_add:
- CHOWN
- SETUID
- SETGID
```
### Network Security
```yaml
# Isolated network configuration
networks:
frontend:
driver: bridge
internal: false
backend:
driver: bridge
internal: true
services:
web-service:
networks:
- frontend
- backend
database:
networks:
- backend
```
## Monitoring Integration
### Health Checks
```yaml
services:
monitored-service:
# ... service configuration ...
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
labels:
- "monitoring.enable=true"
- "monitoring.port=8080"
- "monitoring.path=/metrics"
```
### Logging Configuration
```yaml
services:
logged-service:
# ... service configuration ...
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "service,environment"
labels:
- "logging.enable=true"
- "logging.service=service-name"
```
## Deployment Validation
### Pre-deployment Checks
```bash
#!/bin/bash
# validate-deployment.sh
echo "Validating deployment configuration..."
# Check Docker Compose syntax
docker-compose -f $1 config > /dev/null
if [ $? -eq 0 ]; then
echo "✅ Docker Compose syntax valid"
else
echo "❌ Docker Compose syntax error"
exit 1
fi
# Check required environment variables
required_vars=("PUID" "PGID" "TZ" "DOMAIN")
for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
echo "❌ Missing required variable: $var"
exit 1
else
echo "✅ Variable $var is set"
fi
done
# Check storage paths
if [ ! -d "$DATA_ROOT" ]; then
echo "❌ Data root directory does not exist: $DATA_ROOT"
exit 1
else
echo "✅ Data root directory exists"
fi
echo "✅ All validation checks passed"
```
### Post-deployment Verification
```bash
#!/bin/bash
# verify-deployment.sh
SERVICE_NAME=$1
EXPECTED_PORT=$2
echo "Verifying deployment of $SERVICE_NAME..."
# Check container status
if docker ps | grep -q $SERVICE_NAME; then
echo "✅ Container is running"
else
echo "❌ Container is not running"
exit 1
fi
# Check port accessibility
if curl -f http://localhost:$EXPECTED_PORT/health > /dev/null 2>&1; then
echo "✅ Service is responding on port $EXPECTED_PORT"
else
echo "❌ Service is not responding on port $EXPECTED_PORT"
fi
# Check logs for errors
if docker logs $SERVICE_NAME 2>&1 | grep -i error; then
echo "⚠️ Errors found in logs"
else
echo "✅ No errors in logs"
fi
echo "✅ Deployment verification complete"
```
## Troubleshooting
### Common Issues
#### Container Won't Start
```bash
# Check container logs
docker logs container-name
# Check resource usage
docker stats
# Verify configuration
docker-compose config
# Check port conflicts
netstat -tulpn | grep :8080
```
#### Permission Issues
```bash
# Fix ownership
sudo chown -R $PUID:$PGID /mnt/storage/service-name
# Check permissions
ls -la /mnt/storage/service-name
# Verify user mapping
docker exec container-name id
```
#### Network Connectivity
```bash
# Test container networking
docker exec container-name ping google.com
# Check network configuration
docker network inspect homelab
# Verify DNS resolution
docker exec container-name nslookup service.local
```
#### Storage Issues
```bash
# Check disk space
df -h
# Verify mount points
mount | grep storage
# Check RAID status
cat /proc/mdstat
```
### Emergency Procedures
#### Service Recovery
```bash
# Stop problematic service
docker-compose -f service.yml down
# Remove containers and volumes
docker-compose -f service.yml down -v
# Restore from backup
./scripts/restore-service.sh service-name
# Redeploy service
docker-compose -f service.yml up -d
```
#### System Recovery
```bash
# Stop all services
docker stop $(docker ps -q)
# Clean up system
docker system prune -a
# Restart Docker daemon
sudo systemctl restart docker
# Redeploy critical services
./scripts/deploy-critical.sh
```
## Automation Scripts
### Deployment Automation
```bash
#!/bin/bash
# deploy-service.sh
HOST=$1
SERVICE=$2
COMPOSE_FILE="hosts/$HOST/$SERVICE.yml"
if [ ! -f "$COMPOSE_FILE" ]; then
echo "Error: Compose file not found: $COMPOSE_FILE"
exit 1
fi
echo "Deploying $SERVICE on $HOST..."
# Validate configuration
docker-compose -f $COMPOSE_FILE config > /dev/null
if [ $? -ne 0 ]; then
echo "Error: Invalid compose configuration"
exit 1
fi
# Deploy service
docker-compose -f $COMPOSE_FILE up -d
# Wait for service to be ready
sleep 30
# Verify deployment
./scripts/verify-deployment.sh $SERVICE
echo "Deployment complete: $SERVICE"
```
### Update Automation
```bash
#!/bin/bash
# update-service.sh
SERVICE=$1
echo "Updating $SERVICE..."
# Pull latest images
docker-compose -f hosts/*/$(SERVICE).yml pull
# Recreate containers
docker-compose -f hosts/*/$(SERVICE).yml up -d
# Clean up old images
docker image prune -f
echo "Update complete: $SERVICE"
```
## Best Practices
### Configuration Management
- Use environment variables for configuration
- Store secrets in Docker secrets or external vaults
- Version control all configuration files
- Document all custom configurations
### Resource Management
- Set appropriate resource limits
- Monitor resource usage
- Plan for capacity growth
- Implement resource quotas
### Security Practices
- Use non-root users in containers
- Implement network segmentation
- Regular security updates
- Monitor for vulnerabilities
### Backup Strategies
- Automate backup processes
- Test restore procedures
- Implement versioned backups
- Store backups offsite
## Related Documentation
- **[Service Categories](20-Service-Categories.md)** - Available services overview
- **[Common Issues](40-Common-Issues.md)** - Troubleshooting guide
- **[Ansible Automation](50-Ansible-Automation.md)** - Automated deployments
- **[GitOps Guide](../GITOPS_DEPLOYMENT_GUIDE.md)** - GitOps workflows
---
*This deployment guide provides comprehensive instructions for deploying and managing services in the homelab environment using modern DevOps practices and tools.*