Boilerplates CLI: turning homelab templates into rendered configs
Create reusable templates and turn them into configurable workloads for homelabs and self-hosted infrastructure. Free and Open-Source.
At a glance
- What is it?
- ChristianLempa/boilerplates is a Python CLI that renders git-backed infrastructure templates into Docker Compose, Kubernetes, Terraform, Ansible and static files. It is aimed at homelab and self-hosted operators who repeat the same service setup across machines.
- Who is it for?
- Adopt it if you run several self-hosted services and keep re-editing the same Compose or Ansible files, and you are willing to keep templates in `template.json` format. Do not adopt it if you are still on the pre-0.2.0 `template.yaml` and `.j2` layout, since the README states those are no longer supported, or if you need language-specific validation of generated Python and Bash.
- 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 30 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The repetition problem Boilerplates targets
Anyone running a homelab ends up with the same files written many times: a Compose stack per service, an Ansible role per host, a Terraform module per provider. The differences between two copies are usually a handful of values (hostname, timezone, port, whether a feature is on). Boilerplates exists to hold the repeated part once and substitute the variable part per deployment. The README frames this as creating reusable templates and turning them into configurable workloads, with the CLI described as the main interface for working with template libraries locally.
The intended user is the self-hosting operator, not an application developer. The topic list points at Docker, Docker Compose, Docker Swarm, Kubernetes, Terraform, Ansible, Packer and Bash, which is the toolset of someone maintaining machines rather than shipping a product. There is no hosted control plane in the README: templates live in git repositories, and the CLI copies rendered output to a local directory or a remote server.
How the templating and library model fit together
Two mechanisms do the work. The first is a custom delimiter set. Templates use `<< >>` for variables, `<% %>` for blocks and `<# #>` for comments, described in the README as Jinja2-like syntax. Those delimiters matter because the generated files are frequently themselves templated. A Compose file or an Ansible task can contain `${VAR}` or `{{ }}` that must survive rendering and be resolved later by Docker or Ansible. Using `<< >>` keeps the two layers from colliding, which is a deliberate choice rather than an aesthetic one.
The second mechanism is the library. Templates are stored in git repositories, and the CLI can add, list, update and remove them. The README shows `boilerplates repo add my-templates https://github.com/user/templates --directory library --branch main`, so a library is a repository plus a directory plus a branch. The library/ directory in this repository holds the built-in set, and a separate boilerplates-library repository is linked for 100+ presets. Rendering combines template-defined variables and defaults, interactive prompts, and CLI overrides.
The format change is the part to read carefully. Boilerplates 0.2.0 introduced `template.json` as the manifest, with renderable content under `files/`. The README states that legacy `template.yaml` or `template.yml` manifests and `.j2` files are no longer supported. A template author who skips that note will find their templates do not load.
Installing the Boilerplates CLI and generating a first stack
The README gives two installation routes. The automated installer downloads a script and uses `pipx` to create an isolated environment, after which the `boilerplates` command is on your PATH. The version flag shown in the README is `--version v1.2.3`, which is the installer's example value, not a released version of this project; the current release listed in the repository is v0.2.1.
curl -fsSL https://raw.githubusercontent.com/christianlempa/boilerplates/main/scripts/install.sh | bashOn NixOS with flakes you can skip installation entirely and run the CLI straight from the repository, which is useful for trying it before adding it to a profile.
nix run github:christianlempa/boilerplates -- --help
nix profile install github:christianlempa/boilerplatesThe first real use is to sync the library, confirm what is available, and inspect one template before generating anything.
boilerplates repo update
boilerplates compose list
boilerplates compose show nginx`repo update` fetches the configured libraries. `compose list` prints the Docker Compose templates the library exposes, and `compose show nginx` prints the metadata and variables for one of them, which is where you learn the variable names you will later override. Generation itself runs either interactively or with overrides.
boilerplates compose generate authentik
boilerplates compose generate traefik --output my-proxy \
--var service_name=traefik \
--var traefik_enabled=true \
--var traefik_host=proxy.example.com \
--no-interactiveThe README gives both forms verbatim. The interactive path prompts for each variable; the non-interactive path takes `--var name=value` pairs and `--output` to choose the destination directory. If you set the same value constantly, `boilerplates compose defaults set container_timezone="America/New_York"` stores it so the wizard stops asking.
Where Boilerplates is the wrong tool
Validation depth is the clearest limitation, and the README states it rather than hiding it. The `python` and `bash` template kinds get what the README calls intentionally minimal validation: template syntax, declared variables, rendering and generic semantic checks. Language-specific checks such as Python compilation, shell syntax checks, formatting or test execution are described as possible follow-up work, not current behaviour. So a rendered Python file that is syntactically invalid as Python can still pass validation. If your workflow depends on generated code being checked, you add that check yourself.
The second boundary is the format break. Because 0.2.0 dropped `template.yaml` and `.j2`, any template collection written before that release needs rewriting to `template.json` with content under `files/`. There is no migration path described in the README, and the release notes for v0.2.0-1 and v0.2.0-2 are not reproduced here. Treat an existing `.j2` library as work to redo, not as something the CLI will read.
Third, this is a rendering and copying tool, not a state manager. Nothing in the README suggests it tracks what was deployed, detects drift, or applies changes to a running host. If you need convergence on live infrastructure, that job belongs to the Ansible or Terraform templates you generate, not to the CLI.
Boilerplates against plain Jinja2 or cookiecutter
The obvious alternative is rendering the same templates with Jinja2 directly, or scaffolding projects with cookiecutter. Both work, and both are general-purpose. The difference is what Boilerplates adds on top of rendering.
With plain Jinja2 you supply the variable values yourself, you decide where templates live, and you write your own prompt loop if you want one. Boilerplates supplies the library layer: git repositories added with `repo add`, fetched with `repo update`, and listed with `repo list`. It supplies the prompt layer: an interactive wizard plus `--var` overrides plus persistent defaults. And it supplies a template contract: `template.json` for metadata and variables, `files/` for renderable content, and a `kind` that groups templates by output technology, which is what makes `boilerplates compose list` and `boilerplates static list` meaningful commands rather than directory listings.
Cookiecutter is closer in spirit, since it also scaffolds from templates with prompts. The distinction here is the delimiter choice and the target. Cookiecutter assumes default Jinja2 syntax and is commonly used for application skeletons; Boilerplates uses `<< >>`, `<% %>` and `<# #>` precisely so the output can still contain Jinja2 or shell syntax, and its presets target infrastructure files rather than application code. If your templates are application scaffolds with no second templating layer, cookiecutter is the simpler fit.
Licence, releases and what upgrades cost
The repository is MIT licensed, and `pyproject.toml` declares `license = "MIT"`. MIT permits use, modification and redistribution provided the copyright notice and permission notice are retained. That is the extent of what the repository states; questions about your own distribution obligations are for your legal counsel, not this page.
The Python requirement is `>=3.9`. Runtime dependencies are `typer[all]>=0.9.0`, `rich>=13.0.0`, `PyYAML>=6.0`, `python-frontmatter>=1.0.0`, `Jinja2>=3.0`, `email-validator>=2.0.0` and a pinned `click==8.1.4`. The `click` pin is worth noting: it is an exact version, not a range, so it can conflict with other tools in the same environment. The installer's `pipx` isolation sidesteps that, which is likely why the README recommends it.
Upgrade cost is dominated by the template format, not the CLI. The jump to 0.2.0 broke `template.yaml` and `.j2`, so a library written against 0.1.x needs conversion before it will load. `requirements.txt` pins exact versions (`typer==0.20.0`, `rich==14.2.0`, `PyYAML==6.0.3`, `python-frontmatter==1.1.0`, `Jinja2==3.1.6`), which gives reproducible installs and means dependency upgrades arrive as deliberate edits. The last push to the repository was on 2026-08-31, and the most recent release listed is v0.2.1 from 2026-06-02. The repository is not archived, so the CLI is being changed; the README's own warning about the 0.2.0 break is the reason to read the changelog before bumping versions.
Editorial conclusion
Adopt it if you run several self-hosted services and keep re-editing the same Compose or Ansible files, and you are willing to keep templates in `template.json` format. Do not adopt it if you are still on the pre-0.2.0 `template.yaml` and `.j2` layout, since the README states those are no longer supported, or if you need language-specific validation of generated Python and Bash. Before committing, run `boilerplates repo update` and `boilerplates compose show nginx` to confirm the library resolves and the template metadata matches your environment.
Frequently asked questions
What is a boilerplate in the context of ChristianLempa/boilerplates?
In this project a boilerplate is a reusable template for infrastructure, such as a Docker Compose stack or an Ansible role, stored in a git-backed library. The CLI renders it with your variable values to produce a concrete, environment-specific configuration.
What does generating boilerplates mean with this CLI?
It means running a generate command such as `boilerplates compose generate nginx`, which combines template defaults, interactive prompts and `--var` overrides to write rendered files into an output directory. The README shows both the interactive form and a non-interactive form with `--no-interactive`.
Which template formats does Boilerplates 0.2.0 accept?
Templates must use `template.json` as the manifest and keep renderable content under `files/`. The README states that legacy `template.yaml` or `template.yml` manifests and `.j2` template files are no longer supported.
How do I install the Boilerplates CLI?
The README provides an installer script that pipes into bash and uses `pipx` to create an isolated environment, after which the `boilerplates` command is available. On NixOS with flakes you can instead run it with `nix run github:christianlempa/boilerplates` or install it to your profile.
Can Boilerplates use templates from my own repository?
Yes. Libraries are git-based, and the README shows `boilerplates repo add my-templates https://github.com/user/templates --directory library --branch main` to register a custom one, with `repo list`, `repo update` and `repo remove` to manage it.
Official sources
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.
[](https://hysenlabs.com/projects/christianlempa-boilerplates)