Skip to content
sed-iPublic

About

Create ad-hoc charms for a given image

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

jocker

jocker scaffolds a minimal Juju Kubernetes charm tree for an ad-hoc OCI image (from Docker Hub or any other registry) -- the closest thing to docker run for Juju.

Status

MVP: only jocker init is implemented. It generates the charm tree; you pack and deploy it yourself with charmcraft and juju. A jocker deploy command that automates packing/deploying is planned for later.

Prerequisites

  • uv -- to run jocker itself, and because jocker uses it to generate the charm's uv.lock as a final step.
  • skopeo (optional but recommended) -- jocker uses it to prefill each container's command and environment config defaults from the image. Without it, those defaults are left empty and jocker prints a warning.

Install & run

Run directly from GitHub with uv, no local install needed:

uv tool run --from git+https://github.com/<your-org>/jocker jocker init my-app --image my-app=docker.io/library/nginx:latest

Note that jocker appears twice: --from git+https://.../jocker tells uv which package to fetch, and the second jocker tells it which command from that package to run (uv tool run doesn't infer the command name from --from). Dropping the second jocker -- e.g. running uv tool run --from git+https://.../jocker init my-app ... -- makes uv try to run a program literally called init from your PATH (usually your system's init/pid 1 binary), which fails with a confusing init: unrecognized option error.

Or install it as a persistent tool:

uv tool install --from git+https://github.com/<your-org>/jocker jocker

Run from a local checkout

If you have a local clone of this repo (e.g. at /home/user/code/jocker) and want to use it from somewhere else, like /tmp/some-k8s-operator, point uv run at the checkout with --project -- you don't need to cd into it or install anything globally:

cd /tmp/some-k8s-operator
uv run --project /home/user/code/jocker jocker init my-app --image my-app=docker.io/library/nginx:latest

uv run --project <path> uses that path's environment (installing/syncing it on first use) but still runs the command with your current directory as the working directory, so jocker init scaffolds into /tmp/some-k8s-operator as expected.

If you'll be doing this often, install it as a tool from the local path instead, which puts a jocker command on your PATH:

uv tool install --from /home/user/code/jocker jocker

After editing jocker's source, re-sync with uv tool upgrade jocker (or uv tool install --reinstall --from /path/to/jocker jocker) to pick up the changes.

Usage

jocker init <charm-name> --image NAME=IMAGE [--image NAME=IMAGE ...] [--storage NAME=PATH ...] [--ports PORT,PORT,...] [--summary TEXT] [--description TEXT] [--base ubuntu@24.04]
  • Must be run in an empty directory (created if it doesn't exist yet). jocker aborts if the target directory already has files in it.
  • --image NAME=IMAGE is repeatable and required at least once. Each entry adds a workload container named NAME (also used as its Pebble service name), running IMAGE as the upstream-source of its oci-image resource (named NAME-image) in charmcraft.yaml.
  • --storage NAME=PATH can be repeated to declare filesystem storage. Every storage entry is mounted at PATH in every container declared via --image.
  • Each container gets its own namespaced config options: NAME-command and NAME-environment. If skopeo is installed, jocker uses skopeo inspect --config on each image to prefill these options' defaults from the image's Entrypoint and Env. If skopeo is missing, or inspection fails for a given image, jocker leaves that container's defaults empty and prints a warning -- it does not abort.
  • ports is a single, shared config option (ports are per-pod, not per-container). Use --ports PORT,PORT,... (e.g. --ports 8123,8080,4317,4318) to set its default in the generated charmcraft.yaml; it's empty by default.
  • As a final step, jocker runs uv lock --upgrade --no-cache in the new directory to generate uv.lock (required by the charm's uv build plugin). This requires uv to be installed and on PATH; if it isn't, jocker still leaves the charm tree in place but reports the error so you can run the lock command yourself.

Example

Single container:

mkdir clickhouse-k8s && cd clickhouse-k8s
jocker init clickhouse \
  --image clickhouse=docker.io/clickhouse/clickhouse-server:latest \
  --storage db=/data/db \
  --storage logs=/var/log/clickhouse-server

This creates:

.
├── charmcraft.yaml
├── pyproject.toml
├── uv.lock
├── README.md
├── .gitignore
└── src/
    └── charm.py

Then, as usual:

charmcraft pack
juju deploy ./clickhouse_*.charm --resource clickhouse-image=docker.io/clickhouse/clickhouse-server:latest

Multiple containers (e.g. an app plus a sidecar), sharing the same storage mounts and a default ports list:

jocker init my-app \
  --image clickhouse=clickhouse/clickstack-all-in-one:latest \
  --image other-sidecar=some/other-sidecar \
  --storage db=/data/db \
  --ports 8123,8080,4317,4318

What jocker does not do (yet)

  • It inspects each image's Entrypoint/Env (via skopeo) only to prefill config defaults -- always double check charmcraft.yaml and adjust NAME-command/NAME-environment if a default is missing or wrong.
  • It does not run charmcraft pack or juju deploy for you (jocker deploy is planned).

Development

uv sync --extra dev
uv run pytest

Try it in a sandbox with Workshop

To test jocker in a clean, reproducible environment without installing anything on your host, use Canonical's Workshop tool. This repo ships a .workshop/dev.yaml definition with a uv SDK and two ready-made actions.

sudo snap install --channel=6/stable lxd  # skip if LXD is already installed
sudo snap install --classic workshop

From the repo root, launch the workshop once:

workshop launch

Then run the actions:

workshop run -- test   # uv sync --extra dev && uv run pytest, sandboxed
workshop run -- smoke  # runs `jocker init` end-to-end in a scratch dir

After editing jocker's source, no refresh is needed to pick up code changes -- only .workshop/dev.yaml itself (SDKs/actions) requires a workshop refresh. Drop into an interactive shell with workshop shell if you want to poke around manually.

About

Create ad-hoc charms for a given image

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages