Getting Started
This guide takes you from installation to a complete round trip:
- install margot
- write a minimal project
- validate it
- build it
- publish it
- retrieve it
Install
From PyPI
pip install margo-tooling
With uv
uv tool install margo-tooling
With pipx
pipx install margo-tooling
With a container
Every release publishes a container image to GHCR. Mount your project directory into
/workspace:
podman run --rm -v "$PWD":/workspace ghcr.io/karnarokepoch/margot:latest --help
Pin to a specific version instead of latest for reproducible builds:
podman run --rm -v "$PWD":/workspace ghcr.io/karnarokepoch/margot:0.9.0 --help
From source
With uv:
uv tool install .
margot -V
It install it 2 things:
-
The isolated venv (the package itself + deps):
$XDG_DATA_HOME/uv/tools/<package-name>/ # default on Linux: ~/.local/share/uv/tools/margo-tooling/Each tool gets its own dedicated virtualenv here — isolated from your projects and from other tools.
-
The executable (what lands on your PATH):
$XDG_BIN_HOME → else ~/.local/bin/ # so ~/.local/bin/margot
Or with pip:
uv build
pip install dist/*/margo-tooling*.whl
Minimal project
A Margo project is described by a margo.yaml file at the root, alongside your
application descriptor in margo/app.yaml (or margo/app.yaml.jinja). See
Concepts — Project layout for the full directory tree.
A minimal margo.yaml:
apiVersion: v1
id: com-example-app
name: app
version: "1.0.0"
appVersion: "1.27.0"
description: "App web server"
repository: public.ecr.aws/g2n4p2m7/margo
cat > margo.yaml <<EOF
apiVersion: v1
id: com-example-app
name: app
version: "1.0.0"
appVersion: "1.27.0"
description: "App web server"
repository: public.ecr.aws/g2n4p2m7/margo
EOF
A minimal app.yaml.jinja:
apiVersion: v1
kind: ApplicationDescription
id: {{ manifest.id }}
metadata:
name: NGINX
description: {{ manifest.description }}
version: {{ manifest.version }}
catalog:
organization:
- name: "Margot"
site: "https://karnarokepoch.github.io/margot/"
deploymentProfiles: []
mkdir margo
cat > margo/app.yaml.jinja <<EOF
apiVersion: v1
kind: ApplicationDescription
id: {{ manifest.id }}
metadata:
name: NGINX
description: {{ manifest.description }}
version: {{ manifest.version }}
catalog:
organization:
- name: "Margot"
site: "https://karnarokepoch.github.io/margot/"
deploymentProfiles: []
EOF
Place this at the root of your project. The id is the stable machine identifier for
the application — it should not change across releases.
version becomes the OCI tag for margo artefact.
Validate the descriptor
Before building, check that your app.yaml is valid against the Margo spec schema:
margot verify
margot reads margo.yaml, locates margo/app.yaml (or renders margo/app.yaml.jinja
on the fly if you use Jinja2 templating), and validates it against the vendored Margo
spec schema. No network access, no prior build required.
For stricter checks, also run margot's curated recommended schema:
margot verify --recommend
See margot verify for the full flag reference and the
Schema A / Schema B behaviour matrix.
Build locally
Once the descriptor validates, build the artifact into a local staging directory:
margot build
By default this builds the margo artifact type. To build compose or quadlet components,
or everything at once:
margot build --type compose
margot build --type all
Output goes to .dist/ by default. See margot build for
--build-dir, --variant, and other options.
Publish to a registry
Push the built artifact to the OCI registry declared in margo.yaml:
margot push
margot requires valid registry credentials before pushing. Log in first:
margot auth login public.ecr.aws --username AWS --password-stdin
See Authentication for a full walkthrough, including AWS ECR token
retrieval. See margot auth for the flag reference.
Before a real push, you can verify your credentials and registry access without uploading anything:
margot push --dry-run
The dry run performs the same checks as a real push (tag validation, built-artifact
on-disk check, credential expiry) plus a live write-access probe against the registry —
no artifact content is ever inspected or uploaded. See margot push
for details.
On success:
Pushed: public.ecr.aws/g2n4p2m7/margo:1.0.0
Retrieve and inspect
Pull the artifact layers to disk (no extraction — .tgz blobs are written as-is):
margot pull public.ecr.aws/g2n4p2m7/margo:1.0.0 --output ./out
Fetch the raw manifest JSON for a quick remote inspection without downloading any layers:
margot fetch public.ecr.aws/g2n4p2m7/margo:1.0.0
pull and fetch work anonymously — no authentication required.
See margot pull and margot fetch for
the full reference, including --recursive for pulling a margo artifact along with all
its declared components.
Shell completion
Enable shell tab completion for margot commands and flags:
# Quick setup — appends to your shell's rc file directly
margot --install-completion
# Manual setup — prints the script; redirect it wherever you source completions from
margot --show-completion bash > ~/.local/share/bash-completion/completions/margot
Both methods require a shell restart or re-sourcing the rc file to take effect.
--show-completion takes a shell argument (bash, zsh, fish, powershell, or
pwsh) and prints the completion script to stdout.
Note
--install-completion has no --path option — it always appends to the shell's
default rc file (e.g. ~/.bashrc). If you curate your own rc includes rather than
a raw rc append, use --show-completion instead and redirect the output to your
preferred location.