From 09cc7964179703f3f2ea152e5bde718e08242e4c Mon Sep 17 00:00:00 2001 From: "Billy D." Date: Mon, 2 Feb 2026 11:19:16 -0500 Subject: [PATCH] docs: ADR-0020 internal registry URLs for CI/CD Document decision to use registry.lab.daviestechlabs.io for artifact uploads to bypass Cloudflare 100MB limit. --- .../ADR-0020-internal-registry-for-cicd.md | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 docs/adr/ADR-0020-internal-registry-for-cicd.md diff --git a/docs/adr/ADR-0020-internal-registry-for-cicd.md b/docs/adr/ADR-0020-internal-registry-for-cicd.md new file mode 100644 index 0000000..9e14b39 --- /dev/null +++ b/docs/adr/ADR-0020-internal-registry-for-cicd.md @@ -0,0 +1,133 @@ +# ADR-0020: Internal Registry URLs for CI/CD + +## Status + +Accepted + +## Date + +2026-02-02 + +## Context + +| Factor | Details | +|--------|---------| +| Problem | Cloudflare proxying limits uploads to 100MB per request | +| Impact | Docker images (20GB+) and large packages fail to push | +| Current Setup | Gitea at `git.daviestechlabs.io` behind Cloudflare | +| Internal Access | `registry.lab.daviestechlabs.io` bypasses Cloudflare | + +Our Gitea instance is accessible via two URLs: +- **External**: `git.daviestechlabs.io` - proxied through Cloudflare (DDoS protection, caching) +- **Internal**: `registry.lab.daviestechlabs.io` - direct access from cluster network + +Cloudflare's free tier enforces a 100MB upload limit per request. This blocks: +- Docker image pushes (multi-GB layers) +- Large Python package uploads +- Any artifact exceeding 100MB + +## Decision + +**Use internal registry URLs for all CI/CD artifact uploads.** + +CI/CD workflows running on Gitea Actions runners (which are inside the cluster) should use `registry.lab.daviestechlabs.io` for: +- Docker image pushes +- PyPI package uploads +- Any large artifact uploads + +External URLs remain for: +- Git operations (clone, push, pull) +- Package downloads (pip install, docker pull) +- Human access via browser + +## Architecture + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ INTERNET │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ + ┌─────────────────┐ + │ Cloudflare │ + │ (100MB limit) │ + └────────┬────────┘ + │ + ▼ + ┌──────────────────────────────┐ + │ git.daviestechlabs.io │ + │ (external access) │ + └──────────────────────────────┘ + │ + │ same Gitea instance + │ + ┌──────────────────────────────┐ + │ registry.lab.daviestechlabs │ + │ (internal, no limits) │ + └──────────────────────────────┘ + ▲ + │ direct upload + │ + ┌──────────────────────────────┐ + │ Gitea Actions Runner │ + │ (in-cluster) │ + └──────────────────────────────┘ +``` + +## Consequences + +### Positive + +- **No upload size limits** for CI/CD artifacts +- **Faster uploads** (no Cloudflare proxy overhead) +- **Lower latency** for in-cluster operations +- **Cost savings** (reduced Cloudflare bandwidth) + +### Negative + +- **Two URLs to maintain** in workflow configurations +- **Runners must be in-cluster** (cannot use external runners for uploads) +- **DNS split-horizon** required if accessing from outside + +### Neutral + +- External users can still pull packages/images via Cloudflare URL +- Git operations continue through external URL (small payloads) + +## Implementation + +### Docker Registry Login + +```yaml +- name: Login to Internal Registry + uses: docker/login-action@v3 + with: + registry: registry.lab.daviestechlabs.io + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_TOKEN }} +``` + +### PyPI Upload + +```yaml +- name: Publish to Gitea PyPI + run: | + twine upload \ + --repository-url https://registry.lab.daviestechlabs.io/api/packages/daviestechlabs/pypi \ + dist/* +``` + +### Environment Variable Pattern + +For consistency across workflows: + +```yaml +env: + REGISTRY_EXTERNAL: git.daviestechlabs.io + REGISTRY_INTERNAL: registry.lab.daviestechlabs.io +``` + +## Related + +- [ADR-0019: Handler Deployment Strategy](ADR-0019-handler-deployment-strategy.md) - Uses PyPI publishing +- Cloudflare upload limits: https://developers.cloudflare.com/workers/platform/limits/