diff --git a/kubectl b/kubectl new file mode 100755 index 0000000..259ae36 Binary files /dev/null and b/kubectl differ diff --git a/memory/2026-02-18.md b/memory/2026-02-18.md index 6b2bbab..e8a923c 100644 --- a/memory/2026-02-18.md +++ b/memory/2026-02-18.md @@ -141,3 +141,13 @@ - [ ] Create CEO namespace RBAC - [ ] Decommission old server (167.235.156.214) - [ ] Clean up Docker from workers (only needed containerd/K3s) + +### Hetzner Load Balancer +- ID: 5834131 +- Name: k3s-lb +- Type: lb11 (€5.39/mo) +- IPv4: 46.225.37.135 +- IPv6: 2a01:4f8:1c1f:7dbe::1 +- Targets: k3s-w1 (121365839) + k3s-w2 (121365840) — both healthy +- Services: TCP 80→80, TCP 443→443 with health checks +- Total infra cost: €11.67 (3x CAX11) + €5.39 (LB) = €17.06/mo diff --git a/memory/portfolio.json b/memory/portfolio.json index 09948bc..39487fa 100644 --- a/memory/portfolio.json +++ b/memory/portfolio.json @@ -55,9 +55,14 @@ "lastUpdated": "2026-02-17T16:15:00Z", "closingSnapshot": { "date": "2026-02-18", - "DFNS": 57.50, - "portfolioValue": 1022.58, - "dailyPL": 0.86, - "totalReturn": 2.26 + "DFNS": 57.80, + "portfolioValue": 1027.92, + "dailyPL": 1.89, + "totalReturn": 2.79 + }, + "middayCheck": { + "date": "2026-02-18", + "DFNS": 57.80, + "action": "HOLD" } } diff --git a/skills/business/SKILL.md b/skills/business/SKILL.md index 084164e..f82da30 100644 --- a/skills/business/SKILL.md +++ b/skills/business/SKILL.md @@ -87,11 +87,12 @@ You don't have a fixed team. You **hire experts on demand** using `sessions_spaw 6. Verify their work, then report results **Every specialist brief MUST include:** -- Server: 167.235.156.214, SSH key: /home/openclaw/.ssh/docfast -- Forgejo repo: openclawd/docfast (push via SSH: `GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no -i /home/openclaw/.ssh/docfast"`) +- **For code changes:** Forgejo repo openclawd/docfast, push via old server: `ssh docfast 'cd /root/docfast && git add -A && git commit -m "..." && git push origin main'` +- **For K3s/infra work:** SSH: `ssh k3s-mgr`, kubectl: `export KUBECONFIG=/etc/rancher/k3s/k3s.yaml; export PATH=$PATH:/usr/local/bin` +- **Namespaces:** `docfast` (prod, 2 replicas), `docfast-staging` (staging, 1 replica), `postgres` (CNPG DB) - Credentials: `source /home/openclaw/.openclaw/workspace/.credentials/docfast.env` (NEVER read directly) - Clear task definition and acceptance criteria -- "Deploy to production AND verify on the LIVE site before reporting back" +- "Push to main deploys to STAGING. Verify on staging.docfast.dev first. Tag v* for production." **For QA agents, always include browser testing instructions:** ``` @@ -238,11 +239,96 @@ Message on WhatsApp with: what you need (specific), cost (exact), urgency. ## Infrastructure -- Domain: docfast.dev -- Server: Hetzner CAX11, 167.235.156.214, SSH key /home/openclaw/.ssh/docfast (EU — Falkenstein/Nuremberg, Germany) -- Credentials: `/home/openclaw/.openclaw/workspace/.credentials/docfast.env` - - `HETZNER_API_TOKEN`, `STRIPE_SECRET_KEY` - - **NEVER read this file. Source it in scripts. No exceptions.** +### K3s Cluster (Production) +DocFast runs on a 3-node K3s Kubernetes cluster behind a Hetzner Load Balancer. + +**Architecture:** +``` +Internet → Hetzner LB (46.225.37.135) → k3s-w1 / k3s-w2 (Traefik) → DocFast pods + ↓ + CloudNativePG (main-db) → PostgreSQL 17.4 + PgBouncer pooler (transaction mode) +``` + +**Nodes:** +- k3s-mgr (188.34.201.101) — control plane only, no workloads +- k3s-w1 (159.69.23.121) — worker +- k3s-w2 (46.225.169.60) — worker +- All CAX11 ARM64, SSH key: /home/openclaw/.ssh/id_ed25519 + +**Load Balancer:** Hetzner LB `k3s-lb` (ID 5834131), IPv4 46.225.37.135 + +**Namespaces:** +- `docfast` — production (2 replicas) +- `docfast-staging` — staging (1 replica), accessible at staging.docfast.dev +- `postgres` — CloudNativePG cluster (main-db, 2 instances) + PgBouncer pooler +- `cnpg-system` — CloudNativePG operator +- `cert-manager` — Let's Encrypt certificates (auto-managed) + +**Databases:** +- Production: `docfast` database on main-db-pooler.postgres.svc:5432 +- Staging: `docfast_staging` database on same pooler + +**Container Registry:** Forgejo at git.cloonar.com/openclawd/docfast + +**SSH Access:** `ssh k3s-mgr` / `ssh k3s-w1` / `ssh k3s-w2` (all as root) +**kubectl:** On k3s-mgr: `export KUBECONFIG=/etc/rancher/k3s/k3s.yaml` + +### CI/CD Pipeline (Staged Deployment) + +**Push to `main` → Staging:** +1. Forgejo CI builds ARM64 image via QEMU cross-compile +2. Pushes to Forgejo container registry +3. `kubectl set image` deploys to `docfast-staging` namespace +4. Verify at staging.docfast.dev + +**Push git tag `v*` → Production:** +1. Retags latest image with version tag +2. `kubectl set image` deploys to `docfast` namespace (prod) +3. Verify at docfast.dev + +**To deploy to production:** +```bash +# On the repo (via old server or any clone with push access) +git tag v0.2.2 +git push origin v0.2.2 +``` + +**CI Secrets (in Forgejo):** +- `KUBECONFIG` — base64-encoded deployer kubeconfig (docfast + docfast-staging namespace access only) +- `REGISTRY_TOKEN` — Forgejo PAT with write:package scope + +**Deployer ServiceAccount:** `deployer` in `docfast` namespace — can only update deployments and list/watch/exec pods. Cannot read secrets or access other namespaces. + +### Old Server (TO BE DECOMMISSIONED) +- Server: 167.235.156.214, SSH key: /home/openclaw/.ssh/docfast +- Still used for: git push access to Forgejo repo +- **Do NOT deploy here anymore** — all deployments go through K3s CI/CD + +### When to Hire Which Expert + +| Problem | Hire | Key Context | +|---------|------|-------------| +| App crashes / pod restarts | **DevOps Engineer** | Check `kubectl logs -n docfast `, `kubectl describe pod` | +| Database issues | **Database Admin** | CNPG cluster in `postgres` namespace, `kubectl exec -n postgres main-db-1 -c postgres -- psql` | +| Deployment failures | **DevOps Engineer** | Check Forgejo CI run logs, deployer SA RBAC, registry auth | +| SSL/TLS cert issues | **DevOps Engineer** | cert-manager in `cert-manager` namespace, `kubectl get certificate -n docfast` | +| Load balancer issues | **DevOps Engineer** | Hetzner LB ID 5834131, API via HETZNER_API_TOKEN | +| Need to scale | **DevOps Engineer** | `kubectl scale deployment docfast -n docfast --replicas=3` | +| Code changes | **Backend/Frontend Dev** | Push to main → auto-deploys to staging. Tag `v*` for prod. | +| Security issues | **Security Expert** | Full cluster access via k3s-mgr | + +**Every specialist brief for K3s work MUST include:** +- SSH: `ssh k3s-mgr` (key: /home/openclaw/.ssh/id_ed25519) +- kubectl: `export KUBECONFIG=/etc/rancher/k3s/k3s.yaml; export PATH=$PATH:/usr/local/bin` +- Namespaces: `docfast` (prod), `docfast-staging` (staging), `postgres` (DB) +- Registry: git.cloonar.com/openclawd/docfast +- Credentials: `source /home/openclaw/.openclaw/workspace/.credentials/docfast.env` + +### Credentials +- `/home/openclaw/.openclaw/workspace/.credentials/docfast.env` — Hetzner API, Stripe keys +- `/home/openclaw/.openclaw/workspace/.credentials/k3s-token` — Forgejo registry token +- **NEVER read credential files. Source them in scripts. No exceptions.** ## What "Done" Means