Files
kontra/.pi/memory-vault/packs/kontra-day/70-runbooks/access-deployment-operations.md

172 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: runbook
id: runbook.kontra-day.access-deployment-operations
title: access deployment operations
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-09-08
tags:
- pack/kontra-day
- agent-memory/runbook
- autolearn
- rich-discovery
- deployment-runbook
---
# access deployment operations
## Deployment/runbook details discovered (2026-09-08 02:23:28)
Great questions — let me answer each properly, because they cut right to the architecture.
## 1. GOTTH + `.md` files — yes, this is a strong fit
Go + templ + htmx + Alpine + Tailwind, with Goldmark (Go's CommonMark renderer) turning your `.md` into HTML at request time, is one of the best "text-first news site" stacks you can pick right now:
- **One static binary** — build once, copy to `.13`, done. No Node, no PHP runtime, no container even needed.
- **Server-rendered HTML** — SEO-friendly by default (great Lighthouse), fast.
- **templ** gives type-safe components; **htmx** gives interactivity (paging, filters, comment forms later) without a JS framework; **Alpine** for small client bits.
- **Content = files** — your Obsidian/editor workflow stays; go can even re-render on file change in dev.
- Cost: the **admin is DIY** — auth, CRUD, media browser are all code you write. And per-request markdown parsing is fine at this scale (cache rendered HTML if you care).
## 2. Laravel as the "orchestrator" — honest answer: it's the wrong tool *for that role*
Laravel is excellent at **being a web app** (Blade+htmx admin, auth, queues, and — importantly — a genuinely great **mail system** for that email phase later). But you're proposing it as a **publish-state manager** perched over Go:
- You'd run **two servers** (Go on :80, Laravel admin on :8080) both touching the same `.md` files and a shared DB. Every publish toggle, front-page order, archive move = a DB write Laravel makes and Go reads.
- That works, but it's **redundant** — Go can own a small SQLite `publish` table itself, with an htmx admin page inside the same binary. One language, one process, zero sync.
So the real fork is:
| Path | Architecture | When to pick |
|---|---|---|
| **A. All Go** | Go serves site + a minimal htmx admin page managing publish/front-page/archive in SQLite. `.md` = content truth. | You want the leanest thing. Email later = Go mail libs, or hand off to n8n/Postfix on your network. |
| **B. Laravel owns it all** | Blade + htmx admin, Laravel serves pages, S3 media via its filesystem driver, Mailables for email later. Drop Go. | You want Laravel's admin/mail/ecosystem and don't mind PHP runtime. |
| **C. Go site + headless admin** | Go serves; **PocketBase (already on .13)** is the admin/publish/media store. | You want a browser admin *without* writing one. |
| **D. Go + Laravel, loosely coupled** | Go serves; Laravel admin only writes publish-state to a **shared SQLite file** + edits `.md` on disk. | You specifically want Laravel's admin UX and Go's front. Viable, but it's path A with extra running parts. |
"Is Laravel good for this?" — good at admin, great at email, overkill as a proxy. **"Other PHP?"** — Symfony (bulkier), Slim (micro), WordPress (off-the-shelf but you'd be fighting it). If PHP is the choice, Laravel+Filament is the right one.
## 3. Garage S3 media + `.md` coordination under Laravel
- **Showing media in admin**: Laravel has a first-class **S3 filesystem driver** — configure a `garage` disk (endpoint, keys, bucket) and the admin lists objects and renders thumbnails. Public reads via a **Caddy/nginx route** (`/media/*` → bucket) rather than exposing Garage's own port; private buckets can use presigned URLs.
- **Coordination with `.md`**: the cleanest pattern is **shortcodes, not raw URLs**. In your file you write `{{media:cover}}` or `{{vimeo:12345}}`; the renderer (Go or Laravel) resolves the slug to the actual S3 URL at render time. That way you can **rename/migrate media later without touching every article** — plain URLs pasted into `.md` freeze the path forever. Upload flow: admin uploads to bucket → returns URL → editor pastes it in the `.md`. Simple and inspectable.
## 4. Is markdown good? And what's the "scientific" one?
- **Yes — Markdown (GFM/CommonMark) + front-matter is ideal** for text news/opinion with links, images, embeds.
- Variants, in case the name escapes you: **MDX** (JSX components inside markdown), **AsciiDoc** (more structure — tables, includes; great for docs, overkill here), **Org-mode**, reStructuredText.
- **The new scientific one is almost certainly Typst** (2023) — a modern typesetting language with gorgeous math, designed for **documents/PDF**. You *can* render it to SVG for web, but for a news site it's the wrong tool.
- **If you meant LSP** (Language Server Protocol) — that's an *editor autocomplete standard*, not a format; ignore it here.
- For the odd formula: keep markdown and add **KaTeX/MathML** via `$...$` in Goldmark's math extension. You get scientific notation with zero new language.
## 5. My recommendation
**Path A — all Go** (templ + htmx + Alpine + Tailwind), `.md` files as content, SQLite publish-state with a small htmx admin for live/front-page/archive, `{{media:...}}` shortcodes resolved to Garage S3. Deploy = one binary behind Caddy on `.13`. Email phase later = Go mail lib or n8n handoff — revisit then, when requirements are real.
Want me to draft **PLAN.md** on Path A — or would you rather spec out Path B (Laravel-everything) or Path C (Go + PocketBase) instead?
## Source paths observed
- `home/sam/home_network/web_sites/kontra_day/.pi`
- `home/sam/home_network/web_sites/kontra_day/.pi/memory-vault`
- `home/sam/home_network/web_sites/kontra_day/.pi/memory-vault/packs`
- `home/sam/home_network/web_sites/kontra_day/.pi/memory-vault/packs/kontra-day`
- `home/sam/home_network/web_sites/kontra_day/.pi/memory-vault/packs/kontra-day/00-system`
- `home/sam/home_network/web_sites/kontra_day/.pi/memory-vault/packs/kontra-day/00-system/pi-agent`
- `home/sam/home_network/web_sites/kontra_day/.pi/tasks`
- `home/sam/.agents`
- `extensions/pi-config/index.ts`
- `extensions/ask-user-question/index.ts`
- `sys/firmware/efi/efivars`
- `publish/front-page/archive`
- `admin/mail/ecosystem`
- `admin/publish/media`
- `live/front-page/archive`
## Evidence
- Confidence: 83%
- Reason: Extracted repeatable deploy/configuration procedure from rich discovery
## Related
- [[packs/kontra-day/00-system/pi-agent/memory-manifest|Memory Manifest]]
## Related learned memories <!-- same-turn-2026-09-08 02:23:28 -->
- session: [[packs/kontra-day/80-sessions/rich-discovery-access-2026-09-08-02-23-28|Rich discovery: access 2026-09-08 02:23:28]]
- context: [[packs/kontra-day/20-context/access|access]]
- runbook: [[packs/kontra-day/70-runbooks/access-deployment-operations|access deployment operations]]
- observation: [[packs/kontra-day/60-observations/access-repository-structure-and-configuration-patterns|access repository structure and configuration patterns]]
---
## Update (2026-09-08 03:36:06)
## Deployment/runbook details discovered (2026-09-08 03:36:06)
Great — this is the model clicking into place. Short version: **the folder on disk is the website. Everything else is just an editor on top of it.** Here's each question answered.
## The mental model
```
content/ (single git repo, remote = Gitea on your network)
│
┌───────┼───────────┬────────────────┐
│ │ │ │
Neovim Obsidian Decap (web) Go binary
(files) (vault) (admin.domain) (renders on request)
│ │ │ │
└───────┴───────────┴────────────────┘
all write the SAME .md files
```
- **Neovim**: edit a file → save → Go already sees it. The site *always* reflects the working tree — so nothing ever goes stale.
- **Obsidian**: the same folder opens as a vault (it's plain markdown ✓), with Gitea as its git remote, exactly as you use it today.
- **Decap**: a browser UI over the *same files* — click collection → articles, edit fields as forms, markdown body editor; on save it commits to git. No duplication, no import/export.
- **Go binary**: renders markdown → HTML **per request**. It never "re-outputs" a static build, because there's no build step to run. (Optional in-memory cache later if you want it snappier.) Optional niceties: `published: false` front-matter → hidden from public, visible as preview on `admin.kontra.day`; `publish_at: 2026-…` → scheduled go-live.
## "Editing in Neovim — will Decap/Obsidian sync?"
Almost. Everything reads the working tree, so Neovim saves are instantly live either way. The one wrinkle: **Decap shows committed state**, so an uncommitted Neovim edit may not show in the Decap UI until someone commits. Fix = a tiny **file-watcher** (inotify/systemd Path unit) on `content/` that autocommits to git on any change from any editor. Then: *any* editor → autocommit → Gitea push → Decap in sync → Go serves. That one script is the "sync" you're imagining, and it's ~10 lines.
## "How are templates created for the GOTH stack? Can we design them?"
Yes — this is exactly **Phase Two** of your AGENT.md, and it's data + code:
| Template | What it's made of |
|---|---|
| `home` (front page composition) | templ component + editable blocks list |
| `article` / `opinion` / `photo-essay` / `video` | templ component, chosen per page in front-matter |
| `subject-index` (each subject area) | templ component + subject setting |
| `archive`, `about`, 404 | templ components |
| Look & feel | Tailwind + CSS design-token variables (`--accent` etc.) |
Flow: we list the template set → I design 2–3 looks (demos/images) → you approve → they get built as `.templ` components in the binary, themed with tokens so colours/subject accents are admin-editable data, not code.
---
The architecture is now concrete enough to write down. Per your AGENT.md Phase One, next step is **PLAN.md + Vikunja/Outline entries** documenting this decision set. Want me to draft PLAN.md and register the phase tasks now — or do you want to change anything in this model first?
## Source paths observed
- `www.wisp.blog/compare/winter/keystatic`
- `github.com/wintercms/winter`
- `plugins/winter/demo`
- `www.luckymedia.dev/insights/decap-cms`
- `users/roles/auth`
- `slug/meta/sitemap/RSS`
## Evidence
- Confidence: 83%
- Reason: Extracted repeatable deploy/configuration procedure from rich discovery
## Related learned memories <!-- same-turn-2026-09-08 03:36:06 -->
- session: [[packs/kontra-day/80-sessions/rich-discovery-files-2026-09-08-03-36-06|Rich discovery: files 2026-09-08 03:36:06]]
- context: [[packs/kontra-day/20-context/files|files]]
- runbook: [[packs/kontra-day/70-runbooks/access-deployment-operations|files deployment operations]]
- observation: [[packs/kontra-day/60-observations/access-repository-structure-and-configuration-patterns|files repository structure and configuration patterns]]