updated readme with more relevant details, gemini wrote
This commit is contained in:
@@ -1,116 +1,223 @@
|
||||
# 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.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architectural Vision & Pillars
|
||||
## 1. Quickstart: Production Server Deployment
|
||||
|
||||
### 1.1 Static Generation via Eleventy (11ty)
|
||||
- **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
|
||||
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.
|
||||
|
||||
### 1.1 Server Directory Structure (`~/docker/blog`)
|
||||
```text
|
||||
.
|
||||
├── .agents/ # Antigravity agent configurations & customizations
|
||||
│ ├── rules/
|
||||
│ │ └── blog-system.md # Architectural constraints, CSS/template isolation & explainer mode
|
||||
│ └── skills/
|
||||
│ ├── eleventy-tiling-blog/ # Runbook & recipes for Eleventy builds and component extraction
|
||||
│ └── obsidian-sync/ # Runbook & API contracts for Obsidian publishing & plugin sync
|
||||
├── sample-designs/ # Canonical HTML/CSS prototypes & design specification
|
||||
│ ├── article-tiling-firmware.html
|
||||
│ ├── blog-tiling-lead.html
|
||||
│ ├── design-specification.md
|
||||
│ └── service-gateway-tiling.html
|
||||
├── src/ # Eleventy source directory (scaffolded in Phase 2)
|
||||
│ ├── _data/ # Global site metadata, navigation, telemetry data
|
||||
│ ├── _includes/
|
||||
│ │ ├── layouts/ # Base, post, and page templates
|
||||
│ │ └── partials/ # Global bar, hero tile, card, code box, sidebar
|
||||
│ ├── assets/
|
||||
│ │ ├── css/ # Modular CSS (tokens, reset, layout, components)
|
||||
│ │ └── fonts/ # Self-hosted monospace & prose webfonts
|
||||
│ └── posts/ # Markdown content ingested from Obsidian
|
||||
├── .eleventy.js # Eleventy configuration, markdown-it plugins, and shortcodes
|
||||
├── package.json # Project dependencies & build scripts
|
||||
├── server.js # Native Node static web server & clean-URL router
|
||||
├── Dockerfile # Node container definition (built & served via npm)
|
||||
├── docker-compose.yml # Container orchestration (web gateway)
|
||||
└── AGENTS.md # Project-level agent instructions & pair programming guide
|
||||
~/docker/blog/
|
||||
├── .env # Environment variables (SITE_DOMAIN, etc.)
|
||||
├── docker-compose.yml # Production container definition
|
||||
└── posts/ # Your live Markdown articles (.md)
|
||||
```
|
||||
|
||||
### 1.2 Production `docker-compose.yml`
|
||||
```yaml
|
||||
services:
|
||||
web:
|
||||
image: git.riverrooks.dev/venus/river-rooks-blog:latest
|
||||
container_name: river_rooks_web
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "./posts:/app/src/posts:ro"
|
||||
environment:
|
||||
- "SITE_DOMAIN=${SITE_DOMAIN:?Error: SITE_DOMAIN is not set. Please define SITE_DOMAIN in .env}"
|
||||
- "SITE_URL=${SITE_URL:-https://${SITE_DOMAIN}}"
|
||||
- "PORT=${PORT:-8080}"
|
||||
- "WATCH=${WATCH:-false}"
|
||||
ports:
|
||||
- "${HOST_PORT:-${PORT:-8080}}:${PORT:-8080}"
|
||||
networks:
|
||||
- backend
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "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**
|
||||
- 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)*
|
||||
All templates, styles, and engine code are developed in this repository (`~/code/blog`).
|
||||
|
||||
### 2.1 Native Node.js Workflow
|
||||
```bash
|
||||
# Install dependencies
|
||||
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
|
||||
|
||||
# Compile static assets for production
|
||||
# Compile static assets to _site/
|
||||
npm run build
|
||||
|
||||
# Run via Docker Compose
|
||||
docker compose up --build
|
||||
# Start the native static server locally
|
||||
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