59 lines
3.2 KiB
Markdown
59 lines
3.2 KiB
Markdown
# zai-home-base — revenue projects on djg-oracle-sl
|
|
|
|
Workspace for revenue-generating projects. Cluster edge: **Traefik v2.11**
|
|
(hostNetwork 80/443) + **cert-manager** (Let's Encrypt DNS-01 via Cloudflare).
|
|
Sites are static nginx Deployments fed by hostPath docroots in `sites/`.
|
|
|
|
## Live sites
|
|
|
|
- **bestdadjokes.lol** — dad-joke content site (Track 1; ads play via user's AdX/MCM)
|
|
- **myadhd.dev** — placeholder; ADHD micro-tools product coming (Track 2, Paddle/Stripe later)
|
|
|
|
## Layout
|
|
|
|
- `bdj/` — bestdadjokes.lol project
|
|
- `content/jokes.json` — dataset, APPEND-ONLY (joke id = array index)
|
|
- `build.py` — stdlib-only static generator (Python 3.6! no walrus, no dict-merge `|`)
|
|
- `static/` — css/js/favicon (`jokes-data.js` is generated, don't hand-edit)
|
|
- `k8s/traefik.yaml` — edge DaemonSet (hostNetwork, RBAC incl. endpointslices+nodes)
|
|
- `k8s/letsencrypt-issuer.yaml` — ClusterIssuer, DNS-01 via CF token Secret
|
|
- `k8s/static-sites.yaml` — per-site Deployment+Service+Ingress+Certificate
|
|
- `deploy.sh` — build + in-place rsync to docroot (no dir swap — see gotchas)
|
|
- `adhd/site/index.html` — myadhd.dev placeholder (copied to `sites/myadhd.dev/`)
|
|
- `sites/` — live docroots (generated, gitignored)
|
|
|
|
## Deploy content
|
|
|
|
cd bdj && ./deploy.sh
|
|
|
|
New site = docroot + copy the Deployment/Service/Ingress/Certificate pattern in
|
|
`bdj/k8s/static-sites.yaml` + a DNS record (Cloudflare API, token in
|
|
`~/.cloudflare-token`, zones bestdadjokes.lol=0cd16b5205725d310366859b3352a189,
|
|
myadhd.dev=00fa64c074d7162b7616a4a3dc42ba77).
|
|
|
|
## Server facts & gotchas (hard-won)
|
|
|
|
- VM: djg-oracle-sl, Oracle Linux 8.10, **ARM** 4c/23GB, public IP 144.24.30.131
|
|
- **k3s pinned v1.34.11**: newest kubelet (1.36) refuses cgroup v1; OL8 boots cgroup v1
|
|
and a reboot to switch would kill the agent session. Revisit only with user OK.
|
|
- kubectl: `sudo /usr/local/bin/k3s kubectl` (sudo secure_path drops /usr/local/bin)
|
|
- **firewalld is DISABLED** (it silently rejected pod-forwarded traffic → all pod
|
|
egress dead, "No route to host"). OCI security list (22/80/443) is the perimeter.
|
|
- **coredns Corefile patched**: `forward . 1.1.1.1 8.8.8.8` because OCI's
|
|
169.254.169.254 resolver is link-local and unreachable from pods. A k3s upgrade
|
|
may revert this — re-patch if pods can't resolve DNS.
|
|
- **Traefik gotcha**: without `--entrypoints.websecure.http.tls=true`, TLS routers
|
|
register but never match → every HTTPS request 404s while plaintext works.
|
|
- **hostPath gotcha**: never atomic-swap docroot dirs (mv breaks the bind by inode);
|
|
rsync in place. If a pod serves 403/empty after content ops, rollout-restart it.
|
|
- Local test: `curl -sk --resolve bestdadjokes.lol:443:127.0.0.1 https://bestdadjokes.lol/`
|
|
- Shell rule: never `cd` into a directory a command might delete (agent shell cwd
|
|
breaks and needs manual recovery).
|
|
|
|
## Roadmap
|
|
|
|
1. Google Search Console (user creates property; HTML-meta verification token → I add)
|
|
2. Social content pipeline (needs user accounts: X/Pinterest/Bluesky/Reddit)
|
|
3. Ads: site into user's MCM/AdX; ad slots marked `<!-- AD_SLOT_* -->` in build.py
|
|
4. Daily content growth + long-tail topic pages; then paid-traffic arb experiments
|
|
5. myadhd.dev build-out (client-side tools, Paddle/Stripe when user ready)
|