A self-hosted media automation stack built with Docker Compose. This project provides a complete solution for managing, downloading, and streaming your personal media library with VPN protection, reverse proxy, and monitoring.
Support the project:
| Application | Description |
|---|---|
| Traefik | Reverse proxy with automatic HTTPS and SSL certificates |
| Gluetun | VPN client with kill-switch for secure downloads |
| Komodo | Stack deployment orchestration across servers |
| Homepage | Dashboard to access all services |
| Application | Description |
|---|---|
| Sonarr | TV show library management and downloads |
| Radarr | Movie collection management |
| Bazarr | Automatic subtitle downloads |
| Prowlarr | Indexer manager for all arr apps |
| Autobrr | Torrent automation based on filters |
| Application | Description |
|---|---|
| qBittorrent | Torrent client (runs behind VPN) |
| SABnzbd | Usenet downloader |
| NZBGet | Alternative usenet client |
| Flood | Modern web UI for torrent management |
| Application | Description |
|---|---|
| Jellyfin | Self-hosted media server |
| Application | Description |
|---|---|
| Recommendarr | Content recommendations based on your library |
| Monitarr | Arr stack health monitoring |
| Huntarr | Advanced media search |
| Profilarr | Quality profile management |
| Unpackerr | Automatic archive extraction |
| FlareSolverr | Cloudflare bypass for indexers |
| Jackett | Legacy indexer proxy |
| Application | Description |
|---|---|
| Node Exporter | System metrics collection |
| cAdvisor | Container resource monitoring |
| Vector | Log and metrics aggregation |
| Exportarr | Prometheus exporters for arr apps |
For detailed setup instructions, configuration examples, and deployment strategies:
The Modern Media Homelab: Docker Stacks Deployed with GitHub Actions & Komodo
- Proxmox VE 8.x
- Ansible 2.15+ with collections:
community.general,ansible.posix - Ansible roles:
geerlingguy.docker,geerlingguy.pip - Doppler account for secrets management
- GitHub repository with Actions enabled
# On Proxmox host - create the cloud-init template
cd proxmox
export VM_ID=8011
export VM_NAME="debian-13-cloudinit-template"
export STORAGE="local-lvm"
export MEMORY=1024
export CORES=1
export DISK_SIZE=32G
export CLEARTEXT_PASSWORD="your-password"
./debian13-template.sh
# Clone template to create your VM
export TEMPLATE_ID=8011
export STORAGE=local-lvm
export MEMORY=8192
export CORES=4
export SECOND_DISK_SIZE=100G
export SECOND_DISK_STORAGE=local-lvm
./debian13-vm.sh <VM_ID> <VM_NAME> <IP_LAST_OCTET>
# Example: ./debian13-vm.sh 552 "hl-media" 191cd ansible
# Install required roles
ansible-galaxy install -r requirements.yml
# Create vault for secrets
ansible-vault create group_vars/vault.yml
# Run playbooks
ansible-playbook -i inventory/hosts.ini playbooks/main.yml --ask-vault-pass
ansible-playbook -i inventory/hosts.ini playbooks/github-runner.yml --ask-vault-pass
ansible-playbook -i inventory/hosts.ini playbooks/backrest-setup.yml --ask-vault-passPlaybooks:
main.yml- System updates, Docker, ZSH, Neovim, LVM storage, Webmin, SSH bannergithub-runner.yml- Self-hosted GitHub Actions runnerbackrest-setup.yml- Backrest backup service with rsync.net
Setup Doppler project with your secrets synced to GitHub repository secrets:
- VPN credentials (ProtonVPN)
- API keys for all services
- Cloudflare credentials
- Domain configuration
The workflow triggers on merged PRs to main and runs on your self-hosted runner:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ lint-and-test │────▶│ security-scan │────▶│ deploy │
│ (ubuntu-latest)│ │ (hl-media) │ │ (hl-media) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
Pre-commit TruffleHog Deploy stacks
Action lint secret scan
Deploy job steps:
- Setup SSH and sync repository
- Configure Doppler CLI with tokens
- Create directories (
/data/homelab/traefik,/data/homelab/komodo) - Generate
.envfiles from Doppler secrets - Create
proxyDocker network (172.18.0.0/16) - Deploy Traefik stack (reverse proxy & SSL)
- Deploy Komodo stack (infrastructure management)
Access services through your configured domain or Homepage dashboard
This stack uses Gluetun with ProtonVPN and port forwarding enabled. All torrent traffic routes through the VPN with a kill-switch to prevent IP leaks.
Configuration is in docker/arr-stack/docker-compose.env:
VPN_SERVICE_PROVIDER=protonvpn
VPN_TYPE=openvpn
VPN_PORT_FORWARDING=on
VPN_PORT_FORWARDING_PROVIDER=protonvpn
SERVER_COUNTRIES="United States"You need to add your ProtonVPN credentials in docker/arr-stack/.env:
OPENVPN_USER=your_protonvpn_username
OPENVPN_PASSWORD=your_protonvpn_passwordThe port forwarding command automatically updates qBittorrent's listening port when it changes.
Traefik handles all routing using a base domain. Configure your domain in docker/traefik/.env:
MEDIA_DOMAIN=media.yourdomain.comServices are accessible at subdomains:
traefik.media.yourdomain.com- Traefik dashboardsonarr.media.yourdomain.com- Sonarrradarr.media.yourdomain.com- Radarrprowlarr.media.yourdomain.com- Prowlarrqbittorrent.media.yourdomain.com- qBittorrentjellyfin.media.yourdomain.com- Jellyfin
DNS Setup:
- Point a wildcard DNS record (
*.media.yourdomain.com) to your server's IP - Or create individual A records for each service subdomain
- Traefik automatically handles SSL certificates via Let's Encrypt
homelab-media-stack/
├── ansible/ # Server provisioning playbooks
├── docker/
│ ├── arr-stack/ # Media automation containers
│ │ ├── docker-compose.vpn.yml # VPN + qBittorrent + Prowlarr
│ │ ├── docker-compose.arrs.yml # Sonarr, Radarr, Bazarr
│ │ ├── docker-compose.downloaders.yml # SABnzbd, NZBGet, Flood
│ │ ├── docker-compose.jellyfin.yml # Media server
│ │ ├── docker-compose.extended.yml # Additional tools
│ │ └── docker-compose.autobrr.yml # Autobrr + Postgres
│ ├── traefik/ # Reverse proxy configuration
│ ├── komodo/ # Deployment orchestration
│ ├── homepage/ # Dashboard
│ ├── filemanager/ # FileBrowser, Filerise
│ └── observability/ # Monitoring stack
├── .github/workflows/ # CI/CD automation
└── proxmox/ # VM templates
Contributions are welcome. If you find a bug or have an improvement:
- Fork the repository
- Create a feature branch
- Submit a pull request
Please open an issue first to discuss significant changes.
This project is intended for educational purposes only.
Neither the author nor the developers of the code in this repository condone or encourage downloading, sharing, seeding, or peering of copyrighted material.
Such activities are illegal under international laws.
The software and configurations provided are for learning about self-hosted infrastructure, Docker containerization, and home network automation. Users are solely responsible for ensuring their use of this software complies with all applicable laws in their jurisdiction.


