Files
stefankoelle eb0b777418 Remove all em-dashes from website content and documentation
Replace ' — ' with ', ' across 40 files. Hyphens (-) untouched.
timecapsule, stefankoelle, LICENSE, CSS comments left as-is.
2026-09-11 20:13:28 +02:00

273 lines
9.9 KiB
Markdown
Executable File

# moonweb-site
Monorepo for the **moonweb.org** homelab, six static sites built with [Eleventy](https://www.11ty.dev/), deployed to [IONOS SFTP](https://www.ionos.de/).
```
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](https://28k8.moonweb.org) (90s BBS archive), [buildbroken.moonweb.org](https://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](https://www.11ty.dev/) | Markdown/YAML-first, minimal JS, `_data` folders map directly to aggregator output |
| **SSG (timecapsule)** | [Eleventy 2.0.1](https://www.11ty.dev/) | Legacy 2001 design, CommonJS config |
| **Templates** | [Nunjucks](https://mozilla.github.io/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](https://fonts.google.com/specimen/Lobster) (Google Fonts) | Distinctive heading font across all sites |
| **CI/CD** | [GitHub Actions](https://github.com/features/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
```bash
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
```bash
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_HOST`
- `IONOS_SFTP_USER`
- `IONOS_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_HOST`
- `IONOS_SFTP_USER`
- `IONOS_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:
1. Fetches all **public repos** from `skoelle` via GitHub API
2. Reads `.moonweb.yml` from each repo root
3. Filters for `category: code` entries
4. Sorts by subcategory + title
5. Writes combined result to `_data/repos.json`
### `.moonweb.yml` schema
```yaml
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
```bash
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
[![CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/)
This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/).
See [LICENSE](LICENSE) for the full text.