Adds complete k8s/ manifest tree: Namespace, VaultAuth + VaultStaticSecret CRDs (VSO secret sync from Vault KV v2), API and UI Deployments and Services, nginx Ingress with cert-manager TLS, MinIO StatefulSet with PVC and init Job, and Alembic init container on the API Deployment for automatic schema migrations. Includes .yamllint.yml config and validate-k8s Makefile target. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.6 KiB
2.6 KiB
Contract: Operator Deployment Interface
The manifests in k8s/ define the operator's deployment interface — the inputs required before applying and the observable outputs after applying.
Pre-deployment Prerequisites (Operator-supplied)
| Prerequisite | Details |
|---|---|
Vault KV v2 secret at reactbin/api/config |
Must contain keys: DATABASE_URL, JWT_SECRET_KEY, OWNER_USERNAME, OWNER_PASSWORD, S3_ENDPOINT_URL, S3_BUCKET_NAME, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, API_BASE_URL |
Vault KV v2 secret at reactbin/minio/credentials |
Must contain keys: MINIO_ROOT_USER, MINIO_ROOT_PASSWORD |
| Vault Kubernetes auth role | A role in the Vault Kubernetes auth mount bound to the default service account in the reactbin namespace with read access to both paths above |
VaultConnection resource |
Named default in the operator's VSO namespace pointing to the Vault server address |
| External PostgreSQL database | A dedicated database and user created; DATABASE_URL in Vault reflects the credentials |
| DNS | The production domain resolves to the cluster ingress IP |
ClusterIssuer |
A cert-manager ClusterIssuer named letsencrypt-prod exists in the cluster |
| Image tags | The operator substitutes the latest placeholder in k8s/api/deployment.yaml and k8s/ui/deployment.yaml with the real image tag before applying |
Apply Command
# Substitute image tags
sed -i 's|reactbin-api:latest|reactbin-api:<tag>|g' k8s/api/deployment.yaml
sed -i 's|reactbin-ui:latest|reactbin-ui:<tag>|g' k8s/ui/deployment.yaml
# Apply all manifests
kubectl apply -f k8s/
Applying is idempotent — safe to re-run on every deployment.
Observable Outputs (Post-apply)
| Resource | Expected State |
|---|---|
Namespace/reactbin |
Active |
Deployment/api in reactbin |
1/1 Ready (init container completes first) |
Deployment/ui in reactbin |
1/1 Ready |
StatefulSet/minio in reactbin |
1/1 Ready |
Job/minio-init-bucket in reactbin |
Completed |
Secret/api-env in reactbin |
Created by VSO, populated with all API env keys |
Secret/minio-credentials in reactbin |
Created by VSO, populated with MinIO root keys |
Certificate/reactbin-tls in reactbin |
Issued (may take up to 2 minutes on first apply) |
Ingress/reactbin in reactbin |
Address populated with cluster ingress IP |
Verification Commands
# All pods running
kubectl get pods -n reactbin
# API health
curl -sf https://<domain>/api/v1/health
# UI reachable
curl -sf https://<domain>/
# Docs correctly gated (should return 404)
curl -o /dev/null -w "%{http_code}" https://<domain>/docs