Closes leeworks-agents/api-company#5 (docs-site Astro scaffold) Closes leeworks-agents/api-company#9 (metrics instrumentation standard) Closes leeworks-agents/api-company#10 (Gitea Actions openapi aggregation pipeline) Closes leeworks-agents/api-company#11 (docs-site Flux HelmRelease) Closes leeworks-agents/api-company#12 (SEO blog posts x3) Closes leeworks-agents/api-company#13 (legal docs ToS/Privacy/AUP) Closes leeworks-agents/api-company#14 (DNS documentation) ## Changes ### docs/legal/ - terms-of-service.md — API usage, liability, account termination, governing law - privacy-policy.md — request log retention (90d), no PII sold, data sharing - acceptable-use-policy.md — rate limit abuse, scraping prohibition, resale ban ### docs/metrics-standard.md - Defines api_requests_total, api_response_duration_seconds, api_data_freshness_seconds - Fastify (TypeScript) and FastAPI (Python) reference middleware implementations - Prometheus scrape config and Grafana dashboard guidance ### docs/registry.md - Decision: use Gitea built-in container registry (no new infra) - Image naming convention, auth, Kubernetes imagePullSecrets, ingress config ### docs/dns.md - Required A records for all 6 subdomains - cert-manager ClusterIssuer and Ingress TLS examples - Verification commands and human-operator action items ### docs-site/ - Astro 4 + MDX + sitemap scaffold - Base layout with nav linking all APIs, blog, RapidAPI, status - Landing page with API cards - Per-API Redoc viewer pages (zip-enrichment, holidays, air-quality) - Blog index + 3 SEO blog posts (~1000 words each with JSON-LD) - Dockerfile (multi-stage: node build + nginx serve) - nginx.conf with gzip, caching, health endpoint ### flux/ - gitea-runner/: gitea-act-runner HelmRelease (org-scope, dind) - monitoring/: kube-prometheus-stack + Gatus HelmReleases - Prometheus with pod annotation scraping - Grafana at grafana.leeworks.dev with persistence - Gatus status page at status.leeworks.dev, 90-day retention - docs-site/: Deployment + Service + Ingress via raw chart - api-company-source/: GitRepository + Kustomization reference manifests - kustomization.yaml: root kustomize entry point (build validated) ### .gitea/workflows/build-docs.yaml - Aggregates openapi.yaml from zip-enrichment, holidays, air-quality repos - Builds Astro docs-site - Pushes image to registry.leeworks.dev/leeworks-agents/docs-site - Triggered on push to main, schedule daily 02:00 UTC, workflow_dispatch
4.8 KiB
Container Registry: registry.leeworks.dev
Decision Date: 2026-05-24
Status: Planned (Phase 0 prerequisite)
Decision: Use Gitea's Built-in Container Registry
We will use Gitea's built-in container registry (OCI-compatible, enabled via GITEA_CONTAINER_REGISTRY) rather than deploying a separate distribution/distribution instance.
Rationale
- No new infra — Gitea is already deployed; enabling the container registry is a config flag, not a new deployment.
- Integrated auth — API keys, org-scoped tokens, and CI secrets work natively with the Gitea registry.
- Simpler CI — Gitea Actions workflows can use
${{ secrets.GITEA_TOKEN }}to push togitea.leeworks.dev/leeworks-agents/<image>. - OCI compliance — Gitea's container registry is OCI v1 compliant, compatible with Docker, Podman, and Kubernetes image pulls.
Registry Hostname
registry.leeworks.dev
This will be a reverse proxy/ingress alias for gitea.leeworks.dev (Gitea's container registry endpoint).
Alternatively, Docker clients can use the Gitea hostname directly:
gitea.leeworks.dev/leeworks-agents/<image>:<tag>
If a separate hostname is preferred by the operator, configure an Nginx ingress to proxy registry.leeworks.dev → Gitea's container registry port.
Image Naming Convention
registry.leeworks.dev/leeworks-agents/<repo-name>:<tag>
| API | Image |
|---|---|
| ZIP Enrichment | registry.leeworks.dev/leeworks-agents/zip-enrichment:latest |
| Holidays | registry.leeworks.dev/leeworks-agents/holidays:latest |
| Air Quality | registry.leeworks.dev/leeworks-agents/air-quality:latest |
| Docs Site | registry.leeworks.dev/leeworks-agents/docs-site:latest |
Tags should also include the git SHA for traceability: :<sha> in addition to :latest.
Authentication
Pushing from CI (Gitea Actions)
- name: Log in to registry
run: |
echo "${{ secrets.GITEA_TOKEN }}" | docker login registry.leeworks.dev \
-u ${{ gitea.actor }} --password-stdin
- name: Build and push
run: |
docker build -t registry.leeworks.dev/leeworks-agents/${{ gitea.repository_name }}:${{ gitea.sha }} .
docker push registry.leeworks.dev/leeworks-agents/${{ gitea.repository_name }}:${{ gitea.sha }}
docker tag registry.leeworks.dev/leeworks-agents/${{ gitea.repository_name }}:${{ gitea.sha }} \
registry.leeworks.dev/leeworks-agents/${{ gitea.repository_name }}:latest
docker push registry.leeworks.dev/leeworks-agents/${{ gitea.repository_name }}:latest
Pulling from Kubernetes
Create an image pull secret in each namespace:
kubectl create secret docker-registry gitea-registry \
--docker-server=registry.leeworks.dev \
--docker-username=<gitea-user> \
--docker-password=<gitea-token> \
--docker-email=ci@leeworks.dev \
-n <namespace>
Reference in pod spec:
spec:
imagePullSecrets:
- name: gitea-registry
Enabling Gitea Container Registry
If not already enabled, the Gitea administrator needs to ensure:
- In
app.ini(or Helm values), container registry is enabled:[packages] ENABLED = true - The Gitea service is accessible on port 443 at
gitea.leeworks.dev. - If using
registry.leeworks.devas an alias, configure an Nginx Ingress:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: registry-ingress namespace: gitea annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-read-timeout: "600" nginx.ingress.kubernetes.io/proxy-send-timeout: "600" spec: ingressClassName: nginx tls: - hosts: - registry.leeworks.dev secretName: registry-tls rules: - host: registry.leeworks.dev http: paths: - path: / pathType: Prefix backend: service: name: gitea-http port: number: 3000
Verification
# Test login
docker login registry.leeworks.dev -u <user> -p <token>
# Test push
docker pull alpine:latest
docker tag alpine:latest registry.leeworks.dev/leeworks-agents/test:latest
docker push registry.leeworks.dev/leeworks-agents/test:latest
# Test pull from cluster
kubectl run test-pull --image=registry.leeworks.dev/leeworks-agents/test:latest \
--image-pull-policy=Always --rm -it --restart=Never -- echo "Registry works"
Phase 4 Reference
All API repos should update their ROADMAP.md §Phase 4 to reference:
registry.leeworks.dev/leeworks-agents/<repo>:<tag>
as the image target for CI pushes and Flux HelmRelease image references.