Skip to content

Docker runtime of my private docker instances

Notifications You must be signed in to change notification settings

Spiev/docker-runtime

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker Homelab Infrastructure

A production-ready Docker Compose setup for self-hosted services on Raspberry Pi or similar home servers. This repository contains configurations for various services including reverse proxy, home automation, photo management, document management, and more.

🌟 Features

  • Production-tested configurations for Raspberry Pi
  • Security-hardened with fail2ban, rate limiting, and SSL
  • Automated dependency updates via GitHub Dependabot
  • MQTT-based monitoring integration with Home Assistant
  • Automated backups with Restic
  • Template-based setup - easy to customize for your environment

📦 Included Services

Core Infrastructure

  • Nginx Reverse Proxy - SSL termination with Let's Encrypt (certbot)
  • Pi-hole - Network-wide ad blocking with DNS and IPv6 support
  • Fail2ban - Intrusion prevention with custom filters

Home Automation

  • Home Assistant - Home automation hub
  • Mosquitto - MQTT broker for IoT devices
  • Matter Hub - Matter protocol bridge ⚠️ (Migration to Matterbridge planned - upstream EOL)
  • Music Assistant - Music aggregation service

Media & Documents

  • Immich - Photo and video management with ML features
  • Paperless-ngx - Document management with OCR
  • FreshRSS - RSS feed reader

Vehicle & IoT

  • Teslamate - Tesla vehicle data logging with Grafana dashboards and Home Assistant integration

Monitoring & Automation

  • Backup Scripts - Automated Restic backups with MQTT status reporting
  • Update Monitors - Track Docker image and system updates via MQTT
  • Health Checks - Nginx and system status monitoring

🚀 Quick Start

Prerequisites

  • Raspberry Pi 4/5 or similar ARM64 device (or adapt for x86_64)
  • Docker and Docker Compose installed
  • Domain names configured (for SSL certificates)
  • Basic understanding of Docker and networking

Installation

  1. Clone the repository:

    git clone https://github.com/Spiev/docker-runtime.git
    cd docker-runtime
  2. Configure environment files:

    # Each service directory contains .env.example files
    cd immich
    cp .env.example .env
    # Edit .env with your settings
    
    # Repeat for other services: proxy, paperless, etc.
  3. Configure Home Assistant:

    cd homeassistant/homeassistant/config
    
    # Copy all config templates
    cp configuration.yaml.example configuration.yaml
    cp mqtt.yaml.example mqtt.yaml
    cp templates.yaml.example templates.yaml
    cp command_line.yaml.example command_line.yaml
    
    # Edit each .yaml file: replace placeholders (YOUR_HA_DOMAIN, SENSOR_EUI, etc.)
  4. Setup monitoring scripts:

    cd scripts
    
    # MQTT credentials (for monitoring)
    cp .mqtt_credentials.example .mqtt_credentials
    chmod 600 .mqtt_credentials
    # Edit with your MQTT broker credentials
    
    # Restic backup encryption
    cp .restic.env.example .restic.env
    chmod 600 .restic.env
    # Edit with your backup encryption password
    
    # Production scripts (adjust paths for your setup)
    cp backup-to-hdd.sh.example backup-to-hdd.sh
    chmod +x backup-to-hdd.sh
    
    # Nginx auto-update (pulls Dependabot changes and redeploys)
    cp nginx_update.sh.example nginx_update.sh
    chmod +x nginx_update.sh
    # Edit GIT_REPO_DIR if different from $HOME/docker
  5. Start services:

    # Start individual services
    cd proxy
    docker compose up -d
    
    # Or start all services (adjust as needed)

📂 Repository Structure

├── .github/
│   └── dependabot.yml  # Automated Docker image updates
├── proxy/              # Nginx reverse proxy + Let's Encrypt
├── pihole/             # DNS-based ad blocker
├── homeassistant/      # Home automation stack (config templates: *.yaml.example)
├── immich/             # Photo management
├── paperless/          # Document management
├── freshrss/           # RSS feed reader
├── teslamate/          # Tesla vehicle data logging + Grafana
├── fail2ban/           # Intrusion prevention configs
└── scripts/            # Monitoring and backup automation
    ├── *.example       # Template scripts (tracked in git)
    └── *.sh            # Production scripts (not in git, copy from .example)

