Files
api-company/docs/registry.md
agent-company a615b7ebfd feat: implement docs-site, legal docs, metrics standard, flux manifests
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
2026-05-24 23:20:33 +00:00

164 lines
4.8 KiB
Markdown

# 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
1. **No new infra** — Gitea is already deployed; enabling the container registry is a config flag, not a new deployment.
2. **Integrated auth** — API keys, org-scoped tokens, and CI secrets work natively with the Gitea registry.
3. **Simpler CI** — Gitea Actions workflows can use `${{ secrets.GITEA_TOKEN }}` to push to `gitea.leeworks.dev/leeworks-agents/<image>`.
4. **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)
```yaml
- 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:
```bash
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:
```yaml
spec:
imagePullSecrets:
- name: gitea-registry
```
---
## Enabling Gitea Container Registry
If not already enabled, the Gitea administrator needs to ensure:
1. In `app.ini` (or Helm values), container registry is enabled:
```ini
[packages]
ENABLED = true
```
2. The Gitea service is accessible on port 443 at `gitea.leeworks.dev`.
3. If using `registry.leeworks.dev` as an alias, configure an Nginx Ingress:
```yaml
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
```bash
# 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.