Read-only mirror — the public repositories of the Forgejo instance, refreshed every 10 minutes. The live instance (fg.dieschoenewolke.de) is reachable only over the VPN; clone here with https://git.dieschoenewolke.de/git/<owner>/<repo>.git.
summaryrefslogtreecommitdiff
path: root/AGENTS.md
diff options
context:
space:
mode:
Diffstat (limited to 'AGENTS.md')
-rw-r--r--AGENTS.md45
1 files changed, 45 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..594ffaa
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,45 @@
+# AGENTS — distroless-mirror
+
+Public read-only OCI mirror of `gcr.io/distroless/{static,base,cc,python3}` on
+`img.dieschoenewolke.de`, served by zot on the VPS. `README.md` has the
+architecture, the deploy sequence and the zot-vs-registry:2 rationale.
+
+## Rules
+
+- **Read-only is a property of the registry, not of the edge.** Keep
+ `http.accessControl.repositories."**".anonymousPolicy` at `["read"]` and keep
+ the config free of any `auth` block. Adding htpasswd or an LDAP block would
+ create an authenticated write path that the internet could reach.
+- The port publish stays `127.0.0.1:5000`. The edge vhost is the only entry
+ point; never publish zot on `0.0.0.0` or a host interface.
+- Keep the tag allowlist short (`latest|nonroot|debug|debug-nonroot`). It bounds
+ both disk and what an anonymous client can make zot fetch from gcr.io.
+- `platforms` stays `linux/amd64` + `linux/arm64`. Without the allowlist zot
+ copies every child of the index (arm, ppc64le, riscv64, s390x) and the mirror
+ triples in size on a 28 GB root.
+- Marker tags (`synced-<repo>-<tag>-<digest12>`) are written only after a
+ successful pull **by digest** through the public hostname. Do not move tag
+ creation before the verification, and do not mark from the digest comparison
+ alone.
+- Sync one way only: VPS pulls from gcr.io; nothing pushes into the registry.
+
+## Traps
+
+- `edge-nginx/nginx/default.conf` is a single-file bind mount. Write in place
+ (`cat new > default.conf`), then `docker exec edge-nginx nginx -t` and
+ `nginx -s reload` (or force-recreate). Replacing the file breaks the mount.
+- AppSec must stay off for this host: docker/containerd/skopeo/crane user
+ agents trip CRS scanner rules. The CrowdSec IP bouncer still applies.
+- Do not test from the VPS: its own requests go through AppSec and can be
+ challenged. Test from codeserver over the public name.
+- The wildcard `*.dieschoenewolke.de` SAN covers `img`; a new **name** needs a
+ DNS record, not a certificate change. A new apex-level domain would need the
+ certbot SAN list and a 300 s deSEC propagation wait.
+- zot's periodic sync updates an existing tag only on the next `pollInterval`
+ (2 h). A digest mismatch in the auditor is therefore "pending", not "failed";
+ only a 404 for a ref that was already marked is a regression.
+- `proxy_buffering off` and `proxy_max_temp_file_size 0` are deliberate: layer
+ blobs are streamed, not spooled onto the 28 GB root filesystem.
+- zot GC removes untagged manifests after `gcDelay` (1 h). Never rely on an
+ untagged digest staying pullable — keep the tag (or a marker tag) that
+ references it.