🔒 Security Features

SSL/TLS

  • Automatic Let's Encrypt certificate management
  • Multi-domain support with SANs
  • Auto-renewal every 24 hours

Hardening

  • Nginx security headers (HSTS, CSP, X-Frame-Options, etc.)
  • Rate limiting on authentication endpoints
  • Connection limits per IP
  • Service-specific timeouts and upload limits

Fail2ban Protection

  • Custom filters for Nginx auth failures, rate limiting, and scanning
  • Per-service jails (Immich, Paperless, FreshRSS, Home Assistant)
  • Home Assistant special handling: Monitors HA's internal log (HA returns HTTP 200 for failed logins)
  • Recidive jail for repeat offenders
  • DOCKER-USER iptables chain integration

Credential Management

  • All credentials in .env files (excluded from git)
  • Template files (.env.example, .yaml.example) for easy setup
  • Home Assistant configs use .yaml.example suffix to indicate placeholders need customization
  • File permissions enforced (600 for credential files)
  • No hardcoded secrets in scripts

📊 Monitoring

MQTT Integration

Monitoring scripts send status updates to Home Assistant via MQTT:

  • Backup Status - Real-time backup progress and statistics
  • System Updates - Raspberry Pi package and firmware status

Home Assistant Sensors

Scripts automatically create MQTT Discovery sensors:

  • sensor.restic_backup_status - Backup state and metrics
  • sensor.rpi_updates - System update status
  • sensor.nginx_version - Currently installed nginx version
  • sensor.nginx_update_status - Update status (up_to_date, updated, error)
  • sensor.nginx_last_check - When the update script last ran
  • sensor.nginx_last_update - When nginx was last updated

Example automation:

automation:
  - alias: "Backup Failed Alert"
    trigger:
      - platform: state
        entity_id: sensor.restic_backup_status
        to: "failed"
    action:
      - service: notify.mobile_app
        data:
          title: "Backup Failed!"
          message: "Check backup logs immediately"

💾 Backup Strategy

Restic Backups

  • Immich: Backs up photo library including auto-exported database dumps
  • Paperless: Exports PostgreSQL database, then backs up all documents
  • Home Assistant: Backs up configuration files (yaml configs, custom_components) and HA's own backup archives
    • Excludes .storage/ and .cloud/ to avoid permission issues (included in HA backups)
  • Storage: External HDD with encrypted Restic repository
  • Automation: Cron-scheduled with MQTT status reporting

Setup Backup Automation

# Add to crontab
crontab -e

# Daily backup at 2 AM with logging
0 2 * * * /path/to/scripts/backup-to-hdd.sh >> /path/to/logs/backup.log 2>&1

Restore from Backup

Prerequisites:

# Mount backup drive
sudo mount /dev/sda1 /mnt/sda1 -o rw,uid=$UID,user,dmask=007,fmask=117

# Load Restic password
cd ~/docker/scripts
source .restic.env

List available snapshots:

restic -r /mnt/sda1/restic-repo snapshots

Restore Home Assistant:

# Stop Home Assistant
cd ~/docker/homeassistant
docker compose down

# Restore from latest snapshot
restic -r /mnt/sda1/restic-repo restore latest \
  --target /tmp/restore \
  --include '**/homeassistant/homeassistant/config'

# Copy restored files
cp -r /tmp/restore/home/stefan/docker/homeassistant/homeassistant/config/* \
  ~/docker/homeassistant/homeassistant/config/

# For full HA restore: Extract latest backup archive
cd ~/docker/homeassistant/homeassistant/config/backup
tar -xzf <latest-backup>.tar.gz
# Then restore via HA UI: Settings → System → Backups → Upload

# Start Home Assistant
docker compose up -d

# Cleanup
rm -rf /tmp/restore

Restore Immich:

# Stop Immich
cd ~/docker/immich
docker compose down

# Restore from specific snapshot (e.g., snapshot abc123)
restic -r /mnt/sda1/restic-repo restore abc123 \
  --target /tmp/restore \
  --include '**/immich/library'

