All checks were successful
Update README with ADR Index / update-readme (push) Successful in 6s
- Add Gitea Action to auto-update README badges and ADR table on push - Standardize 8 ADRs from heading-style to inline metadata format - Add shields.io badges for ADR counts (total/accepted/proposed) - Replace static directory listing with linked ADR table in README - Accept ADR-0030 (MFA/YubiKey strategy)
4.8 KiB
4.8 KiB
Internal Registry URLs for CI/CD
- Status: accepted
- Date: 2026-02-02
- Deciders: Billy
- Technical Story: Bypass Cloudflare 100MB limit by using internal registry endpoints for CI pushes
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
- 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
- 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:
env:
REGISTRY_EXTERNAL: git.daviestechlabs.io
REGISTRY_INTERNAL: registry.lab.daviestechlabs.io
Related
- ADR-0019: Handler Deployment Strategy - Uses PyPI publishing
- Cloudflare upload limits: https://developers.cloudflare.com/workers/platform/limits/