Cairn
CI/CD application for creating custom images with frappe-docker
- Author: Datahenge
- Repository: https://github.com/Datahenge/cairn
- GitHub stars: 1
- Forks: 0
- License: MIT
- Category: Developer Tools
- Maintenance: Actively Maintained
- Frappe versions: v16
Install Cairn
bench get-app https://github.com/Datahenge/cairn
Tags
- deployment
- deployment-automation
- devops
- docker-registry
- erpnext
- frappe
- frappe-erpnext
- frappe-framework
Add the Frappe Gems badge to your README
Maintain Cairn? Paste this into your README:
[](https://frappegems.com/gems/apps/Datahenge/cairn)
About Cairn
cairn
A thin, opinionated wrapper around frappe/frappe_docker
that makes running a custom ERPNext deployment (Frappe + ERPNext + custom apps) on a
single VPS reproducible, immutable, and low-thought — without ever modifying
upstream.
Distributed as datahenge-cairn on PyPI — installs the cairn-build,
cairn-adopt, and cairn-registry commands.
Two pillars: reproducible custom image builds and a pull-based deploy lifecycle (git ref → image tag → running stack, with image-only rollback). A strict data-plane boundary keeps cairn out of your databases and volumes entirely — it ships code, not data.
> Cairn: a trail marker of stacked stones. Each deploy drops a durable marker > (ref → resolved commits → image tag → digest) you can navigate back to.
Three roles, one install
cairn is three commands, one package, told apart by what's configured on a machine rather than by what's installed:
Builder — cairn-build |
Target — cairn-adopt |
Registry — cairn-registry |
|
|---|---|---|---|
| Does | Builds images, pushes them, moves environment pointers | Polls for its pointer, pulls the image, converges the running stack | Provisions and operates a local OCI registry: lifecycle, retention, garbage collection |
| Reads | cairn.toml (the manifest) |
/etc/cairn/adopt.toml (a descriptor, generated by cairn-adopt examine) |
/etc/cairn/registry.toml (optional — built-in defaults otherwise) |
| Needs | Docker Engine v23+ or podman v4+, git |
Docker Engine + docker compose |
Docker Engine + docker compose, openssl |
| Credential | push access to the registry | pull-only | none — reads no manifest, no [cairn] environment |
One pip install datahenge-cairn installs all three — see Get
Started for installing it, and note that a
target simply never has a reason to run cairn-build's commands, and its pull-only registry
credential means it couldn't push or retag even if it did. cairn-registry is only needed at
all if you choose the self-hosted local-registry option (see Where your images
live) — it is independent of the other two roles and is sometimes
colocated with a builder or target, sometimes not.
Configuration
One manifest declares the image (cairn.toml, committed with the deployment); machine-local
build settings, if you need any, live separately and are never shared. See the Builder
walkthrough for provisioning one from scratch
(cairn-build setup --client), and the published reference for the full manifest
schema (cairn.toml), the
machine-local /etc/cairn/builder.toml layer and its CAIRN_* environment-variable
overrides (builder.toml), and
a target's /etc/cairn/adopt.toml descriptor
(target descriptor).
Where images are pushed
Which registry you use, and who owns the credential, is worth thinking about deliberately
— especially when you're building images for a client. See Where your images
live below. cairn itself is registry-agnostic and stores no
credentials — authenticate with docker login or podman login before pushing.
How to use
On a builder — build, push, and manage environment pointers: see the Builder walkthrough and Build Automation.
On a target — adopt an existing deployment and converge it going forward: see the Target walkthrough and Reconcile Automation.
On a registry host (only if you self-host — see Where your images live): see the Registry guide.
Where your images live
cairn builds an image and puts it in a container registry; your deployment targets pull from there. cairn is registry-agnostic and assumes nothing — but which registry is not a neutral choice when you build software for clients:
📦 Choosing a container registry — start here. The image belongs in the account that owns the source; your credential should reach the engagement's images and nothing else; and what each option costs at ERPNext image sizes. Includes what to ask a client for.
🐙 GitHub Container Registry — GHCR in detail: tokens, scopes, how narrow access can be, visibility, and the deletion rule that is genuinely surprising. One option among several, not the default.
If you choose to self-host — cost dominates and off-host rollback history is genuinely not
needed — cairn-registry provisions and operates that registry: lifecycle, retention, and
garbage collection, so disk use stays bounded. See the Self-Hosted Registry
guide or cairn-registry --help.
> You should never be the sole owner of a client's image. If the relationship ends, they must > still be able to deploy and roll back software they own. cairn is built so the registry can be > an account you do not control, and so your push credential can be scoped to one repository.
Related Developer Tools apps for Frappe & ERPNext
- Frappe — Low code web framework for real world applications, in Python and Javascript
- Frappe Docker — Docker environment for developing, deploying, and running Frappe applications (ERPNext and custom apps) in production and development
- Builder — Craft beautiful websites effortlessly with an intuitive visual builder and publish them instantly
- Bench — CLI to manage Multi-tenant deployments for Frappe apps
- Frappe Ui — A set of components and utilities for rapid UI development
- Press — Full service cloud hosting for the Frappe stack - powers Frappe Cloud
- Gameplan — Open Source Discussions Platform for Remote Teams
- Doppio — A Frappe app (CLI) to magically setup single page applications and Vue/React powered desk pages on your custom Frappe apps.