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
This commit is contained in:
+144
@@ -0,0 +1,144 @@
|
||||
# DNS Configuration
|
||||
|
||||
**Last updated:** 2026-05-24
|
||||
**Status:** Planned (Phase 6 pre-launch)
|
||||
|
||||
---
|
||||
|
||||
## DNS Provider
|
||||
|
||||
DNS for `leeworks.dev` is managed externally (by the human operator via their registrar/DNS provider). The agent cannot directly create DNS records. This document tracks the required records for human operator action.
|
||||
|
||||
---
|
||||
|
||||
## Required Records
|
||||
|
||||
All records should point to the cluster ingress IP. To find the current ingress IP:
|
||||
|
||||
```bash
|
||||
kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
|
||||
```
|
||||
|
||||
| Subdomain | Type | Target | Purpose | TLS Required |
|
||||
|-----------|------|--------|---------|-------------|
|
||||
| `zip.leeworks.dev` | A | `<cluster-ingress-ip>` | ZIP Enrichment API | Yes (cert-manager) |
|
||||
| `holidays.leeworks.dev` | A | `<cluster-ingress-ip>` | Holidays API | Yes (cert-manager) |
|
||||
| `aqi.leeworks.dev` | A | `<cluster-ingress-ip>` | Air Quality API | Yes (cert-manager) |
|
||||
| `docs.leeworks.dev` | A | `<cluster-ingress-ip>` | Documentation site | Yes (cert-manager) |
|
||||
| `status.leeworks.dev` | A | `<cluster-ingress-ip>` | Gatus status page | Yes (cert-manager) |
|
||||
| `registry.leeworks.dev` | A | `<cluster-ingress-ip>` | Container registry (Gitea) | Yes (cert-manager) |
|
||||
| `grafana.leeworks.dev` | A | `<cluster-ingress-ip>` | Grafana (internal/restricted) | Yes (cert-manager) |
|
||||
|
||||
---
|
||||
|
||||
## TLS Certificate Management
|
||||
|
||||
TLS certificates are issued automatically by **cert-manager** using Let's Encrypt (ACME HTTP-01 or DNS-01 challenge).
|
||||
|
||||
### Prerequisites
|
||||
- cert-manager deployed in the cluster (part of Talos setup)
|
||||
- A `ClusterIssuer` configured for Let's Encrypt
|
||||
|
||||
### ClusterIssuer (Let's Encrypt Production)
|
||||
|
||||
```yaml
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: legal@leeworks.dev
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-prod-key
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
```
|
||||
|
||||
### Example Ingress with TLS
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: zip-enrichment-ingress
|
||||
namespace: zip-enrichment
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- zip.leeworks.dev
|
||||
secretName: zip-tls
|
||||
rules:
|
||||
- host: zip.leeworks.dev
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: zip-enrichment
|
||||
port:
|
||||
number: 3000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification Steps
|
||||
|
||||
After DNS records are created:
|
||||
|
||||
```bash
|
||||
# Check DNS resolution
|
||||
dig zip.leeworks.dev +short
|
||||
dig holidays.leeworks.dev +short
|
||||
dig aqi.leeworks.dev +short
|
||||
dig docs.leeworks.dev +short
|
||||
dig status.leeworks.dev +short
|
||||
dig registry.leeworks.dev +short
|
||||
|
||||
# Check TLS certificates (once services are deployed)
|
||||
curl -v https://zip.leeworks.dev/health 2>&1 | grep -E "SSL|certificate|issuer"
|
||||
|
||||
# Check cert-manager issued certs
|
||||
kubectl get certificates -A
|
||||
|
||||
# Expect HTTP 200 on health endpoints
|
||||
for host in zip.leeworks.dev holidays.leeworks.dev aqi.leeworks.dev; do
|
||||
echo -n "$host: "
|
||||
curl -s -o /dev/null -w "%{http_code}" https://$host/health
|
||||
echo
|
||||
done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Action Required (Human Operator)
|
||||
|
||||
The following actions require human operator access to the DNS provider:
|
||||
|
||||
1. Log into the DNS provider managing `leeworks.dev`
|
||||
2. Find the cluster ingress IP: `kubectl get svc -n ingress-nginx ingress-nginx-controller`
|
||||
3. Create/update the 6 A records listed in the table above
|
||||
4. Verify propagation: `dig +trace zip.leeworks.dev`
|
||||
|
||||
DNS propagation typically takes 5–60 minutes.
|
||||
|
||||
---
|
||||
|
||||
## Current Status
|
||||
|
||||
- [ ] Cluster ingress IP confirmed
|
||||
- [ ] `zip.leeworks.dev` → DNS record created
|
||||
- [ ] `holidays.leeworks.dev` → DNS record created
|
||||
- [ ] `aqi.leeworks.dev` → DNS record created
|
||||
- [ ] `docs.leeworks.dev` → DNS record created
|
||||
- [ ] `status.leeworks.dev` → DNS record created
|
||||
- [ ] `registry.leeworks.dev` → DNS record created
|
||||
- [ ] TLS certificates issued and valid for all 6 subdomains
|
||||
Reference in New Issue
Block a user