This repository provides a complete infrastructure automation solution using Ansible AWX and Docker to deploy and manage self-hosted services including reverse proxy, monitoring, torrenting, and dynamic DNS.
- Automated Deployments: Ansible playbooks for consistent, repeatable infrastructure setup
- Service Integration: Traefik reverse proxy with automatic SSL certificates
- Monitoring Stack: Prometheus, Grafana, and cAdvisor for complete observability
- Security: VPN-protected torrenting and secure service isolation
- Dynamic DNS: Cloudflare integration for automatic domain updates
- AWX Integration: Enterprise-grade automation platform support
Contains Ansible playbooks executed by AWX.
Subfolders:
- configuration-management/
Contains playbooks for deploying Docker services (Traefik, monitoring stack, Cloudflare DDNS, etc.) - connection-check/
Contains ping tests and connectivity validation. - update-management/
Contains OS update playbooks (Ubuntu, Debian, CentOS, OpenWRT).
Note: Inventories, credentials, and variables are managed inside AWX and not stored in this repository.
Docker Compose stacks for infrastructure services.
-
traefik/
Reverse proxy with automatic SSL, service discovery, and dynamic routing.
Ports: 80, 443 -
monitoring-stack/
Prometheus, Grafana, and cAdvisor for metrics collection and visualization.
Ports: 9090 (Prometheus), 3000 (Grafana), 9222 (cAdvisor) -
cloudflare-ddns/
Automated DNS updates using Cloudflare API.
Background service, no exposed ports -
qbittorrent/
Torrent client with integrated WireGuard VPN for secure downloading.
Port: 8080 (Web UI through VPN)
- Push changes to this repository.
- AWX project auto-syncs from GitHub.
- Run the appropriate AWX job template:
- Deploy Traefik
- Deploy Monitoring Stack
- Deploy Cloudflare DDNS
- Playbook will:
- Copy the stack files to
/opt/services/<stack_name> - Pull updated Docker images
- Restart containers using
docker-compose up -d
- Copy the stack files to
The system ensures idempotent deployments β running the same template again updates the service.
- Cloudflare Account: Active Cloudflare account with domain management
- Domain Configuration:
- Domain added to Cloudflare with DNS management enabled
- DNS A record pointing to your server's public IP (will be updated automatically by Cloudflare-DDNS container)
- DNS A records for internal services pointing to your Traefik server's private IP address
- Cloudflare API token with DNS edit permissions (required for automatic SSL certificates)
- Linux Host with:
- Docker Engine
- Docker Compose plugin
- Local DNS Server: Internal DNS server (Pi-hole, AdGuard Home, or similar) for resolving internal service domains
- AWX instance with:
- Git connection to this repository
- SSH credentials for remote nodes
- Optional environment variables (Cloudflare token)
Before deploying, you'll need to configure several files for your specific infrastructure. Here's what needs to be customized:
Create this file with your Cloudflare credentials:
CF_API_EMAIL=your-email@example.com
CF_AUTH_METHOD=token
CF_API_KEY=your-cloudflare-api-token
CF_ZONE_ID=your-zone-id
CF_RECORD=your-domain.com
CF_TTL=3600
CF_PROXY=trueCLOUDFLARE_DNS_API_TOKEN=your-cloudflare-dns-api-tokenUpdate all domain names from mdcloud.org to your domain:
pihole.mdcloud.orgβpihole.yourdomain.comgrafana.mdcloud.orgβgrafana.yourdomain.comprometheus.mdcloud.orgβprometheus.yourdomain.com- etc.
Update IP addresses to match your network:
192.168.1.100β Your OMV server IP192.168.1.101β Your Pi-hole server IP192.168.1.102β Your Jellyfin server IP- etc.
Update all IP addresses and host labels:
- targets: ['YOUR_IP:9100']
labels:
host: 'Your-Host-Name'Create .env file with your VPN provider credentials:
VPN_SERVICE_PROVIDER=custom
VPN_TYPE=wireguard
WIREGUARD_PRIVATE_KEY=your-private-key
WIREGUARD_ADDRESSES=your-vpn-ip/32
WIREGUARD_ENDPOINT_IP=vpn-server-ip
WIREGUARD_ENDPOINT_PORT=vpn-port
WIREGUARD_PUBLIC_KEY=vpn-public-keyUpdate the download path to match your storage:
- /your/nfs/share/path:/downloads- Change default passwords for all services
- Use strong API tokens with minimal required permissions
- Configure firewall rules for exposed ports
- Regularly rotate credentials and API keys
-
Configure Domain & DNS:
- Add your domain to Cloudflare
- Create A record pointing to your server's public IP
- Generate Cloudflare API token with DNS permissions
- Wait for DNS propagation (may take 5-30 minutes)
-
Configure Infrastructure: Customize all configuration files for your environment (see Infrastructure Configuration section below)
-
Setup AWX Project pointing to this repository
-
Configure Inventory with your target hosts
-
Deploy Core Services:
- Run "Deploy Traefik" β Access at
https://your-domain.com - Run "Deploy Monitoring Stack" β Access at
https://your-domain.com/grafana
- Run "Deploy Traefik" β Access at
-
Deploy Additional Services as needed
After deployment, the following services will be available:
| Service | URL | Purpose | Default Credentials |
|---|---|---|---|
| Grafana | https://grafana.your-domain.com/ or http://server:3000 |
Monitoring dashboards | |
| Prometheus | https://prometheus.your-domain.com/ or http://server:9090 |
Metrics collection | |
| qBittorrent | http://torrent.your-domain.com or http://server:8080 |
Torrent management |
Note: URLs assume Traefik routing rules are configured in dynamic.yml
- Create a Project pointing to this repo.
- Assign:
- inventory
- SSH credentials
- extra variables (if required)
- Create Job Templates for each playbook.
- Run or schedule deployments.
- System Updates: Run OS-specific update playbooks weekly
- Container Updates: Execute
update_docker_deployments.ymlmonthly - SSL Certificates: Automatically renewed by Traefik/ACME
- Docker volumes in
/opt/services/*/config - Grafana dashboards and data sources
- qBittorrent configuration and torrent data
- Port conflicts: Check
netstat -tulpnon target hosts - Configuration errors: Verify all IP addresses and domains are updated in configuration files
- DNS not resolving: Wait for DNS propagation (5-30 minutes) after adding domain to Cloudflare
- SSL certificate failures: Verify Cloudflare API token and DNS settings; ensure domain points to correct IP
- Service unreachable: Check Traefik logs and routing rules; verify IP addresses in dynamic.yml
- VPN issues: Validate WireGuard configuration in qbittorrent stack
- Environment variables missing: Check that all required .env files are created and populated
# Check service status
docker-compose -f /opt/services/traefik/docker-compose.yml ps
# View recent logs
docker-compose -f /opt/services/monitoring-stack/docker-compose.yml logs --tail=50
# Restart specific service
docker-compose -f /opt/services/cloudflare-ddns/docker-compose.yml restart- No inventory files are stored in this repository β AWX manages hosts and credentials
- Environment variables in
.envfiles can be overridden by AWX credentials for security - Service isolation β each Docker stack runs under
/opt/services/<stack_name>on target servers - Idempotent operations β all playbooks are safe to re-run for updates
When adding new services:
- Create Docker stack in
docker/directory - Add corresponding Ansible playbook in
ansible/playbooks/configuration-management/ - Update this README with service details
- Test deployment in staging environment first
For questions or issues, please check the troubleshooting section above or create an issue in this repository.