updated readme with more relevant details, gemini wrote
This commit is contained in:
@@ -1,116 +1,223 @@
|
|||||||
# River Rooks | Technical Publication & Systems Architecture Blog
|
# River Rooks | Technical Publication & Systems Architecture Blog
|
||||||
|
|
||||||
> Developer-centric, high-signal, low-noise personal technical blog and homelab documentation site.
|
> Developer-centric, high-signal, low-noise personal technical publication and systems architecture blog.
|
||||||
|
|
||||||
Inspired by native terminal environments, modal text editors (Zed, Ghostty), and tiling window managers, this site prioritizes raw performance, keyboard navigability, information density, and structured craftsmanship over generic marketing aesthetics.
|
Inspired by native terminal environments, modal text editors (Zed, Ghostty), and tiling window managers, this site prioritizes raw performance, keyboard navigability, information density, and structured craftsmanship over generic marketing aesthetics.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Architectural Vision & Pillars
|
## 1. Quickstart: Production Server Deployment
|
||||||
|
|
||||||
### 1.1 Static Generation via Eleventy (11ty)
|
The production deployment uses a **decoupled container architecture**. The server does not need Node.js, git, or build dependencies—it only pulls the prebuilt engine from the registry and mounts a local folder containing your Markdown posts.
|
||||||
- **Engine:** Fast, pre-rendered static HTML and minimal client-side runtime using **Eleventy** and **Nunjucks (`.njk`)** templates.
|
|
||||||
- **Performance:** Instant time-to-first-byte (TTFB), zero client-side framework bloat, and pure static asset delivery via high-performance native Node runtime.
|
|
||||||
- **Syntax Highlighting & Code Blocks:** Terminal-styled code blocks with title bars displaying filenames, language tags, and high-contrast monospace code.
|
|
||||||
|
|
||||||
### 1.2 Dynamic Obsidian Publishing Pipeline
|
|
||||||
- **Seamless Authoring:** Author and edit technical dispatches, CTF write-ups, and homelab notes directly inside an **Obsidian** vault.
|
|
||||||
- **Custom Ingestion API:** A dedicated server-side endpoint (`POST /api/posts`) accepting markdown payloads and assets, paired with a custom Obsidian plugin for one-click publishing.
|
|
||||||
- **LiveSync Integration:** Architectural support for syncing notes from a self-hosted Obsidian LiveSync (CouchDB) instance.
|
|
||||||
- **Content Normalization:** Translates Obsidian wikilinks (`[[slug|Title]]`), callouts (`> [!NOTE]`), and asset references into standard web formats during ingestion and build time.
|
|
||||||
|
|
||||||
### 1.3 Strict CSS Isolation & Reusable Templating
|
|
||||||
- **No Monolithic Inlines:** Replaces repetitive inline `<style>` tags with a modular CSS token and component architecture.
|
|
||||||
- **Design Tokens:** Centralized CSS custom properties (`--bg-canvas`, `--bg-surface`, `--border-color`, `--accent-cyan`, etc.) for consistent dark-mode native styling.
|
|
||||||
- **DRY Layouts & Partials:** Reusable Nunjucks components for global navigation (`global-bar`), hero tiles (`hero-tile`), split cards, and article workspace layouts (`article-workspace-grid`).
|
|
||||||
|
|
||||||
### 1.4 AI Pair Architect & Pedagogical Explainer
|
|
||||||
- **Interactive Learning:** The workspace includes customized Antigravity agent configurations (`.agents/` and `AGENTS.md`) that pair-program with the author, architecting solutions while clearly explaining *how* and *why* code is built.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Strict Design Specification
|
|
||||||
|
|
||||||
Adhering to the principles in [`sample-designs/design-specification.md`](./sample-designs/design-specification.md):
|
|
||||||
|
|
||||||
| Rule | Constraint |
|
|
||||||
| :--- | :--- |
|
|
||||||
| **Color Scheme** | Dark-mode native only. Canvas: `#0d0f12`, Surface: `#121417`, Elevated: `#1c1f26`, Borders: `#2b303b`. |
|
|
||||||
| **Accents** | High-signal terminal accents used sparingly: Cyan (`#00f0ff`), Green (`#00e676`), Amber (`#ffb700`). |
|
|
||||||
| **Borders & Radius** | Crisp 1px solid borders. Zero to 4px maximum border-radius (sharp corners preferred). |
|
|
||||||
| **Strict Anti-Patterns** | **NO** glassmorphism (`backdrop-filter`), **NO** drop shadows or glows, **NO** gradients, **NO** spring animations. |
|
|
||||||
| **Typography** | Monospace for UI & code (`IBM Plex Mono`, `JetBrains Mono`); clean sans-serif for body prose (`Inter`). |
|
|
||||||
| **Interactivity** | Instant binary hover snaps (no slow fade transitions); high-contrast focus outlines for keyboard navigation. |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Project Directory Map
|
|
||||||
|
|
||||||
|
### 1.1 Server Directory Structure (`~/docker/blog`)
|
||||||
```text
|
```text
|
||||||
.
|
~/docker/blog/
|
||||||
├── .agents/ # Antigravity agent configurations & customizations
|
├── .env # Environment variables (SITE_DOMAIN, etc.)
|
||||||
│ ├── rules/
|
├── docker-compose.yml # Production container definition
|
||||||
│ │ └── blog-system.md # Architectural constraints, CSS/template isolation & explainer mode
|
└── posts/ # Your live Markdown articles (.md)
|
||||||
│ └── skills/
|
```
|
||||||
│ ├── eleventy-tiling-blog/ # Runbook & recipes for Eleventy builds and component extraction
|
|
||||||
│ └── obsidian-sync/ # Runbook & API contracts for Obsidian publishing & plugin sync
|
### 1.2 Production `docker-compose.yml`
|
||||||
├── sample-designs/ # Canonical HTML/CSS prototypes & design specification
|
```yaml
|
||||||
│ ├── article-tiling-firmware.html
|
services:
|
||||||
│ ├── blog-tiling-lead.html
|
web:
|
||||||
│ ├── design-specification.md
|
image: git.riverrooks.dev/venus/river-rooks-blog:latest
|
||||||
│ └── service-gateway-tiling.html
|
container_name: river_rooks_web
|
||||||
├── src/ # Eleventy source directory (scaffolded in Phase 2)
|
restart: unless-stopped
|
||||||
│ ├── _data/ # Global site metadata, navigation, telemetry data
|
volumes:
|
||||||
│ ├── _includes/
|
- "./posts:/app/src/posts:ro"
|
||||||
│ │ ├── layouts/ # Base, post, and page templates
|
environment:
|
||||||
│ │ └── partials/ # Global bar, hero tile, card, code box, sidebar
|
- "SITE_DOMAIN=${SITE_DOMAIN:?Error: SITE_DOMAIN is not set. Please define SITE_DOMAIN in .env}"
|
||||||
│ ├── assets/
|
- "SITE_URL=${SITE_URL:-https://${SITE_DOMAIN}}"
|
||||||
│ │ ├── css/ # Modular CSS (tokens, reset, layout, components)
|
- "PORT=${PORT:-8080}"
|
||||||
│ │ └── fonts/ # Self-hosted monospace & prose webfonts
|
- "WATCH=${WATCH:-false}"
|
||||||
│ └── posts/ # Markdown content ingested from Obsidian
|
ports:
|
||||||
├── .eleventy.js # Eleventy configuration, markdown-it plugins, and shortcodes
|
- "${HOST_PORT:-${PORT:-8080}}:${PORT:-8080}"
|
||||||
├── package.json # Project dependencies & build scripts
|
networks:
|
||||||
├── server.js # Native Node static web server & clean-URL router
|
- backend
|
||||||
├── Dockerfile # Node container definition (built & served via npm)
|
labels:
|
||||||
├── docker-compose.yml # Container orchestration (web gateway)
|
- "traefik.enable=true"
|
||||||
└── AGENTS.md # Project-level agent instructions & pair programming guide
|
- "traefik.http.routers.blog.rule=Host(`riverrooks.dev`) || Host(`www.riverrooks.dev`)"
|
||||||
|
- "traefik.http.routers.blog.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.blog.tls.certresolver=basic"
|
||||||
|
- "traefik.http.services.blog.loadbalancer.server.port=8080"
|
||||||
|
- "traefik.docker.network=backend"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 Deployment Commands
|
||||||
|
```bash
|
||||||
|
# 1. Pull the prebuilt engine from Gitea registry
|
||||||
|
docker compose pull
|
||||||
|
|
||||||
|
# 2. Launch the container
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 3. Verify healthcheck status (transitions to healthy in 3-5 seconds)
|
||||||
|
docker compose ps
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Development & Build Roadmap
|
## 2. Local Development & Verification
|
||||||
|
|
||||||
- [x] **Phase 1: Foundation & Agent Customizations**
|
All templates, styles, and engine code are developed in this repository (`~/code/blog`).
|
||||||
- Establish `README.md` architectural blueprint.
|
|
||||||
- Setup `.agents/` workspace rules, skills, and root `AGENTS.md`.
|
|
||||||
- [ ] **Phase 2: Eleventy Scaffolding & Modularization**
|
|
||||||
- Initialize Node/npm environment and configure `.eleventy.js`.
|
|
||||||
- Extract design tokens, layout styles, and components into `src/assets/css/`.
|
|
||||||
- Build reusable Nunjucks layouts and partials modeled on `sample-designs/`.
|
|
||||||
- [ ] **Phase 3: Dynamic Obsidian Ingestion & Plugin**
|
|
||||||
- Implement the server-side note ingestion endpoint (`POST /api/posts`).
|
|
||||||
- Develop the custom Obsidian plugin for publishing notes and frontmatter.
|
|
||||||
- Integrate wikilink and callout transformation filters.
|
|
||||||
- [ ] **Phase 4: Containerization & Deployment**
|
|
||||||
- Verify static build outputs in `_site/`.
|
|
||||||
- Update Dockerfile and `docker-compose.yml` for unified production serving.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Development Setup
|
|
||||||
|
|
||||||
*(To be initialized during Phase 2)*
|
|
||||||
|
|
||||||
|
### 2.1 Native Node.js Workflow
|
||||||
```bash
|
```bash
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
# Start Eleventy local development server with hot-reload
|
# Run automated test suite (unit tests, filters, server, and docker assertions)
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Launch Eleventy dev server with hot-reload (binds to http://localhost:8080)
|
||||||
npm run dev
|
npm run dev
|
||||||
|
|
||||||
# Compile static assets for production
|
# Compile static assets to _site/
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
# Run via Docker Compose
|
# Start the native static server locally
|
||||||
docker compose up --build
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 2.2 Local Docker Compose Workflow
|
||||||
|
The local `docker-compose.yml` provides sensible defaults (`localhost`, port 8080, and mounts `./src/posts`):
|
||||||
|
```bash
|
||||||
|
# Build and run the local container stack
|
||||||
|
docker compose up -d --build
|
||||||
|
|
||||||
|
# View container logs (Eleventy compilation + server output)
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
# Stop and clean up
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Push & Update Cycles
|
||||||
|
|
||||||
|
Because the system separates the **Engine** (templates/code) from the **Content** (markdown notes), updates follow two distinct paths:
|
||||||
|
|
||||||
|
### 3.1 Publishing or Editing Articles (Content Workflow)
|
||||||
|
When you write a new note or edit an existing article:
|
||||||
|
|
||||||
|
1. **Add or update the Markdown file** in `posts/` (e.g. `posts/my-new-post.md`):
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Article Title"
|
||||||
|
date: 2026-09-14
|
||||||
|
tags: ["#systems", "#architecture"]
|
||||||
|
excerpt: "A short synopsis of the article."
|
||||||
|
---
|
||||||
|
|
||||||
|
# Article Content...
|
||||||
|
```
|
||||||
|
2. **Recompile the site:**
|
||||||
|
```bash
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
*Eleventy compiles the mounted markdown in ~150ms and starts serving immediately.*
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> **Zero-Restart Live Reload:** Set `WATCH=true` in your server's `docker-compose.yml` environment. Eleventy will watch the `posts/` directory in the background. Whenever a note is saved or synced (e.g., from Obsidian), the site automatically updates in memory without running any commands.
|
||||||
|
|
||||||
|
### 3.2 Updating Blog Templates, CSS, or Features (Engine Workflow)
|
||||||
|
When you modify design tokens, Nunjucks templates, server routes, or dependencies:
|
||||||
|
|
||||||
|
1. **Develop and verify locally:**
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
2. **Build and push the new engine image to the Gitea container registry:**
|
||||||
|
```bash
|
||||||
|
# Build the engine image
|
||||||
|
docker build -t git.riverrooks.dev/venus/river-rooks-blog:latest .
|
||||||
|
|
||||||
|
# Push to Gitea
|
||||||
|
docker push git.riverrooks.dev/venus/river-rooks-blog:latest
|
||||||
|
```
|
||||||
|
3. **Update the production server:**
|
||||||
|
```bash
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. System Architecture & Structure
|
||||||
|
|
||||||
|
### 4.1 High-Level Architecture
|
||||||
|
```text
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Dev Machine / Workstation │
|
||||||
|
│ src/ (templates, CSS, config) + Dockerfile + entrypoint.sh │
|
||||||
|
└──────────────────────────────┬──────────────────────────────┘
|
||||||
|
│ docker push
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Gitea Container Registry (git.riverrooks.dev) │
|
||||||
|
│ image: venus/river-rooks-blog:latest │
|
||||||
|
└──────────────────────────────┬──────────────────────────────┘
|
||||||
|
│ docker pull
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Production Server │
|
||||||
|
│ │
|
||||||
|
│ ~/docker/blog/posts/ ──(volume)──> [ river_rooks_web ] │
|
||||||
|
│ (Live Markdown Notes) ├── entrypoint.sh │
|
||||||
|
│ ├── 11ty compiles │
|
||||||
|
│ Traefik (SSL / Proxy) <──────────── └── server.js (:8080) │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 Key Engine Components
|
||||||
|
- **`entrypoint.sh`**: Dynamic container entrypoint. Compiles mounted markdown notes with Eleventy on boot, starts optional background file watcher, and spawns `server.js` as PID 1 for clean signal handling.
|
||||||
|
- **`Dockerfile`**: Minimal `node:22-alpine` container with pre-installed dependencies, baseline static pre-compilation, and baked-in `HEALTHCHECK` querying `http://127.0.0.1:8080/healthz`.
|
||||||
|
- **`server.js`**: Zero-dependency native Node static web server supporting clean directory URLs, MIME caching, security headers, and the `/healthz` telemetry endpoint.
|
||||||
|
- **`eleventy.config.js`**: Eleventy 3.x configuration, custom collections (`posts`, `tagList`), markdown-it anchor plugins, and custom date/reading-time filters.
|
||||||
|
|
||||||
|
### 4.3 Directory Map
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── .agents/ # Antigravity agent configurations & rules
|
||||||
|
├── sample-designs/ # Design specifications & HTML/CSS prototypes
|
||||||
|
├── src/ # Blog engine source
|
||||||
|
│ ├── _data/ # Site metadata & navigation
|
||||||
|
│ ├── _filters/ # Modular Eleventy filters (date, readingTime, headings)
|
||||||
|
│ ├── _includes/
|
||||||
|
│ │ ├── layouts/ # Base & post Nunjucks templates
|
||||||
|
│ │ └── partials/ # Global bar, hero tile, post cards, code box
|
||||||
|
│ ├── assets/
|
||||||
|
│ │ └── css/ # Modular CSS (tokens, reset, layout, components)
|
||||||
|
│ └── posts/ # Default/fallback markdown posts
|
||||||
|
├── test/ # Automated test suite (node:test)
|
||||||
|
├── docker-compose.yml # Local development compose file
|
||||||
|
├── sample-docker-compose.yml # Production-ready compose template
|
||||||
|
├── Dockerfile # Production container image definition
|
||||||
|
├── entrypoint.sh # Container startup & compilation entrypoint
|
||||||
|
├── server.js # Native Node static HTTP server
|
||||||
|
├── eleventy.config.js # Eleventy configuration
|
||||||
|
├── package.json # Project scripts & dependencies
|
||||||
|
└── README.md # Documentation & runbook
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Strict Design Specification
|
||||||
|
|
||||||
|
All UI components and stylesheets strictly follow [`sample-designs/design-specification.md`](./sample-designs/design-specification.md):
|
||||||
|
|
||||||
|
| Rule | Constraint |
|
||||||
|
| :--- | :--- |
|
||||||
|
| **Color Scheme** | Dark-mode native only. Canvas: `#0d0f12`, Surface: `#121417`, Elevated: `#1c1f26`, Borders: `#2b303b`. |
|
||||||
|
| **Accents** | Terminal accents: Cyan (`#00f0ff`), Green (`#00e676`), Amber (`#ffb700`), Red (`#ff5252`). |
|
||||||
|
| **Borders & Radius** | Crisp 1px solid borders. Zero to 4px maximum border-radius (sharp corners). |
|
||||||
|
| **Strict Anti-Patterns** | **NO** glassmorphism (`backdrop-filter`), **NO** drop shadows or glows, **NO** gradients, **NO** spring animations. |
|
||||||
|
| **Typography** | Monospace for UI & code (`IBM Plex Mono`, `JetBrains Mono`); clean sans-serif for body prose (`Inter`). |
|
||||||
|
| **Interactivity** | Instant binary hover snaps (no slow fade transitions); high-contrast focus outlines for keyboard navigation. |
|
||||||
|
|||||||
Reference in New Issue
Block a user