moonweb-site
Monorepo for the moonweb.org homelab, six static sites built with Eleventy, deployed to IONOS SFTP.
www.moonweb.org/ -> Central index & gateway
www.moonweb.org/infra/ -> Infrastructure overview (Proxmox, Synology, Docker)
www.moonweb.org/smarthome/ -> Smart home projects & dashboards
www.moonweb.org/code/ -> Curated GitHub project catalog
www.moonweb.org/retro/ -> Physical retro hardware collection
www.moonweb.org/timecapsule/ -> 2000s internet time capsule (retro design)
stefankoelle.de -> CV, career, personal site (LED Matrix docs)
Other sites (not in this monorepo): 28k8.moonweb.org (90s BBS archive), buildbroken.moonweb.org (.NET Open Space blog).
Architecture
+-------------------------------------------------------------------+
| GitHub Actions CI |
| +-------------------+ +---------------------+ |
| | build-deploy- | | deploy-stefankoelle | |
| | moonweb | | | |
| +--------+----------+ +----------+----------+ |
| | | |
| v v |
| npm run build npm run build:stefankoelle |
| + build:timecapsule | |
| | | |
| v v |
| dist/moonweb/ dist/stefankoelle/ |
+-----------+------------------------+-------------------------------+
| |
v v
+------------------+ +------------------+
| IONOS SFTP | | IONOS SFTP |
| (www.moonweb.org)| | (stefankoelle.de)|
+--------+---------+ +--------+---------+
v v
www.moonweb.org/* stefankoelle.de
Tech Stack
| Layer | Technology | Why |
|---|---|---|
| SSG | Eleventy 3.1.6 | Markdown/YAML-first, minimal JS, _data folders map directly to aggregator output |
| SSG (timecapsule) | Eleventy 2.0.1 | Legacy 2001 design, CommonJS config |
| Templates | Nunjucks | Shared base.njk layout with site-switcher header, card-grid.njk for index pages |
| Styling | Custom CSS (variables-based) | base.css for shared layout, accent colors inlined in base.njk |
| Fonts | Lobster (Google Fonts) | Distinctive heading font across all sites |
| CI/CD | GitHub Actions | Single build job, parallel SFTP deploy |
| Deploy | IONOS SFTP | Static hosting via SFTP upload |
| DNS | Cloudflare | DNS management + redirects from old subdomains |
| GitHub Catalog | Python aggregator | Reads .moonweb.yml from each repo, outputs repos.json |
| Runtime | Fully static | No server-side code, no containers, no database |
Local Development
npm install # install Eleventy + deps
cd timecapsule && npm install # timecapsule has own deps (Eleventy 2.x)
npm run dev # moonweb sites (localhost:8081)
npm run dev:stefankoelle # stefankoelle.de (localhost:8086)
npm run dev:timecapsule # timecapsule (localhost:8087)
Build
npm run prebuild:cv # pre-build tasks (CV PDF)
npm run build # builds all moonweb sites (hub, infra, smarthome, code, retro)
npm run build:stefankoelle # builds stefankoelle.de
npm run build:timecapsule # builds timecapsule
npm run build:moonweb # builds moonweb + timecapsule (for deployment)
Project Structure
moonweb-site/
├── hub/ # Central index + redirect .htm files
├── infra/ # Infra overview + 8 detail pages
├── smarthome/ # Smart home overview + 9 detail pages
├── code/ # GitHub catalog
├── retro/ # Retro hardware + 13 detail pages
├── timecapsule/ # 2000s retro design (Eleventy 2.x)
│ ├── eleventy.config.js
│ ├── package.json
│ └── src/
├── stefankoelle/ # CV, career, personal site
│ ├── eleventy.config.js
│ ├── index.njk
│ ├── cv-print.njk
│ ├── ledmatrix/
│ └── assets/
├── shared/ # Shared components
│ ├── _includes/
│ │ ├── base.njk # base layout (header, site-switcher, footer)
│ │ ├── card-grid.njk # card-grid template
│ │ └── sitemap.njk # central sitemap template
│ ├── base.css # shared CSS
│ └── favicon/ # favicon SVGs per section
├── _data/
│ └── repos.json # populated by the GitHub aggregator
├── scripts/
│ ├── github-aggregator/ # Python: reads .moonweb.yml -> repos.json
│ └── cloudflare/ # redirect setup for old subdomains
├── .github/workflows/
│ ├── build-deploy-moonweb.yml # CI/CD: IONOS SFTP (www.moonweb.org)
│ └── deploy-stefankoelle.yml # CI/CD: IONOS SFTP (stefankoelle.de)
├── eleventy.config.js # single config for all moonweb sites
├── .eleventyignore # excludes stefankoelle/, timecapsule/
├── DESIGN.md
├── SPEC.md
├── PLAN.md
├── TODO.md
└── package.json
CI/CD Pipeline
IONOS SFTP (www.moonweb.org)
Defined in .github/workflows/build-deploy-moonweb.yml:
push to main
|
+-- Build
| +-- checkout -> setup-node (22) -> npm ci
| +-- npm run build (all moonweb sites in one Eleventy run)
| +-- npm run build:timecapsule
|
+-- Deploy
+-- SFTP upload to IONOS /websites/moonweb/
Required secrets:
IONOS_SFTP_HOSTIONOS_SFTP_USERIONOS_SFTP_PASSWORD
IONOS SFTP (stefankoelle.de)
Defined in .github/workflows/deploy-stefankoelle.yml:
push to main (paths: stefankoelle/**)
|
+-- Build stefankoelle
| +-- npm run build:stefankoelle
|
+-- Deploy via SFTP
+-- SFTP upload to IONOS /websites/stefankoelle/
Required secrets:
IONOS_SFTP_HOSTIONOS_SFTP_USERIONOS_SFTP_PASSWORD
URL Structure
All moonweb.org sites are accessible under www.moonweb.org as subdirectories:
| URL | Content |
|---|---|
www.moonweb.org/ |
Hub (root) |
www.moonweb.org/infra/ |
Infrastructure |
www.moonweb.org/smarthome/ |
Smart Home |
www.moonweb.org/code/ |
Code catalog |
www.moonweb.org/retro/ |
Retro hardware |
www.moonweb.org/timecapsule/ |
2000s time capsule |
www.moonweb.org/impressum/ |
Legal notice |
Cloudflare redirects forward old subdomains:
hub.moonweb.org/*->www.moonweb.org/*infra.moonweb.org/*->www.moonweb.org/infra/*smarthome.moonweb.org/*->www.moonweb.org/smarthome/*code.moonweb.org/*->www.moonweb.org/code/*retro.moonweb.org/*->www.moonweb.org/retro/*
GitHub Aggregator (www.moonweb.org/code/)
scripts/github-aggregator/aggregate.py automatically builds the project catalog:
- Fetches all public repos from
skoellevia GitHub API - Reads
.moonweb.ymlfrom each repo root - Filters for
category: codeentries - Sorts by subcategory + title
- Writes combined result to
_data/repos.json
.moonweb.yml schema
title: "MVG Departures"
category: code # code | smarthome | infra
subcategory: "Web Apps" # drives grouping on www.moonweb.org/code/
status: active
stack: [Python, FastAPI]
hosted_on: "Docker Host Debian (PVE)"
summary: "Compact MVG/S-Bahn departure monitor with configurable stations."
repo_url: "https://github.com/skoelle/mvg-departures"
Manual run
python3 -m venv .venv
.venv/bin/pip install pyyaml
.venv/bin/python scripts/github-aggregator/aggregate.py
Content Rules
| Site | Detail pages? | Rule |
|---|---|---|
| smarthome | Yes | When enough content exists - no placeholder cards |
| infra | Rarely | Deliberately shallow - sensitive data (IPs, keys, passwords) stripped |
| code | Never | Overview cards + GitHub links only - no README duplication |
| retro | Minimal | Honest minimal overview, no over-investment |
| timecapsule | Static | 1:1 migration of original 2001 design, no changes |
Infra redaction rule: Architecture-level only (Proxmox, Synology, Docker, VLAN concept). No concrete IPs, WireGuard keys, passwords, internal hostnames.
Language
All moonweb sites are written entirely in English. The timecapsule uses the original 2001 English content.
Documentation
| File | Purpose |
|---|---|
DESIGN.md |
Initial concept and design decisions |
SPEC.md |
Complete specification - what gets built |
PLAN.md |
Phased implementation plan |
TODO.md |
Open items, workflow, and current status |
README.md |
This file - project overview for GitHub |
AGENTS.md |
AI agent instructions for this codebase |
License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
See LICENSE for the full text.