- Main reverse proxy handling all incoming traffic
- Automatic SSL certificate management through Let's Encrypt
- Integration with Cloudflare DNS for domain validation
- Secure dashboard for monitoring and management
- HTTP to HTTPS redirection
- Customizable dashboard for your home lab
- Service status monitoring
- Bookmarks and quick access to services
- Widget support for extended functionality
- Docker integration for container status
- Service monitoring and status page
- Real-time uptime checks (HTTP, Ping, Port, etc.)
- Notification integrations (Email, Slack, Discord, etc.)
- Customizable status pages
- Self-hosted Git repository management
- CI/CD pipelines
- Container registry
- Issue tracking and project management
- Virtualization platform
- VM and container management
- Accessed via Traefik reverse proxy
- Network Attached Storage
- ZFS-based storage system
- Accessed via Traefik reverse proxy
- Network management
- Device monitoring
- Accessed via Traefik reverse proxy
- Media server for movies, TV, music, and photos
- User management with profiles
- Transcoding capabilities
- Mobile apps available
- Recipe management and meal planning
- Automatic recipe import from websites
- Shopping list generation
- Meal calendar for planning
- Mobile-friendly interface
- Home automation platform
- IoT device integration and control
- Automation workflows
- Energy monitoring
- Accessed via Traefik reverse proxy
- Self-hosted AI model server
- Local AI model inference
- API access for integration with other services
- Web interface for Ollama AI models
- Provides a user-friendly chat interface
- Manages models and configurations
- LLM API Gateway and Router
- Standardizes API calls to various LLMs
- Provides load balancing and fallback options
- Self-hosted speech-to-text using NVIDIA NeMo
- Parakeet TDT model for fast transcription
- Punctuation, capitalisation, and ITN post-processing
- Optional LLM cleanup via Ollama
- REST API with Bearer token authentication
- Workflow automation platform
- Connects different services and APIs
- Visual workflow editor
- Self-hosted collaborative bookmark manager
- Preserves web pages as snapshots (HTML, PDF, Screenshot)
- Organize links with collections and tags
- Accessed via Traefik reverse proxy
- Linux server with Docker (20.10+) and Docker Compose (v2+) installed
- Domain name with Cloudflare DNS management
- SSL/TLS certificates from Let's Encrypt (managed automatically by Traefik)
- Basic understanding of networking and Docker concepts
- Port 80 and 443 accessible from the internet
- For Jellyfin: sufficient storage for media files
Install Docker and Docker Compose if not already installed:
# Update system
sudo apt update && sudo apt upgrade -y
# Install required packages
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Add Docker repository
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Install Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Add your user to the docker group
sudo usermod -aG docker $USER
# Apply changes (or log out and back in)
newgrp dockerClone the repository to your server:
git clone <repository-url>
cd dockerCreate the required Docker network for all services:
docker network create proxySet up environment files for each service:
# Create and configure Traefik environment file
cp traefik/.env.example traefik/.env
# Create and configure Linkwarden environment file (requires manual password entry)
# (The NEXTAUTH_SECRET will be generated if not present)
cp linkwarden/.env.example linkwarden/.env # Or create manually if no exampleEdit the .env files with your specific configurations:
# Example configurations for traefik/.env
TRAEFIK_DASHBOARD_AUTH=admin:$(htpasswd -nb admin your_secure_password | sed 's/\\$/\\$\\$/g')
[email protected]
TRAEFIK_LOG_PATH=/var/log/traefik/access.log
CF_DNS_API_TOKEN=your_cloudflare_api_token_here
DOMAIN_TRAEFIK=traefik.openshaw.tech
DOMAIN_GITLAB=gitlab.openshaw.tech
# Add other domain names as needed
# Example structure for linkwarden/.env (Set SECURE passwords!)
# NEXTAUTH_SECRET=YOUR_SECURE_NEXTAUTH_SECRET_HERE
# NEXTAUTH_URL=https://linkwarden.openshaw.tech/api/v1/auth
# POSTGRES_USER=linkwarden
# POSTGRES_PASSWORD=YOUR_SECURE_POSTGRES_PASSWORD_HERE
# POSTGRES_DB=linkwardenPrepare directories for persistent data and ensure proper permissions:
# Create required directories for Traefik
mkdir -p traefik/data
touch traefik/data/acme.json
chmod 600 traefik/data/acme.json
# Prepare directories for other services as needed
mkdir -p gitlab/{config,logs,data}
mkdir -p homepage/data
mkdir -p mealie/data
mkdir -p ollama/data
mkdir -p jellyfin/data
mkdir -p linkwarden # Added for Linkwarden volumes (pgdata, data)
mkdir -p uptime-kuma/data # Added for Uptime Kuma- Login to your Cloudflare account
- Add DNS records for each service:
- Type: A or CNAME
- Name: subdomain (e.g., traefik, gitlab, uptime)
- Content: Your server's IP address
- Proxy status: DNS only (gray cloud)
Deploy services in the correct order:
# Start Traefik first (core infrastructure)
cd traefik
docker compose up -d
cd ..
# Deploy Homepage dashboard
cd homepage
docker compose up -d
cd ..
# Deploy GitLab (may take several minutes to fully initialize)
cd gitlab
docker compose up -d
cd ..
# Deploy other services
cd ollama
docker compose up -d
cd ..
cd mealie
docker compose up -d
cd ..
cd jellyfin
docker compose up -d
cd ..
# Deploy Linkwarden
cd linkwarden
# IMPORTANT: Ensure .env has secrets before running!
docker compose up -d
cd ..
# Deploy Uptime Kuma
cd uptime-kuma
docker compose up -d
cd ..Refer to the homeassistant directory for detailed setup and configuration instructions.
# Start Home Assistant
cd homeassistant
docker compose up -d
cd ..Check that all containers are running correctly:
docker psVerify service access through your domain names:
- https://traefik.openshaw.tech
- https://gitlab.openshaw.tech
- https://homepage.openshaw.tech
- https://recipes.openshaw.tech
- https://jellyfin.openshaw.tech
- https://ollama.openshaw.tech
- https://linkwarden.openshaw.tech
- https://uptime.openshaw.tech
- https://stt.openshaw.tech
-
Main configuration:
traefik/config/traefik.yaml- Controls log levels, entry points, and global settings
- Configures the dashboard and API access
- Sets up certificate resolvers for Let's Encrypt
- Defines Docker provider settings
-
Service rules:
traefik/config/config.yaml- Contains static service definitions for external services
- Defines routing rules, middlewares, and load balancer options
- Configures TLS settings for each service
-
Environment variables:
traefik/.env- Cloudflare API credentials for DNS challenges
- Dashboard authentication credentials
- Domain names for each service
- Log file paths
Key Features:
- Automatic SSL certificate generation and renewal using Let's Encrypt
- DNS-01 challenge through Cloudflare for wildcard certificates
- Docker service discovery for automatic container registration
- Secure dashboard access with basic authentication
- HTTP to HTTPS redirection for all services
- Support for both Docker-based and external services
-
Main configuration:
gitlab/config/gitlab.rb- Server settings, feature toggles, and integration options
- SMTP configuration for email notifications
- Backup settings and scheduling
-
Secrets:
gitlab/config/gitlab-secrets.json- Automatically generated secrets for GitLab services
- Should not be manually edited
-
Custom SSL certificates:
gitlab/config/ssl/- SSL certificates are managed by Traefik
- GitLab is configured to use HTTP behind Traefik's SSL termination
-
Important settings:
- GitLab is exposed on ports 8929 (HTTP), 8930 (HTTPS), and 8922 (SSH)
- Traefik routes traffic based on the hostname
gitlab.openshaw.tech
-
Service configuration:
homepage/data/services.yaml- Defines service groups and their details
- Sets icons, URLs, and descriptions for each service
-
Custom styling:
homepage/data/custom.css- Custom CSS for Homepage appearance
-
Widgets:
homepage/data/widgets.yaml- Configures dashboard widgets and their placement
- Integrates with Docker for container status
-
Environment settings:
- Allowed hosts configuration:
HOMEPAGE_ALLOWED_HOSTS=10.1.10.10:3000,homepage.openshaw.tech - Docker socket mounted for container integration
- Allowed hosts configuration:
-
Docker Compose configuration:
jellyfin/docker-compose.yaml- Container environment variables for user/group IDs
- Volume mappings for configuration and media
- Optional GPU passthrough (currently commented out)
-
Media directories:
/mnt/dozer/mediamapped to/datainside the container- Persistent volume for configuration data
-
Network settings:
- Discovery ports: 7359/udp and 1900/udp for DLNA
- Traefik labels for routing through
jellyfin.openshaw.tech
-
Docker Compose configuration:
mealie/docker-compose.yaml- Environment variables for feature toggles
- Volume mappings for persistent data
-
Data storage:
mealie/data/- Database files
- Recipe images and backups
- User data and templates
-
Key settings:
- Recipe visibility:
RECIPE_PUBLIC=true - Signup allowed:
ALLOW_SIGNUP=true - Port 9000 exposed internally and routed through Traefik
- Recipe visibility:
-
Docker Compose configuration:
ollama/docker-compose.yaml- Volume mapping for model storage
- Network configuration for API access
- GPU configuration for hardware acceleration
-
Data storage:
ollama_dataDocker volume- Stores downloaded AI models
- Persists configuration between container restarts
-
API access:
- Internal port 11434 exposed for API calls
- Accessible through Traefik at
ollama.openshaw.tech
-
GPU Configuration:
- Uses NVIDIA runtime for GPU acceleration
- Environment variables:
NVIDIA_VISIBLE_DEVICES=all- Makes all GPUs visible to the containerNVIDIA_DRIVER_CAPABILITIES=compute,utility- Enables necessary GPU functions
- Memory limits:
- Set to 40GB for larger language models
- For large models (like Gemma3:27b), ensure:
- Sufficient host RAM (minimum 32GB, recommended 48GB)
- NVIDIA GPU with adequate VRAM (24GB+ for full-sized models)
- VM configuration with proper VFIO passthrough (if using VMs)
- Docker Compose configuration:
linkwarden/docker-compose.yaml- Environment variables for Linkwarden configuration
- Volume mappings for Linkwarden data and configuration
- Docker Compose configuration:
uptime-kuma/docker-compose.yaml- Volume mapping for persistent data (
./data:/app/data) - Traefik labels for routing through
uptime.openshaw.tech
- Volume mapping for persistent data (
- Configuration: Done via the web UI at
https://uptime.openshaw.techafter initial setup. - Data storage:
uptime-kuma/data/- Stores monitor configurations, history, and user settings.
GitLab has built-in backup functionality:
# Enter the GitLab container
docker exec -it gitlab /bin/bash
# Create a backup
gitlab-backup create STRATEGY=copy
# Exit the container
exit
# Copy backups to a safe location
rsync -avz ~/docker/gitlab/data/backups/ /path/to/backup/destination/Mealie creates automatic database backups:
# Copy Mealie backups to external storage
rsync -avz ~/docker/mealie/data/backups/ /path/to/backup/destination/Uptime Kuma stores its configuration in a SQLite database within its data volume.
# Backup Uptime Kuma data volume
rsync -avz ~/docker/uptime-kuma/data/ /path/to/backup/destination/uptime-kuma-data/Create a script to regularly backup your configuration files:
#!/bin/bash
BACKUP_DIR="/path/to/backup/destination/configs-$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# Backup environment files
cp ~/docker/traefik/.env $BACKUP_DIR/traefik.env
cp ~/docker/*/.env $BACKUP_DIR/ 2>/dev/null
# Backup configuration files
cp -r ~/docker/traefik/config $BACKUP_DIR/traefik-config
cp -r ~/docker/homepage/data/*.yaml $BACKUP_DIR/homepage-config
cp -r ~/docker/gitlab/config/gitlab.rb $BACKUP_DIR/gitlab-config
# Backup SSL certificates
cp ~/docker/traefik/data/acme.json $BACKUP_DIR/
# Compress backup
tar -czf $BACKUP_DIR.tar.gz $BACKUP_DIR
rm -rf $BACKUP_DIR
echo "Backup completed: $BACKUP_DIR.tar.gz"Save this as backup-configs.sh, make it executable with chmod +x backup-configs.sh and schedule it with cron.
Regular update script:
#!/bin/bash
LOG_FILE="/var/log/docker-updates.log"
echo "Docker update started at $(date)" >> $LOG_FILE
cd ~/docker
# Update container images
echo "Pulling latest images..." >> $LOG_FILE
docker compose pull >> $LOG_FILE 2>&1
# Restart services with new images
services=("traefik" "gitlab" "homepage" "mealie" "ollama" "jellyfin" "linkwarden" "uptime-kuma")
for service in "${services[@]}"; do
echo "Updating $service..." >> $LOG_FILE
cd ~/docker/$service
docker compose down
docker compose up -d
cd ~/docker
echo "$service updated successfully." >> $LOG_FILE
done
echo "Docker update completed at $(date)" >> $LOG_FILESave this as update-containers.sh, make it executable and schedule it during a maintenance window.
Perform these tasks monthly:
-
Check disk space usage:
df -h docker system df
-
Clean up unused Docker resources:
docker system prune --volumes
-
Check container logs for errors:
for service in traefik gitlab homepage mealie ollama jellyfin linkwarden uptime-kuma; do docker logs --tail 100 $service > /tmp/$service-logs.txt done grep -i error /tmp/*-logs.txt
-
Verify SSL certificate expiration dates:
# Check main domain echo | openssl s_client -servername traefik.openshaw.tech -connect traefik.openshaw.tech:443 2>/dev/null | openssl x509 -noout -dates # Check another service domain echo | openssl s_client -servername uptime.openshaw.tech -connect uptime.openshaw.tech:443 2>/dev/null | openssl x509 -noout -dates
-
Verify backup integrity:
# Test restore a backup to a temporary location docker run --rm -v ~/docker/gitlab/data/backups:/backups -v /tmp/gitlab-restore:/restore gitlab/gitlab-ce bash -c "mkdir -p /restore && tar -xf /backups/latest-backup.tar -C /restore"
-
Firewall Configuration:
# Allow only necessary ports sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp # SSH sudo ufw allow 80/tcp # HTTP sudo ufw allow 443/tcp # HTTPS sudo ufw enable
-
Traefik Security Headers: Add to your Traefik configuration:
# Add to traefik.yaml middlewares: security-headers: headers: frameDeny: true browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true stsIncludeSubdomains: true stsPreload: true stsSeconds: 31536000
-
Container Security:
- Run containers as non-root users where possible
- Use read-only file systems where applicable
- Limit container capabilities
-
Two-factor authentication:
- Enable 2FA for GitLab
- Use strong passwords for all service dashboards
-
Regular Credential Rotation:
- Change API keys quarterly
- Update dashboard passwords regularly
-
SSH Hardening:
# Edit SSH configuration sudo nano /etc/ssh/sshd_config # Recommended settings PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes
-
Secrets Management:
- Store all credentials in .env files (excluded from git)
- Consider using Docker secrets for production environments
-
Uptime Kuma:
- Use the Uptime Kuma instance at
https://uptime.openshaw.techto monitor all other services.
- Use the Uptime Kuma instance at
-
Traefik Access Logs:
- Review logs regularly:
cat ${TRAEFIK_LOG_PATH} - Set up log rotation to prevent disk filling
- Review logs regularly:
-
Docker Stats:
# Live container resource usage docker stats -
Advanced Monitoring: Consider adding Prometheus and Grafana:
# Add to docker-compose.yaml prometheus: image: prom/prometheus volumes: - ./prometheus:/etc/prometheus # ...configuration... grafana: image: grafana/grafana # ...configuration...
-
Let's Encrypt Rate Limits:
- Problem: Too many certificate requests
- Solution: Use staging environment first
# In traefik.yaml certificatesResolvers: letsencrypt: acme: caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
-
Cloudflare DNS Verification:
- Problem: DNS-01 challenge failing
- Solution: Verify API token permissions (Zone:DNS:Edit)
- Check logs:
docker logs traefik
-
Certificate Renewal:
- Problem: Certificates not renewing
- Solution: Check permissions on
acme.json(chmod 600) - Verify Traefik can reach Let's Encrypt servers
-
Container Cannot Reach Internet:
- Problem: DNS resolution issues
- Solution: Add DNS servers to Docker daemon
# /etc/docker/daemon.json { "dns": ["1.1.1.1", "8.8.8.8"] }
- Restart Docker:
sudo systemctl restart docker
-
Services Can't Communicate:
- Problem: Containers can't reach each other
- Solution: Verify all containers are on the
proxynetworkdocker network inspect proxy
-
Port Conflicts:
- Problem: Services fail to start due to port conflicts
- Solution: Check if ports are already in use
sudo netstat -tulpn | grep LISTEN
-
GitLab Slow/Unresponsive:
- Problem: High resource usage
- Solution: Adjust resource limits in
gitlab.rb# Reduce worker counts sidekiq['concurrency'] = 5 puma['worker_processes'] = 2
- Increase server resources if possible
-
Jellyfin Transcoding Issues:
- Problem: Videos stutter or fail to play
- Solution: Enable hardware acceleration
# Uncomment in docker-compose.yaml deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]
- Install appropriate GPU drivers on host
-
Traefik Dashboard 404:
- Problem: Can't access Traefik dashboard
- Solution: Verify API is enabled and dashboard middleware
# traefik.yaml api: dashboard: true
To add a new service to your infrastructure:
-
Create a new directory in
~/docker/ -
Create a
docker-compose.yamlfile with appropriate Traefik labels:services: new-service: image: new-service-image container_name: new-service labels: - "traefik.enable=true" - "traefik.http.routers.new-service.rule=Host(`new-service.openshaw.tech`)" - "traefik.http.routers.new-service.entrypoints=websecure" - "traefik.http.routers.new-service.tls.certresolver=letsencrypt" - "traefik.http.services.new-service.loadbalancer.server.port=SERVICE_PORT" # Example for Uptime Kuma: # - "traefik.http.routers.uptime-kuma.rule=Host(`uptime.openshaw.tech`)" # - "traefik.http.services.uptime-kuma.loadbalancer.server.port=3001" networks: - proxy networks: proxy: external: true
-
Add the service to Homepage dashboard in
homepage/data/services.yaml -
Add the service to Uptime Kuma for monitoring via its web UI.
-
Deploy the service:
docker compose up -d
For critical services, consider implementing high availability:
- Use Docker Swarm or Kubernetes for container orchestration
- Implement database replication for stateful services
- Use shared storage solutions for persistent data
- Configure load balancing across multiple nodes
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.