- Jinja 78.7%
- Python 12.5%
- Shell 8.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
CI - Validate & Test / Validate YAML Syntax (push) Successful in 23s
CI - Validate & Test / Validate Ansible Playbooks (push) Successful in 11m16s
CI - Validate & Test / Validate Docker Compose Files (push) Successful in 4s
CI - Validate & Test / Security Scan (push) Successful in 3s
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSFt3Gh4sEYgS6CAfk8h6QaohXshAUCaqrYzAAKCRA8h6QaohXs hNIDAPwM/jE4dr71ZsPbk04UjFLTvfQ4IOVb5MVJoInT0XhxYgD/fZB9/V1qD06W KGT8XvJBbUX1SNjlN3uQd5a15KGhQAQ= =tDSx -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSFt3Gh4sEYgS6CAfk8h6QaohXshAUCaqrYzQAKCRA8h6QaohXs hLDSAP9hvyVDNGWYXHQRiqNbwCv2QdHPA8Mpqgk2xlEtYPAl6QD8DY9gFO6Wy1jx ibm0ODijWnQt/1VeQ2lgi56RB4z4QAM= =4Vcc -----END PGP SIGNATURE----- Merge tag '0.12.1' into develop fix: alloy service |
||
| .forgejo/workflows | ||
| ansible | ||
| compose | ||
| scripts | ||
| .ansible-lint | ||
| .gitignore | ||
| .yamllint | ||
| CHANGELOG.md | ||
| README.md | ||
PX Homelab Infrastructure
GitOps-managed homelab infrastructure running on a Proxmox cluster with automated LXC container provisioning and service deployment using Ansible and Forgejo Actions.
Overview
This project provides a complete Infrastructure-as-Code solution for managing a homelab environment. It automates the deployment of LXC containers across multiple Proxmox nodes and orchestrates Docker-based services including authentication, media streaming, monitoring, downloads, and development tools.
Key Features:
- Infrastructure-as-Code with Ansible
- CI/CD with Forgejo Actions
- Git Flow workflow for version management
- Secrets management with Ansible Vault
- Automated container provisioning and service deployment
- Monitoring and observability stack
- Reverse proxy with Traefik and automatic SSL
Architecture
The infrastructure is distributed across three Proxmox nodes:
Proxmox Node 01 - Core Services
- reverse-proxy (Traefik) - Ingress controller with automatic SSL via Let's Encrypt
- auth (Authentik) - Identity provider and SSO
- vaultwarden - Password manager
- immich - Photo and video management (with GPU acceleration)
- uptime-kuma - Uptime monitoring
- reelport - Application monitoring with Grafana Alloy
- opencloud-vm (VM) - Nextcloud instance
Proxmox Node 02 - Media Services
- downloads - Download automation (*arr stack)
- media - Media management (Jellyfin, Radarr, Sonarr, Bazarr, Prowlarr, FlareSolverr, Seerr)
Proxmox Node 03 - Monitoring & Development
- monitoring - Observability stack (Prometheus, Grafana, InfluxDB, Alertmanager)
- forgejo - Self-hosted Git service
- development-vm (VM) - Development environment
Project Structure
px-homelab/
├── ansible/ # Ansible automation
│ ├── deploy-lxc-containers.yml # LXC container provisioning
│ ├── deploy-services.yml # Service deployment (Docker)
│ ├── inventory.ini # Hosts and groups
│ ├── requirements.yml # Ansible collections
│ ├── requirements.txt # Python dependencies
│ ├── group_vars/ # Group variables
│ │ ├── all/ # Variables for all hosts
│ │ │ ├── main.yml # Container definitions & defaults
│ │ │ └── vault.yml # Encrypted secrets
│ │ ├── proxmox_nodes/ # Variables for proxmox nodes
│ │ ├── lxc_containers/ # Variables for lxc containers
│ │ └── vms/ # Variables for vms
│ ├── host_vars/ # Host-specific encrypted variables
│ │ ├── auth/vault.yml
│ │ ├── downloads/vault.yml
│ │ ├── forgejo/vault.yml
│ │ ├── immich/vault.yml
│ │ ├── media/vault.yml
│ │ ├── monitoring/vault.yml
│ │ ├── opencloud/vault.yml
│ │ └── vaultwarden/vault.yml
│ ├── roles/ # Ansible roles
│ │ ├── docker/ # Docker installation
│ │ ├── alloy/ # Grafana Alloy setup
│ │ ├── vector/ # Vector log collector setup
│ │ └── pihole_dns/ # Pi-hole DNS configuration
│ └── templates/ # Jinja2 templates for .env files
│ ├── proxmox-node01/
│ ├── proxmox-node02/
│ └── proxmox-node03/
├── compose/ # Docker Compose configurations
│ ├── proxmox-node01/ # Services for node 01
│ │ ├── auth/
│ │ ├── immich/
│ │ ├── opencloud/
│ │ ├── reelport/
│ │ ├── reverse-proxy/
│ │ │ ├── docker-compose.yml
│ │ │ ├── traefik.yml # Traefik static config
│ │ │ └── dynamic/ # Dynamic routing rules
│ │ ├── uptime-kuma/
│ │ └── vaultwarden/
│ ├── proxmox-node02/ # Services for node 02
│ │ ├── downloads/
│ │ └── media/
│ └── proxmox-node03/ # Services for node 03
│ ├── forgejo/
│ │ ├── docker-compose.yml
│ │ └── init.d/ # Pre-deployment scripts
│ └── monitoring/
│ ├── docker-compose.yml
│ └── prometheus/
│ └── prometheus.yml
├── scripts/ # Utility scripts
│ ├── fs_storage_to_volumes.sh
│ └── generate-unused-mac.py
├── .forgejo/
│ └── workflows/ # CI/CD pipelines
│ ├── ci.yml # Validation and linting
│ ├── dry-run.yml # Test deployments
│ ├── deploy-lxc-containers.yml
│ └── deploy-services.yml
│ └── deploy-vector.yml
└── docs/ # Documentation (empty)
Ansible Playbooks
1. deploy-lxc-containers.yml
Provisions and configures LXC containers on Proxmox hosts.
What it does:
- Validates mount paths exist on Proxmox hosts
- Downloads required LXC templates (Debian 12)
- Creates LXC containers with specified resources (CPU, RAM, disk)
- Configures networking with static IPs
- Sets up mount volumes (bind mounts from host)
- Configures privileged/unprivileged containers
- Registers containers with Pi-hole DNS
- Starts containers
Usage:
# Deploy all containers
ansible-playbook -i ansible/inventory.ini ansible/deploy-lxc-containers.yml
# Deploy specific containers
ansible-playbook -i ansible/inventory.ini ansible/deploy-lxc-containers.yml \
--extra-vars '{"containers": "auth,vaultwarden"}'
Key Features:
- Selective deployment with
containersvariable - Idempotent operations (safe to re-run)
- Unprivileged containers by default (security)
- GPU passthrough support (for Immich hardware transcoding)
- Automatic DNS registration
Required Environment Variables:
PROXMOX_USER- Proxmox API userPROXMOX_TOKEN_ID- API token IDPROXMOX_TOKEN_SECRET- API token secretPROXMOX_ROOT_TOKEN_ID- Root token (for privileged containers)PROXMOX_ROOT_TOKEN_SECRET- Root token secret
2. deploy-services.yml
Deploys Docker-based services to LXC containers.
What it does:
- Installs Docker using the
dockerrole - Syncs Docker Compose files from
compose/directory - Templates
.envfiles fromansible/templates/ - Runs initialization scripts from
init.d/directory (if present) - Deploys services with
docker compose - Pulls latest images
- Removes orphaned containers
- Prunes unused Docker images
Usage:
# Deploy all services
ansible-playbook -i ansible/inventory.ini ansible/deploy-services.yml
# Deploy specific services
ansible-playbook -i ansible/inventory.ini ansible/deploy-services.yml \
--extra-vars '{"services": "auth,vaultwarden"}'
Key Features:
- Selective deployment via
servicesvariable - Automatic Docker installation if not present
- File synchronization with
rsync - Secret management via templated
.envfiles - Pre-deployment hooks via
init.d/scripts - Container lifecycle management
Forgejo Workflows
1. ci.yml - Continuous Integration
Trigger: Pull requests and pushes to main/develop branches
Jobs:
- validate-yaml: Lints YAML files with
yamllint - validate-ansible: Syntax checks Ansible playbooks
- validate-docker-compose: Validates all Docker Compose files
- security-scan: Scans for hardcoded secrets
2. deploy-lxc-containers.yml - Container Deployment
Trigger:
- Git tags (e.g.,
v1.0.0) - Manual dispatch
Workflow:
- Prepare: Generates deployment ID and determines containers to deploy
- Deploy:
- Sets up Python environment
- Installs Ansible and collections
- Configures SSH keys
- Runs
deploy-lxc-containers.ymlplaybook - Notifies deployment status
Environment Variables:
production(default)- Configurable via workflow dispatch
Inputs:
containers: Comma-separated list (optional, defaults toall)
3. deploy-services.yml - Service Deployment
Trigger:
- Successful completion of
deploy-lxc-containers.yml - Manual dispatch
Workflow:
- Check Prerequisites: Verifies LXC deployment succeeded
- Prepare: Generates deployment ID and determines services to deploy
- Deploy:
- Sets up Python environment
- Installs Ansible and collections
- Configures SSH keys
- Prepares Ansible Vault password
- Runs
deploy-services.ymlplaybook - Creates deployment summary
Inputs:
services: Comma-separated list (optional, defaults toall)skip_on_lxc_failure: Skip if triggered by failed LXC deployment (default:true)
4. dry-run.yml - Test Deployment
Trigger: Manual dispatch only
Purpose: Validates deployment without making changes (Ansible check mode)
Workflow:
- Runs
deploy-services.ymlwith--checkflag - Perfect for testing changes before actual deployment
Deployment Guide
Prerequisites
-
Proxmox Cluster
- 3 nodes with SSH access
- API tokens configured
- Storage configured (
local-lvmfor containers)
-
Local Environment
- Python 3.12+
- Ansible 2.15+
- SSH key for Proxmox access
-
Forgejo Secrets (for CI/CD)
SSH_PRIVATE_KEY- SSH key for Proxmox accessANSIBLE_USER- SSH usernameANSIBLE_VAULT_PASSWORD- Ansible Vault passwordPROXMOX_USER,PROXMOX_TOKEN_ID,PROXMOX_TOKEN_SECRETPROXMOX_ROOT_TOKEN_ID,PROXMOX_ROOT_TOKEN_SECRET
Local Deployment
- Install Dependencies
cd ansible
pip install -r requirements.txt
ansible-galaxy collection install -r requirements.yml
- Configure Secrets
# Create vault password file
echo "your-vault-password" > secrets.pass
chmod 600 secrets.pass
# Edit vault files
ansible-vault edit --vault-password-file secrets.pass ansible/group_vars/all/vault.yml
- Deploy Containers
ansible-playbook -i ansible/inventory.ini ansible/deploy-lxc-containers.yml \
--vault-password-file secrets.pass
- Deploy Services
ansible-playbook -i ansible/inventory.ini ansible/deploy-services.yml \
--vault-password-file secrets.pass
CI/CD Deployment
This project follows Git Flow guidelines for version management and deployments.
- Full Deployment: Finish a Git Flow release
# Create a new release branch
git flow release start 1.0.0
# Make final adjustments, update CHANGELOG.md
git add .
git commit -m "Prepare release 1.0.0"
# Finish the release (creates tag and pushes automatically)
git flow release finish 1.0.0
git push origin main develop --tags
This automatically triggers the deployment pipeline when the tag is pushed.
-
Selective Deployment: Use workflow dispatch
- Go to Actions → Deploy services
- Click "Run workflow"
- Specify services to deploy (or leave empty for all)
-
Test Changes: Use dry-run workflow
- Go to Actions → Dry Run Deployment
- Click "Run workflow"
- Review output for validation
Development
Git Flow Workflow
This project follows Git Flow for branch management:
- main - Production-ready code
- develop - Integration branch for features
- feature/ - New features (branch from develop)
- release/ - Release preparation (branch from develop)
- hotfix/ - Emergency fixes (branch from main)
Development Process:
# Start a new feature
git flow feature start my-new-feature
# Work on your feature
git add .
git commit -m "Add new feature"
# Finish feature (merges to develop)
git flow feature finish my-new-feature
# Create a release when ready
git flow release start 1.1.0
# Finish release (merges to main and develop, creates tag)
git flow release finish 1.1.0
Adding a New Service
- Create directory structure:
mkdir -p compose/proxmox-nodeXX/service-name
- Add
docker-compose.yml - Add entry to
ansible/inventory.ini - Create
.env.j2template inansible/templates/ - Add encrypted variables in
ansible/host_vars/service-name/vault.yml - Deploy and test
Ansible Roles
docker Role
Installs Docker CE and Docker Compose plugin on Debian-based systems.
Tasks:
- Updates apt cache
- Adds Docker's GPG key and repository
- Installs Docker packages
- Starts and enables Docker service
pihole_dns Role
Registers LXC containers with Pi-hole DNS for local name resolution.
Purpose: Enables accessing services via hostnames (e.g., auth.pxlab)
Monitoring
Access monitoring services:
- Grafana:
http://monitoring.pxlab:3000 - Prometheus:
http://monitoring.pxlab:9090 - Uptime Kuma:
http://uptime.pxlab:3001 - Traefik Dashboard:
http://traefik.pxlab:8080
Security
- Secrets stored in Ansible Vault (encrypted)
- Unprivileged LXC containers by default
- Forgejo Actions secrets for CI/CD
- Automatic security scanning in CI pipeline
- SSL certificates via Let's Encrypt