go-places/INFRASTRUCTURE.md

103 lines
6.1 KiB
Markdown
Raw Permalink Normal View History

2026-10-07 15:14:50 +02:00
# 🏰 Ecosystem Installation Playbook: End-to-End Guide
**Target System:** Kubernetes Cluster managed by Rancher
**Ecosystem Components:** go-places (this repository), go-loose, go-guess, go-tell, etc.
**Goal:** Achieve a "Press Start" configuration where the entire stack runs reliably, persistently, and securely.
**Author:** AI Assistant
**Date Generated:** 2026-10-03
---
## ⚠️ IMPORTANT WARNINGS & SAFETY CHECKLIST
*** DO NOT PROCEED WITHOUT READING THIS SECTION. ***
* **Destructive Actions:** This guide includes commands to prune/reset system environments (e.g., Docker). Ensure all necessary repositories are backed up *before* executing Phase 0 cleanup steps.
* **Security:** All networking relies on the Ingress Controller and Cert-Manager for TLS termination. Ensure your DNS points correctly to the Ingress LoadBalancer IP.
* **Service Mesh:** An innovative Service Mesh (e.g., Istio/Linkerd) will be implemented to handle mTLS, traffic routing, and observability. This adds significant complexity; proceed with caution.
---
## ⚙️ Phase 0: Prerequisites, Cleanup, and Backup (The "Start From Scratch" State)
This phase ensures a known, clean state. **Execute these steps only when ready for a fresh deployment.**
### 0.1 Tool Installation
* Install Docker Engine.
* Install Helm 3.
* Install `kubectl` and configure access to the target K8s cluster (`kubectl config use-context <target-cluster>`).
### 0.2 System Cleanup (Mandatory for Clean Slate)
* *Action:* Run the following commands to stop all services and remove all unused images/volumes.
* *Command:* `docker stop $(docker ps -q) && docker rm $(docker ps -aq) && docker image prune -f && docker system prune -a -f`
### 0.3 Repository Persistence Setup (Forgejo Mounts)
To ensure code history persists across host reboots, we must map local paths to persistent volumes.
* *Action:* Identify the root path for the source code (e.g., `/home/dnoulet/go/`).
* *Command (Example):* Configure the K8s PersistentVolumeClaim (PVC) for Forgejo to mount at `/mnt/forgejo-repo`.
* *Guidance:* Refer to the Forgejo installation guide for exact PVC definitions.
## 🗺️ Phase 1: Core Infrastructure Deployment (The Foundation)
This phase sets up the networking and security backbone before deploying any application logic.
### 1.1 Service Mesh Implementation
* *Recommendation:* Implement **Istio** for a robust Service Mesh.
* *Action:* Apply Istio's base installation manifest (`istioctl install --set profile=default`).
### 1.2 TLS Management (Cert-Manager)
* *Action:* Deploy `cert-manager`. This allows dynamic issuance of certificates for external traffic.
* *Resource:* Define the necessary `Certificate` resources referencing your public domains.
### 1.3 Entry Point (Ingress Controller)
* *Action:* Deploy the Ingress Controller (e.g., Nginx Ingress Controller).
* *Configuration:* Configure the Ingress resource to reference the `Certificate` Secret generated by Cert-Manager.
## 🛠️ Phase 2: Application Build and Deployment (The Go Code)
This phase builds the Go services and deploys them into the cluster, using the Service Mesh for communication.
### 2.1 Building Docker Images
* *Action:* Navigate to the service root and build the image.
* *Command:* `make build`, then `docker build -t go-places:latest .` (build context is the repository root).
### 2.2 Deploying Services via Helm
* **Order of Deployment is Critical:**
1. **`go-loose` (Auth):** Deploy first as it is a core dependency.
`helm upgrade --install go-loose ./charts/go-loose -n dev`
2. **`go-places`:** Deploy next. It reaches `go-loose` only by verifying that service's JWTs, so there is no service URL to wire up; set `AUTH_MODE=jwt` and `JWT_SECRET` to the shared signing secret.
`helm upgrade --install go-places ./charts/api -n dev`
3. **`go-guess`, `go-tell`:** Repeat the above for all other applications.
## ✅ Phase 3: Verification and Finalization
* **Service Health Check:** Verify all pods are running (`kubectl get pods -n dev`).
* **Dependency Checks:** `curl -fsS https://api.yourdomain.com/healthz` and `curl -fsS https://api.yourdomain.com/readyz`. Both are unauthenticated so a probe or a quick `curl` works; `/readyz` additionally pings SQLite and answers `503` when the database is unreachable.
* **API Functionality Test:** Send an authenticated request. The GraphQL executor only answers `POST`, so a browser link cannot leak data:
```bash
curl -H "Authorization: Bearer $GO_LOOSE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"query":"{ places { id title } }"}' \
https://api.yourdomain.com/graphql
```
* **Media Check:** `curl -I https://api.yourdomain.com/media/<key>` should return `200` and `Cache-Control: public, max-age=31536000, immutable`. Media is deliberately unauthenticated so `<img>` tags work; if that is not acceptable for your data, put the Ingress in front of it with an auth subrequest.
## 🌐 Phase 4: Web Front-end
The React app in `web/` is a static bundle. It is **not** served by the `go-places` image and **not** deployed by `charts/api`; the API has no front-end assets. Two ways to publish it:
* **Recommended:** build once and serve from a static host (or an nginx Deployment) on a subdomain, e.g. `https://places.yourdomain.com`. Point it at the API by configuring the CORS origins allowed by the Ingress, or serve it under the same host so the browser makes same-origin requests.
* **Quick path:** serve `web/dist` from any web server and use the Vite dev proxy locally (see `DEVELOPER.md`), which avoids CORS entirely because everything is same-origin.
The client needs two things from its build environment:
| Variable | Meaning |
| --- | --- |
| `VITE_API_BASE` | Optional. Base URL for the API when it is not same-origin. Empty means same-origin. |
| `VITE_API_TOKEN` | Optional. A token baked into the bundle. Leave unset and let the user paste a go-loose token into the "Set token" field in the UI. |
Baking a token into a public bundle publishes it to every visitor, so only do that for a throwaway demo.
---
*End of Initial Playbook Draft.*