feat: provision Alpine LXC 136 running Atheos, wired to Gitea
Provisions a LAN-only browser code editor (Atheos) in an Alpine 3.23 LXC on the scotty PVE node, with armistace/blog cloned and ready to edit. Built via the AI-DLC workflow; the full process trail is in aidlc-docs/. Deliverables - scripts/provision.sh rebuild the guest from scratch (re-runnable) - scripts/update-atheos.sh move Atheos to latest upstream and RE-PIN - scripts/build-and-test.sh captures evidence for every acceptance criterion - files/atheos.conf nginx vhost (socket path byte-matches the FPM pool) - files/ssh-config ~atheos/.ssh/config deploy-key alias - RUNBOOK.md operational guide (START AT STEP 1) - docs/security-notes.md credential model + wider-web hardening TODOs - docs/resiliency-notes.md what a non-PoC deployment would need Design decisions - D1 no git identity is configured by the agent; the operator sets it. Git will refuse the first commit until then, which is deliberate (requirement FR-11). - D2 Atheos pinned to commit f90cd18 (build 611) with a verified tarball sha256, plus update-atheos.sh as the deliberate escape hatch. - D3 nginx :80, web root /var/www/atheos, php-fpm over a unix socket. - D6 git auth is a per-repository DEPLOY KEY scoped to armistace/blog, not a personal access token (a PAT's write:repository scope reaches every repo the account can write). Verified on the live guest (40 checks, 0 failures) - AC-2 Atheos served over HTTP 200 by nginx+php-fpm; socket paths byte-match - AC-3 20 posts + themes/cleanblog present; owned by the php-fpm user - AC-4 all five writable paths writable as the service user - AC-5 remote targets armistace/blog; deploy key authenticates over SSH - AC-6 survival proven with a real container restart, marker byte-identical - AC-8 no python/pelican/pip/make and no DB engine - scope boundary enforced - FR-11 git identity is empty; deploy key mode 600 owned by the service user Traps documented in the RUNBOOK (each cost real debugging time) - The Gitea SSH user is `gitea`, NOT `git` (app.ini SSH_USER=gitea). With `git`, sshd answers "Invalid user git" and rejects before reading authorized_keys, which is indistinguishable from a bad key. - The Gitea SSH endpoint is the LAN address (:22 is not forwarded publicly). - `uptime` and `free` report the PVE HOST inside an LXC without lxcfs, so a container that just restarted can claim days of uptime.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# Application Design Plan — atheos-blog-lxc
|
||||
|
||||
**Stage**: INCEPTION — Application Design (**minimal depth**)
|
||||
**Date**: 2026-09-29
|
||||
|
||||
## Rationale for minimal depth
|
||||
|
||||
There is no application code to design — this project provisions a guest and installs an existing
|
||||
PHP application. "Application Design" here means recording the **runtime component map and its
|
||||
interfaces**, so that (a) the unit boundaries are defensible and (b) a later agent inheriting the
|
||||
repo can see how the pieces talk to each other without re-deriving it.
|
||||
|
||||
## Plan (checkboxes)
|
||||
|
||||
- [ ] Generate `components.md` — component definitions + responsibilities
|
||||
- [ ] Generate `component-methods.md` — the *interfaces* between components (not business logic)
|
||||
- [ ] Generate `services.md` — orchestration / request flow
|
||||
- [ ] Generate `component-dependency.md` — dependency matrix + data flow
|
||||
- [ ] Generate `application-design.md` — consolidated design
|
||||
- [ ] Validate design completeness and consistency
|
||||
|
||||
## Design questions
|
||||
|
||||
Most design decisions were already fixed in requirements.md. Below is the one that is genuinely
|
||||
open, plus two where I state my decision so you can veto it rather than having to choose blind.
|
||||
|
||||
---
|
||||
|
||||
### Q1 (genuine — blocks U4) — what git committer identity should Atheos use?
|
||||
|
||||
Atheos's git integration commits as a configured user. You told me you'll own the `armistace`
|
||||
credentials (**FR-11** — I must not create them). But `git` will refuse to commit at all without
|
||||
*some* identity, so leaving it entirely unset risks a broken first commit for you.
|
||||
|
||||
- **A)** Set a **neutral non-armistace** identity, e.g. `Atheos <atheos@atheos.local>`, purely so
|
||||
commits don't hard-fail; **you** override it with your own identity when you set up credentials.
|
||||
*(Recommended — leaves the tool working without impersonating you.)*
|
||||
- **B)** Set **nothing at all** — leave `user.name`/`user.email` unset, and the RUNBOOK tells you to
|
||||
set them as your first action after SSH-ing in. *(Purest reading of FR-11; first commit fails until you do.)*
|
||||
- **C)** Use a **placeholder under your name** (e.g. `armistace <ar17787@gmail.com>`) so commits are
|
||||
attributed to you out of the box. *(Note: this creates an armistace identity, which is what FR-11
|
||||
says I should not do — only pick this if you want to override that.)*
|
||||
- **X)** Other (describe after the tag)
|
||||
|
||||
`[Answer]:`
|
||||
|
||||
---
|
||||
|
||||
### Q2 (decision stated — veto if wrong) — pin Atheos to a specific upstream commit
|
||||
|
||||
Upstream Atheos is an actively-moving master branch with no releases. For a reproducible
|
||||
re-provision (FR-9), I propose pinning to a **specific verified commit SHA** resolved at build
|
||||
time and recorded in the script + RUNBOOK, rather than tracking `master`.
|
||||
|
||||
`[Answer]:` *(leave blank to accept)*
|
||||
|
||||
---
|
||||
|
||||
### Q3 (decision stated — veto if wrong) — where things live
|
||||
|
||||
- Web root: `/var/www/atheos` (Atheos app)
|
||||
- Atheos workspace: `/var/www/atheos/workspace` → this is where `blog` is cloned
|
||||
- nginx listens on **:80**, `root /var/www/atheos`, `index index.php`
|
||||
- php-fpm via **unix socket** (`/run/php-fpm83/...`) — not a TCP port, so nothing extra listens on the LAN
|
||||
|
||||
`[Answer]:` *(leave blank to accept)*
|
||||
|
||||
---
|
||||
|
||||
## Assumptions carried
|
||||
|
||||
- Atheos is served at the **site root** (`http://<ip>/`), not a subdirectory.
|
||||
- The operator completes Atheos's first-run installer in the browser (creates the admin user);
|
||||
the agent seeds neither the admin nor any Atheos user.
|
||||
- `blog` is pre-cloned into `workspace/` so it appears as a ready-to-open project (your Q6).
|
||||
Reference in New Issue
Block a user