# Ops & Deploy Runbook — blog.hoelee.com How this blog is built, deployed, and kept alive. Read when debugging CI/CD, deployment, or hosting. --- ## Pipeline ``` Markdown (src/content/posts) → Astro build (dist/) → Gitea Actions → act_runner on unRaid → nginx container → Cloudflare tunnel → Cloudflare CDN → blog.hoelee.com ``` - **Repo:** `git.hoelee.com/hoelee/hoelee-blog` (push here first, then GitHub — standing convention). - **Runner:** `act_runner` on unRaid (verified working: Gitea 1.27.3 + runner 3.3.2, PAT-secret pipeline). --- ## Write & publish a post 1. Create `src/content/posts/.md` with frontmatter (see `content-guide.md` §6). 2. Push to `main`. 3. CI builds `dist/` and deploys to the nginx container automatically. - **Before pushing a post that adds art**, generate its in-page derivatives: `uv run --with pillow python scripts/optimize-images.py ` (banner `.webp` + `/og/thumb/-{400,800}.webp`). The PNGs from `banner-gen` / `og-gen` remain the `og:image` source of truth — see `design-guide.md` §3 for the format policy and measured sizes. 4. Verify live: `curl -I https://blog.hoelee.com/` → expect 200. --- ## Build pitfalls (from prior Astro work — check these first) - **Pagefind is an ES module and exposes no window global.** `dist/pagefind/pagefind.js` ends with `export { search, debouncedSearch, … }`. Load it with a dynamic `import()`, never a classic `