Proxmox-GitOps: Recursive GitOps Environment for Container Automation in Proxmox

3 months ago 3

Build Status

Proxmox GitOps implements a self-sufficient, extensible CI/CD environment for provisioning, configuring, and orchestrating Linux Containers (LXC) within Proxmox VE. Leveraging an Infrastructure-as-Code (IaC) approach, it manages the entire container lifecycle—bootstrapping, deployment, configuration, and validation—through version-controlled automation.

The architecture is based on a multi-stage pipeline capable of recursively deploying and configuring itself.

Concept

Initial bootstrapping is performed via a local Docker environment, with subsequent deployments targeting Proxmox VE. This ensures consistent, reproducible, and automated infrastructure management.

  • Configure credentials and Proxmox API token in local/.config.json as config.json
  • Run local/run.sh for local Docker environment
  • Accept the Pull Request to deploy on Proxmox VE

Pipeline

Reusable container definitions are stored in the libs folder. Copy an example container (like libs/broker or libs/proxy) as a template, or create a new container lib from scratch and follow these steps:

  • Add config.env to your container's root directory, e.g.:
IP=192.168.178.42 ID=42 HOSTNAME=apache CORES=2 MEMORY=2048 SWAP=512 DISK=local-lvm:8 BOOT=yes
  • Paste generic pipeline in gitea/workflows:
on: workflow_dispatch: push: branches: [ release, main, develop ] jobs: include: runs-on: shell steps: - id: init uses: srv/config/.gitea/workflows@main with: repo: ${{ gitea.repository }} ref: ${{ gitea.ref_name }} cache_bust: ${{ gitea.run_number }}
  • Add your cookbook to the container definition root:
# ./libs/apache/recipes/default.rb package 'apache2' service 'apache2' do action [:enable, :start] end file '/var/www/html/index.html' do content "<h1>Hello from #{Env.get(node, 'login')}</h1>" mode '0644' owner 'app' # see base/roles/base/tasks/main.yml group 'app' # each container is configured identically end
  • Optionally, use Env.get() and Env.set() to access Gitea environment variables.

  • a) Deploy: Push to the release branch of a new repository

  • b) Add to Meta-/Mono-Repository: Add path to repositories and redeploy Proxmox-GitOps

The container can be tested locally running ./local/run.sh [container]

Local Development

  • Docker
  • Proxmox VE
  • Proxmox API token
  • See Wiki for recommendations
  • During configuration, the codebase is pushed into a Gitea instance running inside the container
  • This triggers the same pipeline from within the new environment, enabling recursive configuration ("pipeline within a pipeline")
  • Subsequent runs are idempotent: Ansible and Chef validate and enforce the desired state using static configuration

Repositories

  • Self-Managed Infrastructure: The system provisions, configures, and verifies itself recursively
  • Container Provisioning: Managed by Ansible using the Proxmox API
  • Container Configuration: Managed by cookbooks for application-level setup
  • CI/CD Orchestration: Execution is handled by a Runner automatically installed inside the container
  • Environment Management: Environment variables are initially loaded from config.json and recursively propagated into the GitOps system
  • Modularity: Distinct components and modular reusable workflows managed within Gitea, facilitating extension
Read Entire Article