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,29 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Skeleton for a new image. Copy this directory to images/<name>/ and edit.
|
||||
#
|
||||
# Conventions worth keeping:
|
||||
# * leave upstream tags and package versions unpinned, so a rebuild picks up
|
||||
# updates — the published image tag is what pins things for consumers
|
||||
# * keep the ARG/LABEL block last, so changing build metadata does not
|
||||
# invalidate the layers above it
|
||||
#
|
||||
# To build on top of an image already published here, replace the FROM with:
|
||||
# FROM gitea.libretechconsulting.com/rmcguire/node-agent:latest
|
||||
FROM alpine:3
|
||||
|
||||
# hadolint ignore=DL3018
|
||||
RUN apk add --no-cache bash ca-certificates
|
||||
|
||||
CMD ["bash"]
|
||||
|
||||
ARG VERSION=dev
|
||||
ARG REVISION=unknown
|
||||
ARG CREATED=unknown
|
||||
LABEL org.opencontainers.image.title="CHANGEME" \
|
||||
org.opencontainers.image.description="CHANGEME" \
|
||||
org.opencontainers.image.source="https://gitea.libretechconsulting.com/rmcguire/images" \
|
||||
org.opencontainers.image.base.name="docker.io/library/alpine:3" \
|
||||
org.opencontainers.image.version="${VERSION}" \
|
||||
org.opencontainers.image.revision="${REVISION}" \
|
||||
org.opencontainers.image.created="${CREATED}"
|
||||
@@ -0,0 +1,32 @@
|
||||
# CHANGEME
|
||||
|
||||
One or two sentences: what this image is for, and who pulls it.
|
||||
|
||||
```
|
||||
gitea.libretechconsulting.com/rmcguire/CHANGEME
|
||||
```
|
||||
|
||||
## Contents
|
||||
|
||||
Base: `alpine:3`
|
||||
|
||||
| Group | Tools |
|
||||
| ----- | ----- |
|
||||
| Shell | `bash` |
|
||||
|
||||
## Environment
|
||||
|
||||
| Variable | Value | Why |
|
||||
| -------- | ----- | --- |
|
||||
| | | |
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
docker run --rm -it gitea.libretechconsulting.com/rmcguire/CHANGEME:latest
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
Anything a consumer would otherwise trip over — required capabilities, writable
|
||||
paths, credentials the image expects to be mounted.
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
# Smoke-test skeleton. Optional, but CI runs it whenever it exists and is
|
||||
# executable, so it is the cheapest place to assert what the image promises.
|
||||
#
|
||||
# Usage: test.sh [image-ref]
|
||||
set -euo pipefail
|
||||
|
||||
REF="${1:?usage: test.sh <image-ref>}"
|
||||
echo "==> smoke-testing ${REF}"
|
||||
|
||||
# Run the checks in one container. Mirror the securityContext the image is
|
||||
# actually deployed with, so CI catches read-only or non-root breakage.
|
||||
docker run --rm --interactive \
|
||||
--read-only \
|
||||
--tmpfs /tmp:rw,size=64m \
|
||||
"$REF" bash -s <<'INNER'
|
||||
set -uo pipefail
|
||||
fail=0
|
||||
|
||||
ok() { printf ' \033[32mok\033[0m %s\n' "$1"; }
|
||||
bad() { printf ' \033[31mFAIL\033[0m %s\n' "$1"; fail=1; }
|
||||
|
||||
for t in bash; do
|
||||
command -v "$t" >/dev/null 2>&1 && ok "$t" || bad "$t (not on PATH)"
|
||||
done
|
||||
|
||||
[ "$fail" = 0 ] && echo "all checks passed" || echo "FAILURES above"
|
||||
exit "$fail"
|
||||
INNER
|
||||
Reference in New Issue
Block a user