mirror of
https://github.com/skoelle/moonweb-site.git
synced 2026-09-17 17:00:25 +00:00
README.md and 2 new links
This commit is contained in:
@@ -1,61 +1,245 @@
|
|||||||
# moonweb-site
|
# 🌙 moonweb-site
|
||||||
|
|
||||||
Monorepo for hub.moonweb.org, infra.moonweb.org, smarthome.moonweb.org,
|
Monorepo for the **moonweb.org** homelab — five static sites built with [Eleventy](https://www.11ty.dev/), deployed to [Cloudflare Pages](https://pages.cloudflare.com/).
|
||||||
code.moonweb.org and retro.moonweb.org. cv (stefankoelle.de) stays external
|
|
||||||
(Cloudflare Free-Tier limits to 5 Pages projects per repository).
|
|
||||||
|
|
||||||
See `SPEC.md` for the full specification and `PLAN.md` for the phased
|
```
|
||||||
implementation plan. Cloudflare Free-Tier limits to 5 Pages projects per
|
hub.moonweb.org → 🏠 Central index & gateway
|
||||||
repository — cv (stefankoelle.de) stays external.
|
infra.moonweb.org → 🏗️ Infrastructure overview (Proxmox, Synology, Docker)
|
||||||
|
smarthome.moonweb.org → 🏡 Smart home projects & dashboards
|
||||||
|
code.moonweb.org → 💻 Curated GitHub project catalog
|
||||||
|
retro.moonweb.org → 🕹️ Physical retro hardware collection
|
||||||
|
```
|
||||||
|
|
||||||
## What is real vs. placeholder
|
> **External sites** (not in this monorepo): [stefankoelle.de](https://stefankoelle.de) (CV), [www.moonweb.org](https://www.moonweb.org) (2000s time capsule), [28k8.moonweb.org](https://28k8.moonweb.org) (90s BBS archive), [home.moonweb.org](https://home.moonweb.org) (Authelia-protected dashboard).
|
||||||
|
|
||||||
- Structure, layouts, themes, Eleventy configs, CI workflow: fully implemented.
|
---
|
||||||
- `code/_data/repos.json`: populated with real data pulled from the
|
|
||||||
`skoelle` GitHub account (public repos only, private repos like
|
|
||||||
`wetterapi` intentionally excluded from the public catalog).
|
|
||||||
- `infra/`, `smarthome/`: overview pages and detail pages with real content,
|
|
||||||
redacted per SPEC.md §6.
|
|
||||||
- `retro/`: intentionally minimal, per SPEC.md §5.
|
|
||||||
|
|
||||||
Note: stefankoelle.de (CV) is hosted separately and linked from the hub
|
## 📐 Architecture
|
||||||
and site-switcher — it is not part of this monorepo (Cloudflare Free-Tier
|
|
||||||
limits to 5 Pages projects per repository).
|
|
||||||
|
|
||||||
## Local development
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ GitHub Actions CI │
|
||||||
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
|
||||||
|
│ │ build:hub │ │build:infra│ │build:smart│ │build:… │ │
|
||||||
|
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └───┬────┘ │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ ▼ ▼ ▼ ▼ │
|
||||||
|
│ dist/hub/ dist/infra/ dist/smarthome/ dist/…/ │
|
||||||
|
└──────────────────────┬──────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌────────────────────────┐
|
||||||
|
│ Cloudflare Workers │
|
||||||
|
│ (5 Pages projects) │
|
||||||
|
└────────────────────────┘
|
||||||
|
│
|
||||||
|
┌──────────────┼──────────────┐
|
||||||
|
▼ ▼ ▼
|
||||||
|
hub.moonweb.org infra.moonweb.org …
|
||||||
|
```
|
||||||
|
|
||||||
Each site has its own minimal Eleventy config so you can preview one site
|
### Why 5 separate Cloudflare projects?
|
||||||
at a time:
|
|
||||||
|
Cloudflare Free-Tier limits to **5 Pages projects per repository**. Each subdomain (hub, infra, smarthome, code, retro) gets its own project. `stefankoelle.de` stays external to stay within this limit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ 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, low maintenance for 5 sites |
|
||||||
|
| **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, `theme-*.css` per domain accent color, no build step needed |
|
||||||
|
| **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) | Matrix build for all 5 sites, artifact upload, parallel deploy |
|
||||||
|
| **Deploy** | [Cloudflare Workers](https://workers.cloudflare.com/) | Static asset hosting via `wrangler pages deploy`, one worker per site |
|
||||||
|
| **DNS** | Cloudflare | Already managing DNS — zero additional setup for Pages custom domains |
|
||||||
|
| **GitHub Catalog** | Python aggregator | Reads `.moonweb.yml` from each repo, outputs `repos.json` |
|
||||||
|
| **Runtime** | Fully static | No server-side code, no containers, no database — pure HTML/CSS/JS |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Design System
|
||||||
|
|
||||||
|
### Header-consistent, content-flexible
|
||||||
|
|
||||||
|
- **Header is identical** across all home-section sites: site-switcher (hub · infra · smarthome · code · retro · cv), domain accent color, Lobster title font.
|
||||||
|
- **Index pages** use a shared card-grid layout with grouped sections.
|
||||||
|
- **Detail pages** keep the same header but use a freer layout below it (e.g., pin tables, API docs, photos in free arrangement).
|
||||||
|
|
||||||
|
### Accent colors
|
||||||
|
|
||||||
|
| Domain | Color | Hex |
|
||||||
|
|--------|-------|-----|
|
||||||
|
| hub | Neutral blue | `#3b6ea5` |
|
||||||
|
| infra | Grey-blue | `#99333A` |
|
||||||
|
| smarthome | Teal | `#1f8a8a` |
|
||||||
|
| code | Violet | `#3E5098` |
|
||||||
|
| retro | Warm brown | `#8a6d3b` |
|
||||||
|
|
||||||
|
### Emojis
|
||||||
|
|
||||||
|
Each card on index pages has an emoji for visual navigation — consistent across hub, infra, smarthome, code, and retro.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Local Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install # install Eleventy + deps
|
||||||
|
|
||||||
npm run dev:hub # http://localhost:8081
|
npm run dev:hub # http://localhost:8081
|
||||||
npm run dev:infra # http://localhost:8082
|
npm run dev:infra # http://localhost:8082
|
||||||
npm run dev:smarthome # http://localhost:8083
|
npm run dev:smarthome # http://localhost:8083
|
||||||
npm run dev:code # http://localhost:8084
|
npm run dev:code # http://localhost:8084
|
||||||
npm run dev:retro # http://localhost:8085
|
npm run dev:retro # http://localhost:8085
|
||||||
|
|
||||||
|
npm run dev # all 5 in parallel
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build
|
Each site has its own minimal Eleventy config (`<site>/eleventy.config.js`). Live reload is built in.
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build # builds all five Eleventy sites into dist/<site>/
|
npm run build # builds all 5 → dist/<site>/
|
||||||
|
npm run build:hub # build single site
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deploy
|
---
|
||||||
|
|
||||||
Handled entirely by `.github/workflows/build-deploy.yml` on push to `main`:
|
## 📦 Project Structure
|
||||||
builds all sites, then deploys each `dist/<site>` folder to its own
|
|
||||||
Cloudflare Pages project via `wrangler pages deploy`. See the workflow
|
|
||||||
file for the required repo secrets.
|
|
||||||
|
|
||||||
Note: Cloudflare Free-Tier limits to 5 Pages projects per repository —
|
```
|
||||||
cv (stefankoelle.de) stays external.
|
moonweb-site/
|
||||||
|
├── hub/ # 🏠 Central index & gateway
|
||||||
|
├── infra/ # 🏗️ Infra overview + 3 detail pages
|
||||||
|
│ ├── backup-strategy/
|
||||||
|
│ ├── monitoring/
|
||||||
|
│ └── dev-environment/
|
||||||
|
├── smarthome/ # 🏡 Smart home overview + 6 detail pages
|
||||||
|
│ ├── homematic-mqtt/
|
||||||
|
│ ├── tasmota-energy/
|
||||||
|
│ ├── balkonpi/
|
||||||
|
│ ├── airplay-audio/
|
||||||
|
│ ├── octoprint/
|
||||||
|
│ └── tubearchivist/
|
||||||
|
├── code/ # 💻 GitHub catalog
|
||||||
|
│ └── _data/repos.json # populated by the aggregator
|
||||||
|
├── retro/ # 🕹️ Retro hardware (WIP)
|
||||||
|
├── shared/ # 🔧 Shared components
|
||||||
|
│ ├── _includes/
|
||||||
|
│ │ ├── base.njk # base layout (header, site-switcher, footer)
|
||||||
|
│ │ └── card-grid.njk # card-grid template with emoji support
|
||||||
|
│ ├── base.css # shared CSS (layout, cards, typography)
|
||||||
|
│ └── theme-*.css # accent colors per domain
|
||||||
|
├── scripts/
|
||||||
|
│ └── github-aggregator/ # 🐍 Python: reads .moonweb.yml → repos.json
|
||||||
|
│ ├── aggregate.py
|
||||||
|
│ ├── example.moonweb.yml
|
||||||
|
│ └── README.md
|
||||||
|
├── .github/workflows/
|
||||||
|
│ └── build-deploy.yml # ⚙️ CI/CD: build + deploy to Cloudflare
|
||||||
|
├── DESIGN.md # 📋 Initial concept (German)
|
||||||
|
├── SPEC.md # 📋 Full specification (English, 159 lines)
|
||||||
|
├── PLAN.md # 📋 Implementation plan
|
||||||
|
├── TODO.md # 📋 Open items & workflow
|
||||||
|
└── package.json # npm scripts for dev/build
|
||||||
|
```
|
||||||
|
|
||||||
## GitHub aggregator (code.moonweb.org)
|
---
|
||||||
|
|
||||||
`scripts/github-aggregator/aggregate.py` reads a `.moonweb.yml` file from
|
## 🔄 CI/CD Pipeline
|
||||||
each of your GitHub repos and regenerates `code/_data/repos.json`. Run it
|
|
||||||
manually whenever you want to refresh the catalog — see SPEC.md §8 for the
|
Defined in `.github/workflows/build-deploy.yml`:
|
||||||
`.moonweb.yml` schema. It is *not* wired into CI; this is a deliberate,
|
|
||||||
manual step. cv (stefankoelle.de) is not included in this automation.
|
```
|
||||||
|
push to main
|
||||||
|
│
|
||||||
|
├── Build (matrix: hub, infra, smarthome, code, retro)
|
||||||
|
│ ├── checkout → setup-node (22) → npm ci
|
||||||
|
│ ├── npm run build:<site>
|
||||||
|
│ ├── validate dist/<site>/ exists & non-empty
|
||||||
|
│ └── upload artifact (7-day retention)
|
||||||
|
│
|
||||||
|
└── Deploy (matrix: 5 Cloudflare Workers)
|
||||||
|
├── download artifact
|
||||||
|
├── generate wrangler.toml
|
||||||
|
└── wrangler pages deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
**Required secrets:**
|
||||||
|
- `CLOUDFLARE_API_TOKEN` — Workers:Edit permission
|
||||||
|
- `CLOUDFLARE_ACCOUNT_ID` — Cloudflare account ID
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐍 GitHub Aggregator (code.moonweb.org)
|
||||||
|
|
||||||
|
`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 `code/_data/repos.json`
|
||||||
|
|
||||||
|
### `.moonweb.yml` schema
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
title: "MVG Departures"
|
||||||
|
category: code # code | smarthome | infra
|
||||||
|
subcategory: "Web Apps" # drives grouping on code.moonweb.org
|
||||||
|
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
|
||||||
|
export GITHUB_TOKEN=ghp_xxx
|
||||||
|
python scripts/github-aggregator/aggregate.py
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Deliberately manual** — no scheduled CI job. The catalog is refreshed on demand, not on every push.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📏 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 | Still WIP — honest minimal overview, no over-investment |
|
||||||
|
|
||||||
|
**Infra redaction rule:** Architecture-level only (Proxmox, Synology, Docker, VLAN concept). No concrete IPs, WireGuard keys, passwords, internal hostnames.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌍 Language
|
||||||
|
|
||||||
|
All five sites are written **entirely in English**. German source documents are translated once during migration (AI-assisted). New content is authored in English from the start.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Documentation
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `DESIGN.md` | Initial concept and design decisions (German) |
|
||||||
|
| `SPEC.md` | Complete specification — what gets built (English) |
|
||||||
|
| `PLAN.md` | Phased implementation plan |
|
||||||
|
| `TODO.md` | Open items, workflow, and current status |
|
||||||
|
| `README.md` | This file — project overview for GitHub |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 License
|
||||||
|
|
||||||
|
This project is for personal use. See [stefankoelle.de](https://stefankoelle.de) for contact.
|
||||||
|
|||||||
@@ -38,5 +38,13 @@ sections:
|
|||||||
summary: "The 2000s internet projects, networking and engineering."
|
summary: "The 2000s internet projects, networking and engineering."
|
||||||
href: "https://www.moonweb.org"
|
href: "https://www.moonweb.org"
|
||||||
emoji: "🌐"
|
emoji: "🌐"
|
||||||
|
- title: "inseco.de"
|
||||||
|
summary: "Internet services & consulting for gastronomy and clubs (2002–2009), with a custom PHP/CMS."
|
||||||
|
href: "https://inseco.de"
|
||||||
|
emoji: "🍽️"
|
||||||
|
- title: "aztec-project.org"
|
||||||
|
summary: ".NET developer blog and StupidDB – a simple file system object storage framework."
|
||||||
|
href: "https://aztec-project.org"
|
||||||
|
emoji: "🔷"
|
||||||
---
|
---
|
||||||
{% include "card-grid.njk" %}
|
{% include "card-grid.njk" %}
|
||||||
|
|||||||
Reference in New Issue
Block a user