# Copy restored files
cp -r /tmp/restore/home/stefan/docker/immich/library/* \
  ~/docker/immich/library/

# Start Immich
docker compose up -d

# Cleanup
rm -rf /tmp/restore

Restore Paperless:

# Stop Paperless
cd ~/docker/paperless
docker compose down

# Restore from latest snapshot
restic -r /mnt/sda1/restic-repo restore latest \
  --target /tmp/restore \
  --include '**/paperless/library'

# Copy restored files
cp -r /tmp/restore/home/stefan/docker/paperless/library/* \
  ~/docker/paperless/library/

# Restore database from backup
cd ~/docker/paperless/library/backup
gunzip < paperless_*.sql.gz | docker exec -i paperless-db-1 psql -U paperless

# Start Paperless
docker compose up -d

# Cleanup
rm -rf /tmp/restore

Unmount backup drive:

sudo umount /mnt/sda1

Important Notes:

  • Always test restores regularly to ensure backups are working
  • For Home Assistant: Use HA's backup archives in backup/ directory for full restore
  • Adjust paths (/home/stefan/docker) to match your $DOCKER_BASE
  • Consider restoring to a test directory first to verify data integrity

🔧 Common Operations

SSL Certificate Management

cd proxy

# Force certificate renewal
docker compose run --rm certbot renew --force-renewal

# Check certificate status
docker exec proxy-nginx-1 ls -la /etc/letsencrypt/live/

Service Updates

All Docker images are pinned to specific versions and managed via GitHub Dependabot:

  • Proxy (nginx, certbot): Checked daily (internet-facing, security-critical)
  • All other services: Checked weekly on Sundays

Nginx Auto-Update Workflow:

1. Dependabot creates PR for new nginx version (daily at 03:00)
2. GitHub Action auto-merges minor/patch updates
3. nginx_update.sh (via cron) pulls changes and redeploys
4. Status sent to Home Assistant via MQTT

Setup cron for nginx auto-updates:

crontab -e
# Add: 0 4,8,12,16,20,0 * * * /path/to/scripts/nginx_update.sh >> /path/to/logs/nginx_update.log 2>&1

Other Services (manual deployment):

  1. Dependabot creates PRs when new versions are available
  2. Review changelog and merge PR
  3. Deploy update:
cd <service-directory>
docker compose pull && docker compose up -d

Fail2ban Management

# Check jail status
sudo fail2ban-client status

# Unban IP
sudo fail2ban-client unban <IP_ADDRESS>

# View banned IPs
sudo fail2ban-client banned

Database Management

PostgreSQL Versions:

Service Version Image
Paperless 18 postgres:18
Teslamate 18 postgres:18-alpine
Immich 14 Custom with VectorChord

PostgreSQL 18+ Volume Mount: PostgreSQL 18 uses a version-specific data directory. Mount at /var/lib/postgresql (not /data):

volumes:
  - ./postgres:/var/lib/postgresql  # Creates 18/docker subdirectory

Major Version Upgrade (e.g., 17 → 18):

# 1. Backup
docker exec -t <container> pg_dumpall -U <user> > backup.sql

# 2. Stop and rename old data
docker compose down
mv ./postgres ./postgres_old

# 3. Update docker-compose.yml, then start new DB
docker compose up -d db && sleep 10

# 4. Import and start all
cat backup.sql | docker exec -i <container> psql -U <user>
docker compose up -d

🛠️ Customization

Adapting for Your Environment

  1. Domain Configuration:

    • Update proxy/.env with your domains
    • Modify proxy/nginx/default.conf.template for your services
  2. Script Paths:

    • scripts/backup-to-hdd.sh: Set DOCKER_BASE to your Docker directory
  3. Hardware Dependencies:

    • Home Assistant: Requires Zigbee USB dongle (/dev/ttyACM0)
    • Pi-hole: Requires DNS ports (53), may conflict with systemd-resolved

🤝 Contributing

This is a personal homelab setup, but feel free to:

  • Open issues for questions or suggestions
  • Fork and adapt for your own use
  • Share improvements via pull requests

📝 License

This project is provided as-is for educational and personal use. Adapt as needed for your homelab.

⚠️ Important Notes

  • Security: Review all configurations before exposing to the internet
  • Backups: Test restore procedures regularly
  • Updates: Keep Docker images and system packages up to date
  • Monitoring: Set up alerts for critical services

🔗 Related Resources


Built with ❤️ for the self-hosting community

About

Docker runtime of my private docker instances

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •