From e8dd88fafe4428ba003e3d40b30ded6ab87ac268 Mon Sep 17 00:00:00 2001 From: juvdiaz Date: Mon, 29 Jun 2026 17:49:26 -0600 Subject: [PATCH] Add optional artifact cache stack --- README.md | 5 +++ README.md.tmpl | 5 +++ docs/jeannie.1.md | 4 +++ infra/artifact-cache/README.md | 21 ++++++++++++ infra/artifact-cache/docker-compose.yml | 21 ++++++++++++ jeannie | 10 +++++- scripts/artifact-cache | 44 +++++++++++++++++++++++++ 7 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 infra/artifact-cache/README.md create mode 100644 infra/artifact-cache/docker-compose.yml create mode 100755 scripts/artifact-cache diff --git a/README.md b/README.md index 68cac5e..2eb7588 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,7 @@ Run a read-only health snapshot from the Debian server with: ./jeannie backup-status ./jeannie synthetic-checks ./jeannie resource-budget +./jeannie artifact-cache status ./jeannie workers list ./jeannie change-journal list ./jeannie map @@ -333,6 +334,10 @@ registry push/pull smoke test is opt-in with against Kubernetes pod requests/limits and Debian host disk/memory signals. Use it before adding heavier workloads so the HP laptop remains usable. +`artifact-cache` manages an optional Debian-host cache stack in +`infra/artifact-cache` with apt-cacher-ng and a Docker Hub registry pull-through +cache. Use `artifact-cache instructions` for client configuration snippets. + `workers` provides named Kubernetes/Pimox worker lifecycle operations: `list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`. Use `recreate-plan ` before replacing one broken Pimox worker so the diff --git a/README.md.tmpl b/README.md.tmpl index 586e748..39504ae 100644 --- a/README.md.tmpl +++ b/README.md.tmpl @@ -278,6 +278,7 @@ Run a read-only health snapshot from the Debian server with: ./{{ main_script }} backup-status ./{{ main_script }} synthetic-checks ./{{ main_script }} resource-budget +./{{ main_script }} artifact-cache status ./{{ main_script }} workers list ./{{ main_script }} change-journal list ./{{ main_script }} map @@ -333,6 +334,10 @@ registry push/pull smoke test is opt-in with against Kubernetes pod requests/limits and Debian host disk/memory signals. Use it before adding heavier workloads so the HP laptop remains usable. +`artifact-cache` manages an optional Debian-host cache stack in +`infra/artifact-cache` with apt-cacher-ng and a Docker Hub registry pull-through +cache. Use `artifact-cache instructions` for client configuration snippets. + `workers` provides named Kubernetes/Pimox worker lifecycle operations: `list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`. Use `recreate-plan ` before replacing one broken Pimox worker so the diff --git a/docs/jeannie.1.md b/docs/jeannie.1.md index 55e519d..bbff87d 100644 --- a/docs/jeannie.1.md +++ b/docs/jeannie.1.md @@ -90,6 +90,10 @@ opt-in through `LAB_SYNTHETIC_REGISTRY_PUSH=true`. : Check the report-only resource policy in `infra/resource-budgets.yml` against Kubernetes pod requests/limits and Debian disk/memory signals. +`artifact-cache {status|up|down|instructions}` +: Manage the optional Debian-host artifact cache stack for apt packages and +Docker Hub pull-through image caching. + `workers ` : Manage Kubernetes/Pimox worker lifecycle operations. Commands include `list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`. diff --git a/infra/artifact-cache/README.md b/infra/artifact-cache/README.md new file mode 100644 index 0000000..732af58 --- /dev/null +++ b/infra/artifact-cache/README.md @@ -0,0 +1,21 @@ +# Homelab Artifact Cache + +This optional Debian-host stack caches repeated downloads during rebuilds. + +- `apt-cacher-ng` on port `3142` for Debian/Ubuntu apt packages +- Docker registry pull-through cache on port `5001` for Docker Hub images + +It is intentionally separate from the main homelab pipeline. Start it when you +want faster rebuilds and a little more tolerance for upstream outages. + +```bash +cd infra/artifact-cache +docker compose up -d +``` + +Client examples: + +```bash +echo 'Acquire::http::Proxy "http://192.168.100.73:3142";' | sudo tee /etc/apt/apt.conf.d/01homelab-cache +docker pull 192.168.100.73:5001/library/debian:bookworm +``` diff --git a/infra/artifact-cache/docker-compose.yml b/infra/artifact-cache/docker-compose.yml new file mode 100644 index 0000000..aa46a84 --- /dev/null +++ b/infra/artifact-cache/docker-compose.yml @@ -0,0 +1,21 @@ +services: + apt_cache: + image: sameersbn/apt-cacher-ng:3.7.4-20220421 + container_name: homelab-apt-cache + restart: unless-stopped + ports: + - "${APT_CACHE_PORT:-3142}:3142" + volumes: + - "${ARTIFACT_CACHE_ROOT:-/data/artifact-cache}/apt-cacher-ng:/var/cache/apt-cacher-ng" + + registry_cache: + image: registry:2 + container_name: homelab-registry-cache + restart: unless-stopped + ports: + - "${REGISTRY_CACHE_PORT:-5001}:5000" + environment: + REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io + REGISTRY_STORAGE_DELETE_ENABLED: "true" + volumes: + - "${ARTIFACT_CACHE_ROOT:-/data/artifact-cache}/registry:/var/lib/registry" diff --git a/jeannie b/jeannie index 1c421a8..30e89d4 100755 --- a/jeannie +++ b/jeannie @@ -6002,6 +6002,11 @@ resource_budget() { "${REPO_ROOT}/scripts/resource-budget" } +artifact_cache() { + require_debian_server "artifact-cache" + "${REPO_ROOT}/scripts/artifact-cache" "${@:2}" +} + workers_manage() { require_debian_server "workers" "${REPO_ROOT}/scripts/workers" "${@:2}" @@ -6070,6 +6075,9 @@ case "${1:-}" in resource-budget) resource_budget ;; + artifact-cache) + artifact_cache "$@" + ;; workers) workers_manage "$@" ;; @@ -6227,7 +6235,7 @@ case "${1:-}" in echo "Log: ${JEANNIE_LOG_FILE}" ;; *) - echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|capacity|recover-plan|gitops-status|cert-check|release-snapshot|backup-status|synthetic-checks|resource-budget|workers |change-journal {list|path}|map [--dot]|validate|access-audit|kubeconfig-readonly|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-restore|drill-gitea-restore|drill-pihole-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-host|security-trivy|security-secrets|security-nuclei|security-web|security-logs|security-runtime|security-attack-path|openwrt|nuke}" + echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|capacity|recover-plan|gitops-status|cert-check|release-snapshot|backup-status|synthetic-checks|resource-budget|artifact-cache {status|up|down|instructions}|workers |change-journal {list|path}|map [--dot]|validate|access-audit|kubeconfig-readonly|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-restore|drill-gitea-restore|drill-pihole-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-host|security-trivy|security-secrets|security-nuclei|security-web|security-logs|security-runtime|security-attack-path|openwrt|nuke}" exit 1 ;; esac diff --git a/scripts/artifact-cache b/scripts/artifact-cache new file mode 100755 index 0000000..234ca73 --- /dev/null +++ b/scripts/artifact-cache @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +STACK_DIR="${REPO_ROOT}/infra/artifact-cache" +DEBIAN_IP="${LAB_DEBIAN_LAN_IP:-192.168.100.73}" +APT_PORT="${APT_CACHE_PORT:-3142}" +REGISTRY_PORT="${REGISTRY_CACHE_PORT:-5001}" + +case "${1:-status}" in + status) + echo "Artifact cache stack: ${STACK_DIR}" + if command -v docker >/dev/null 2>&1 && [ -d "$STACK_DIR" ]; then + (cd "$STACK_DIR" && docker compose ps) || true + else + echo "docker compose unavailable; cannot inspect local cache stack" + fi + ;; + up) + cd "$STACK_DIR" + docker compose up -d + ;; + down) + cd "$STACK_DIR" + docker compose down + ;; + instructions) + cat <&2 + exit 1 + ;; +esac