Initial commit: image registry structure and node-agent
Set up this repo as a base image registry. Each image is self-contained in
its own directory under images/ (Dockerfile + README.md + optional test.sh);
CI discovers them by glob, so adding an image needs no workflow changes.
template/ is the skeleton to copy.
The Makefile is the single entry point for both local work and CI, so a green
`make all` locally means a green pipeline.
Workflows:
* lint.yaml — layout check, hadolint, shellcheck
* build.yaml — diffs against the base commit to build only the images that
changed, smoke-tests each one before anything is published, then pushes.
Releases are per-image tags (<image>/vX.Y.Z); main publishes :edge.
First image, node-agent: node:22-alpine plus a GNU userland (Alpine ships
BusyBox, whose applets take narrower flags than scripts and models expect),
helm, kubectl, jq, yq, bind-tools, curl, git, ripgrep, fd and friends.
Nothing is version-pinned — rebuilding is how upstream updates land, and the
published tag is what pins things for consumers.
Its smoke test asserts the deployment contract as well as tool presence: the
image must work non-root, with a read-only root filesystem and all
capabilities dropped, which is how ToolHive runs it.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# images
|
||||
|
||||
Custom container images, published to the public
|
||||
[`rmcguire`](https://gitea.libretechconsulting.com/rmcguire/-/packages) registry
|
||||
on Gitea.
|
||||
|
||||
Each image is self-contained in its own directory under `images/`: a `Dockerfile`,
|
||||
a `README.md`, and an optional `test.sh`.
|
||||
|
||||
## Images
|
||||
|
||||
| Image | Base | Purpose |
|
||||
| --- | --- | --- |
|
||||
| [`node-agent`](images/node-agent) | `node:22-alpine` | Node 22 plus a GNU shell, network and Kubernetes toolchain — a general-purpose command execution environment for AI agents |
|
||||
|
||||
## Pulling
|
||||
|
||||
```sh
|
||||
docker pull gitea.libretechconsulting.com/rmcguire/node-agent:latest
|
||||
```
|
||||
|
||||
The registry is public, so no pull secret is required.
|
||||
|
||||
## Tags
|
||||
|
||||
| Tag | Points at |
|
||||
| --- | --- |
|
||||
| `vX.Y.Z` / `vX.Y` / `vX` | a released build |
|
||||
| `latest` | the most recent release |
|
||||
| `edge` | the current tip of `main` |
|
||||
| `main-<sha>` | one specific commit on `main` |
|
||||
|
||||
Releases are cut per image by pushing a tag named `<image>/vX.Y.Z`, which builds
|
||||
and publishes that image alone:
|
||||
|
||||
```sh
|
||||
git tag node-agent/v1.0.0 && git push origin node-agent/v1.0.0
|
||||
```
|
||||
|
||||
Base images and package versions are deliberately **not** pinned — rebuilding is
|
||||
how upstream updates land, and the published tag is what pins things for whoever
|
||||
pulls it.
|
||||
|
||||
## Adding an image
|
||||
|
||||
```sh
|
||||
cp -r template images/my-image
|
||||
```
|
||||
|
||||
1. Edit `images/my-image/Dockerfile`, or base it on an image already published
|
||||
here (`FROM gitea.libretechconsulting.com/rmcguire/node-agent:latest`).
|
||||
2. Fill in `images/my-image/README.md`.
|
||||
3. Extend `images/my-image/test.sh` to assert whatever the image promises.
|
||||
4. `make build test IMAGE=my-image`
|
||||
|
||||
CI needs no changes — it discovers every directory under `images/` that contains
|
||||
a `Dockerfile`.
|
||||
|
||||
## Local development
|
||||
|
||||
```sh
|
||||
make help # list targets
|
||||
make all # everything CI does
|
||||
make build test IMAGE=node-agent # one image
|
||||
```
|
||||
|
||||
## CI
|
||||
|
||||
Two Gitea workflows, both of which just call the `make` targets above:
|
||||
|
||||
- **`lint.yaml`** — repository layout, `hadolint`, `shellcheck`.
|
||||
- **`build.yaml`** — builds only the images whose files changed, smoke-tests each
|
||||
one before anything is published, then pushes on `main` or a release tag.
|
||||
Reference in New Issue
Block a user