Framework
stevius10/Proxmox-GitOps avatar
stevius10/Proxmox-GitOps

Proxmox-GitOps: GitOps for LXC containers on Proxmox VE

IaC Automation Framework for Linux Containers (LXC) on Proxmox VE.

596 stars29 forksRubyMIT

At a glance

What is it?
Proxmox-GitOps turns a monorepository of Git submodules into a self-contained environment that provisions Linux Containers on Proxmox VE, bootstrapping in a local Docker environment and then deploying itself. The README is unusually candid about the cost of that design, and the Proxmox 9 API token restriction is the sharpest edge in it.
Who is it for?
Proxmox-GitOps fits a team that runs its own Proxmox cluster, wants container configuration to live in Git with a pull request as the review gate, and accepts that the framework deploys itself. It is the wrong choice if you cannot run privileged containers as root on Proxmox 9, because the documented behaviour is that root user-based API access takes precedence over token-based authentication.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A monorepository that provisions itself

The repository description calls Proxmox-GitOps an IaC Automation Framework for Linux Containers (LXC) on Proxmox VE, and the Overview explains what that means in practice. It implements a self-contained GitOps environment for provisioning and orchestrating Linux Containers on Proxmox VE, encapsulating infrastructure within an extensible monorepository that is recursively resolved from Git submodules at runtime, providing an Infrastructure-as-Code abstraction for an entire automated container-based infrastructure.

The phrase that carries the weight is recursively resolved from Git submodules at runtime. The infrastructure is not one repository, it is a tree of them, and the tree is assembled when the framework runs rather than when you clone it. That is what makes the self-containment claim possible, because a container can be described in terms of other containers, and the resolution of those references happens at deploy time.

The project site is demo.gitops.pm, and the primary language is Ruby, with the licence MIT. The default branch is `develop` rather than `main`, and the README carries build badges for both, which tells you the project works on a trunk with a release branch, or the other way round, and that the two are tested separately.

The audience is a team that runs Proxmox for its own infrastructure and wants the container definitions in Git with a review step in front of every change.

Bootstrapping in Docker, then deploying to Proxmox

The deployment model has two stages, and the Architecture section states them plainly: initial bootstrapping is performed via a local Docker environment, with subsequent deployments targeting Proxmox VE.

The Usage section walks through the configuration you have to do first. You set the Proxmox VE configuration and authorization in `./local/config.json`, you ensure the centralized environment configuration is in `globals.json`, and you adjust the container resource allocation in `container.env`. Then you run `./local/run.sh` to spin up the local Docker environment.

From there the flow is a pull request. You accept the Pull Request at `http://localhost:8080/main/config` to deploy Proxmox-GitOps on Proxmox VE, from which the deployment of the respective container library can then be triggered in the same way. There is also an automatic path: if `AUTO_DEPLOY` is set to `true` in `globals.json`, it will automatically deploy Proxmox-GitOps and the container libraries to PVE.

That review gate is the point of the whole design. The configuration change is a diff in a repository, a human approves it, and the approval is the trigger for infrastructure change. Setting `AUTO_DEPLOY` removes the human, which is the configuration you would use once you trust the pipeline.

The requirements are short and worth noting exactly: Docker, Proxmox VE 8.4 to 9.2, and the README points to a Getting Started document and the project wiki for recommendations.

Four concepts, and one of them explains why there is Ruby here

The Core Concepts table sets out four ideas with the reasoning attached, and the reasoning is more useful than the labels.

Desired State is the monorepository as a single source of truth representing the entire infrastructure state, justified as a deterministic bootstrap from code over version history. Self-Containment is the composite monorepository being pushed to a local container, which triggers a pipeline that provisions onto Proxmox, justified as fully automated infrastructure deployment mirroring local development.

Dynamic Configuration is the interesting one. It uses imperative logic, for example `config/recipes/repo.rb`, for dynamic, cross-layer state management, and the stated reason is that a declarative approach is intractable for dynamic cross-layer changes, with submodule remote rewriting given as the example. That is a specific and recognisable problem, because rewriting the remote URL of a submodule is exactly the kind of thing a declarative system struggles with and a script handles in three lines.

Monorepository centralizes infrastructure as a single code artifact, utilizing submodules for modular composition, justified as providing a modular container base that is dynamically resolved for container-specific workflow control.

So the design leans on Git as a compositional mechanism rather than only as version history, and the imperative escape hatch is there precisely because some changes cross the layers the declarative parts cover.

Ansible provisions, Chef handles the recursion

The Design section is three bullets, and the second one describes the tooling split in enough detail to plan around.

By convention, Ansible is used for provisioning, with the `community.proxmox` upstream collection, and Cinc, the Chef distribution, handles the modular, recursive desired state complexity. So there are two configuration tools, and the division of labour is that Ansible talks to Proxmox while Chef deals with the parts of the state that are recursive.

The first bullet is about decoupling. Containers operate independently, allowing for runtime replacement and detached operation, which is what makes it possible for a container to be described in terms of other containers without a hard ordering between them.

The third bullet is the integrated baseline. The `base` role standardizes container configuration defaults, and Proxmox-GitOps leverages this baseline and its built-in infrastructure libraries to deploy itself, establishing a reproducible operational pattern to reuse for container `libs`. In other words the framework eats its own cooking: the same baseline role that configures a container is what configures the framework, and the `libs` directory in the repository root is where those reusable pieces live.

That is a coherent answer to the self-containment problem, and it is also where the complexity in the trade-offs section comes from.

The trade-offs section names the Proxmox 9 token problem

