Infrastructure as Code repository for managing a self-hosted homelab environment using Ansible for configuration management and Docker Compose for service orchestration.
This project manages 20+ containerized services including media servers, home automation, authentication, monitoring, and productivity tools. All infrastructure is defined as code, version-controlled, and automated for repeatable deployments.
- Infrastructure as Code: All configurations in version control
- Automated Deployment: Ansible playbooks for server setup and maintenance
- Containerized Services: Docker Compose for service isolation and management
- Reverse Proxy: Traefik with automatic SSL/TLS certificates
- Centralized Authentication: Authentik SSO for supported services
- Monitoring: Uptime monitoring and metrics collection
- CI/CD: Automated linting via GitHub Actions
- Configuration Management: Ansible
- Container Orchestration: Docker & Docker Compose
- Reverse Proxy: Traefik
- Operating System: Ubuntu Server
- CI/CD: GitHub Actions
- Ubuntu server (bare metal or VM)
- SSH access with sudo privileges
- Ansible installed on control machine
- Docker and Docker Compose on target hosts
-
Clone the repository:
git clone <repository-url> cd hetzner-lab
-
Configure Ansible inventory:
# Edit your inventory file with target hosts vim inventory/hosts -
Install Docker on target hosts:
ansible-playbook ansible/installation/inst-docker-ubuntu.yaml
-
Deploy services:
# Deploy individual services docker-compose -f docker/traefik/docker-compose.yaml up -d docker-compose -f docker/portainer/docker-compose.yaml up -d
hetzner-lab/
├── ansible/ # Ansible playbooks
│ ├── installation/ # Initial setup scripts
│ ├── maintenance/ # Maintenance tasks
│ ├── mailcow/ # Mailcow operations
│ └── update/ # Update playbooks
├── docker/ # Docker Compose services
│ ├── traefik/ # Reverse proxy
│ ├── authentik/ # SSO & authentication
│ ├── jellyfin/ # Media server
│ ├── paperless-ngx/ # Document management
│ └── ... # 20+ other services
├── .github/
│ ├── instructions/ # Module-level AI Agent instructions
│ └── workflows/ # CI/CD workflows
├── .vscode/
│ └── tasks.json # VS Code automation tasks
└── AGENTS.md # High-level project documentation
- Traefik - Reverse proxy and SSL/TLS management
- Portainer - Docker management UI
- Cloudflared - Cloudflare tunnel
- Semaphore - Ansible UI
- Authentik - Identity provider and SSO
- Vaultwarden - Password manager
- Uptime Kuma - Service uptime monitoring
- InfluxDB - Time-series database
- Homepage - Service dashboard
- Jellyfin - Media streaming server
- Sonarr/Radarr/Prowlarr - Media management (*arr stack)
- Floatplane Downloader - Content downloader
- ESPHome - ESP device management
- EVCC - EV charging controller
- Zigbee2MQTT - Zigbee bridge
- WMBusMeters - Utility meter reader
- Paperless-ngx - Document management
- Mealie - Recipe manager
- FreshRSS - RSS aggregator
- Ghost - Blogging platform
- Immich - Photo backup and management
- Dawarich - Location tracking
- TeamSpeak - Voice communication server
See .github/instructions/services.instructions.md for detailed service documentation.
This project includes 18 VS Code tasks for common operations. Access them via Command Palette → "Tasks: Run Task".
ansible-lint-all- Lint all playbooksansible-syntax-check- Check playbook syntaxansible-run-playbook- Run specific playbookansible-install-docker- Install Docker on Ubuntuansible-maintenance-apt- System updatesansible-maintenance-diskspace- Check disk spaceansible-maintenance-reboot- Check reboot requirementsansible-mailcow-backup- Backup mailcowansible-docker-cleanup- Clean Docker resources
docker-compose-validate- Validate all compose filesdocker-ps- List running containersdocker-services-list- List all servicesdocker-service-up- Start a servicedocker-service-down- Stop a servicedocker-service-restart- Restart a servicedocker-logs- View service logs
yaml-lint- Lint all YAML filesvalidate-all- Run all validation checks
-
Create service directory:
mkdir -p docker/myservice
-
Create
docker-compose.yamlfollowing the patterns in .github/instructions/docker-compose.instructions.md -
Validate configuration:
docker-compose -f docker/myservice/docker-compose.yaml config
-
Deploy:
docker-compose -f docker/myservice/docker-compose.yaml up -d
Weekly maintenance routine:
# Check disk space
ansible-playbook ansible/maintenance/maint-diskspace.yaml
# Update packages
ansible-playbook ansible/update/upd-apt.yaml
# Check if reboot needed
ansible-playbook ansible/maintenance/maint-reboot-required.yamlMonthly cleanup:
# Clean Docker resources
ansible-playbook ansible/maintenance/maint-docker-clean.yaml# Pull latest image
docker-compose -f docker/servicename/docker-compose.yaml pull
# Recreate container
docker-compose -f docker/servicename/docker-compose.yaml up -d
# Check logs
docker-compose -f docker/servicename/docker-compose.yaml logs -fComprehensive documentation is available for different aspects of the project:
- AGENTS.md - Project architecture and workflows
- Ansible Instructions - Playbook patterns and best practices
- Docker Compose Instructions - Service deployment patterns
- Maintenance Instructions - Operational procedures
- Services Catalog - Complete service documentation
- Write idempotent playbooks (safe to run multiple times)
- Use descriptive task names
- Pass
ansible-lintchecks before committing - Test with
--checkmode first - See ansible.instructions.md for details
- One directory per service
- Use named volumes for persistent data
- Configure Traefik labels for web services
- Set restart policy to
unless-stopped - Validate with
docker-compose config - See docker-compose.instructions.md for patterns
- Never commit secrets to repository
- Use Ansible Vault for sensitive data
- Use environment files (add to
.gitignore) - Implement proper network isolation
- Enable Authentik SSO where supported
This project is configured for AI Agent assistance. Enable these VS Code settings:
github.copilot.chat.codeGeneration.useInstructionFiles→truechat.useAgentsMdFile→true
# Lint Ansible playbooks
ansible-lint ansible/
# Validate Docker Compose files
find docker/ -name 'docker-compose.y*ml' -exec docker-compose -f {} config -q \;
# Check Ansible syntax
find ansible/ -name '*.y*ml' -exec ansible-playbook --syntax-check {} \;GitHub Actions automatically runs ansible-lint on all pull requests and pushes to main branch.
- Vaultwarden (passwords)
- Paperless-ngx (documents)
- Immich (photos)
- Authentik (user data)
- Jellyfin (library metadata)
- *arr stack (configurations)
- ESPHome (device configs)
- Zigbee2MQTT (device pairings)
See maintenance.instructions.md for complete backup strategy.
- Check Traefik labels in docker-compose.yaml
- Verify service is on
traefik_proxynetwork - Check Traefik logs:
docker logs traefik - Verify DNS configuration
- Check inventory and connectivity:
ansible all -m ping - Verify SSH access and sudo permissions
- Run with verbose output:
ansible-playbook -vvv playbook.yaml - Check syntax:
ansible-playbook --syntax-check playbook.yaml
- Check usage:
ansible-playbook ansible/maintenance/maint-diskspace.yaml - Clean Docker:
ansible-playbook ansible/maintenance/maint-docker-clean.yaml - Review logs:
journalctl --vacuum-time=7d
- Fork the repository
- Create a feature branch
- Make changes following the project guidelines
- Test changes locally
- Run validation tasks
- Submit a pull request
[Specify your license here]
For issues and questions:
- Review documentation in
.github/instructions/ - Check AGENTS.md for architectural guidance
- Consult service-specific documentation
Note: This is a self-hosted infrastructure project. Ensure proper security measures, regular backups, and monitoring are in place before deploying to production.