Most project READMEs skip this section. This one has one, and the third entry is the reason an evaluator should keep reading.

The first trade-off is complexity versus autonomy, with self-containment increasing complexity to achieve automated bootstrap and reproducible behavior. The second is Git as state engine, using Git as a state engine rather than for versioning in volatile, stateless contexts, with the monorepository representation encapsulating the entire infrastructure as a self-contained asset suited for version control.

The third is API token restriction versus automation. The README states that with Proxmox 9, stricter privilege separation prevents privileged containers from mounting shares via API token, and that automation capabilities are mainly within the root user context. As a consequence, root user-based API access takes precedence over token-based authentication.

That is a hard operational fact, not a style preference. On Proxmox 9 the token path cannot do everything a privileged container needs, so the framework's own pipeline has to run as root, and the root credentials take precedence over the tokens. For a team that deliberately avoids giving automation root on the hypervisor, that is a reason not to use this, and for a team that already runs root automation it is a non-issue.

The version badges make the scope explicit as well, PVE 8.4 and PVE 9.2, matching the stated requirement of Proxmox VE 8.4 to 9.2.

Configuration is cascading overrides, not one file

The Files and Configuration section explains that cascading overrides are used to separate infrastructure defaults, and the three layers are worth knowing because they explain where a value you are looking for actually lives.

Global environment variables can be set in `globals.json`. `container.stage.env` is sourced for forked-repository deployments, which is the mechanism for a fork to carry its own stage-specific settings. And `.local` files can be used to structure versioning, with examples given as `globals.local.json`, `container.local.env` and `10-assistant.local.caddy`.

That last example is revealing. The naming convention with a numeric prefix and a `.local` suffix, and the mention of structuring versioning through the gitignore, is how a site keeps machine-specific or secret values out of the shared repository while still versioning the shape of the configuration. The numbered prefix also implies an ordering, which is how a cascade of several local files composes into one effective configuration.

The full reference lives in the Configuration Reference document under docs/reference/CONFIGURATION.md, and the repository root shows the rest of the structure: a `base` directory for the baseline role, `config` for the recipes and libraries, `libs` for the reusable container libraries, `local` for the local Docker environment and its configuration, `tasks` for the task definitions, plus `container.env`, `globals.json` and a `docs` directory.

Four lifecycle commands and a monthly release line

The Lifecycle section defines what the framework does with a container, and the four verbs are the API:

code
  - run `release`: creates and configures a container. 
  - run `main`: configures an existing container. 
  - run `snapshot`: creates a snapshot leveraging [`Utils.snapshot`](https://github.com/stevius10/Proxmox-GitOps/blob/develop/config/libraries/utils.rb).
  - run `rollback`: rolls back configuration changes.

Release creates, main configures what already exists, snapshot captures a point, and rollback reverses a configuration change. The separation of create and configure is what makes the pipeline idempotent, since a second run of `main` against an existing container is a reconfiguration rather than a duplicate.

Self-containment has its own operational requirement. The README says to use `git clone --recurse-submodules`, for example for version-controlled mirroring, and notes that `./local/share/` can be used for persistence. The recursive clone is not optional advice, it is what makes the submodules resolve, and the state directory is where a container's runtime state survives a redeploy.

On maintenance, the repository is not archived, the last push was on 2026-10-18, and the recent releases are v1.4.4 from 2026-10-18, v1.4.3 from 2026-09-24 and v1.4.2 from 2026-09-12. A patch release every week or two, on a 1.4 line, with the develop branch as the default.

Editorial conclusion

Proxmox-GitOps fits a team that runs its own Proxmox cluster, wants container configuration to live in Git with a pull request as the review gate, and accepts that the framework deploys itself. It is the wrong choice if you cannot run privileged containers as root on Proxmox 9, because the documented behaviour is that root user-based API access takes precedence over token-based authentication. Verify first that your Proxmox version is in the supported 8.4 to 9.2 range, that you are willing to run the pipeline as root, and how the local configuration in ./local/config.json holds your credentials.

Frequently asked questions

What does Proxmox-GitOps do?

It implements a self-contained GitOps environment for provisioning and orchestrating Linux Containers on Proxmox VE, encapsulating infrastructure in an extensible monorepository that is recursively resolved from Git submodules at runtime. The primary language is Ruby and the licence is MIT.

What do I need before deploying Proxmox-GitOps?

Docker and Proxmox VE 8.4 to 9.2. You also set the Proxmox VE configuration and authorization in ./local/config.json, the environment configuration in globals.json, and the container resource allocation in container.env, then run ./local/run.sh to start the local Docker environment.

How does a configuration change reach Proxmox VE?

Through a pull request. You accept the Pull Request at http://localhost:8080/main/config to deploy Proxmox-GitOps on Proxmox VE, and the deployment of the container library is then triggered in the same way. If AUTO_DEPLOY is set to true in globals.json, the deployment happens automatically without the manual step.

What is the Proxmox 9 limitation in Proxmox-GitOps?

The README states that with Proxmox 9, stricter privilege separation prevents privileged containers from mounting shares via API token, and that automation capabilities are mainly within the root user context, so root user-based API access takes precedence over token-based authentication.

Which tools does Proxmox-GitOps use for configuration?

By convention Ansible is used for provisioning, with the community.proxmox upstream collection, while Cinc, the Chef distribution, handles the modular, recursive desired state complexity. The base role standardizes container configuration defaults and the framework deploys itself with that same baseline.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. stevius10/Proxmox-GitOps on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stevius10-proxmox-gitops.svg)](https://hysenlabs.com/projects/stevius10-proxmox-gitops)

Was this useful?