cmc/cleberg.net

My personal web garden & blog.

clone: git clone https://gitbay.org/cmc/cleberg.net.git

main: README.md · raw

  1# cleberg.net
  2
  3This repository holds the files for [cleberg.net](https://cleberg.net),
  4a static-site with blog posts, personal links, and more.
  5
  6This site uses [orgo](https://github.com/krazywarez/orgo) to build the
  7static site.
  8
  9## Site Structure
 10
 11I write content pages (e.g., blog posts) in org-mode and templates in
 12HTML. orgo builds these files into a static site, and then I deploy
 13them to a web server.
 14
 15The main site components are:
 16
 17- Org source files in `content/`, containing blog posts and pages.
 18  That directory is the site's URL root: `content/blog/post.org`
 19  publishes at `/blog/post.html`.
 20- A configuration file (`content/orgo.toml`) that specifies the base
 21  URL, navigation, templates, and the generated pages (home, blog and
 22  garden indexes, tags, and the RSS feed).
 23- HTML templates in `content/templates/`.
 24- Assets such as images and style sheets, located in designated
 25  subdirectories. `theme/static/` is published at `/`.
 26- Utility scripts (e.g., `build.py`) to facilitate building and
 27  deployment.
 28
 29## Dependencies
 30
 31The publishing system depends on:
 32
 33- [orgo](https://github.com/krazywarez/orgo), the static site
 34  generator, installed with `cargo install --git
 35  https://github.com/krazywarez/orgo`.
 36- `rsync` for deployment.
 37- [uv](https://github.com/astral-sh/uv) to run `build.py`.
 38
 39## Configuration
 40
 41You can customize site settings within the `content/orgo.toml` file.
 42This file establishes key variables such as:
 43
 44- The base URL for links.
 45- Which pages appear in the navigation, and in what order.
 46- Per-directory template rules.
 47- The collections that generate the indexes, tag pages, and feed.
 48
 49Users intending to modify site parameters should review and edit this
 50file accordingly. The orgo documentation contains extensive details on
 51configuration options and expected formats.
 52
 53## Setup Instructions
 54
 55To obtain a working copy of this repository, execute the following
 56commands within a shell environment or Emacs shell interface:
 57
 58``` shell
 59git clone https://github.com/ccleberg/cleberg.net
 60cd cleberg.net
 61emacs -nw
 62```
 63
 64For users employing Doom Emacs, open any repository Org file using
 65`SPC f f` to access the content.
 66
 67## Building and Publishing the Site
 68
 69The `build.py` script wraps the build: it runs orgo, and then either
 70deploys the result or serves it locally.
 71
 72Environment variables control what it does, and all default to off:
 73
 74- `BUILD=true` performs the build.
 75- `DEPLOY=true` deploys in production, or starts a development server
 76  on port 8000 otherwise.
 77- `ENV=prod` selects production: image URLs are rewritten to be
 78  root-relative (see Deployment below) and the `ruff` pass is skipped.
 79  Anything else builds for development.
 80- `DRY_RUN=true` turns a production deploy into a report. Production
 81  only; ignored everywhere else.
 82
 83Exactly one combination writes to the server:
 84
 85| `ENV`  | `BUILD` | `DEPLOY` | `DRY_RUN` | What happens                          | Output       | Server            |
 86|--------|---------|----------|-----------|---------------------------------------|--------------|-------------------|
 87| unset  | `true`  | —        | —         | Development build, `ruff` first       | `.build-dev/`| Untouched         |
 88| unset  | `true`  | `true`   | —         | Development build, then serve on :8000| `.build-dev/`| Untouched         |
 89| `prod` | `true`  | —        | —         | Production build and image rewrite    | `.build/`    | Untouched         |
 90| `prod` | —       | `true`   | `true`    | Reports what a deploy would change    | —            | Read only         |
 91| `prod` | `true`  | `true`   | —         | Production build, then deploy         | `.build/`    | **Overwritten**   |
 92
 93``` shell
 94# Development build:
 95BUILD=true uv run build.py
 96
 97# Development build, then serve it on localhost:8000:
 98BUILD=true DEPLOY=true uv run build.py
 99
100# Production build, no deploy:
101ENV=prod BUILD=true uv run build.py
102
103# What would a deploy change? Connects, compares, transfers nothing:
104ENV=prod DEPLOY=true DRY_RUN=true uv run build.py
105
106# Production build and deploy. This is the one that writes to the server:
107ENV=prod BUILD=true DEPLOY=true uv run build.py
108```
109
110Generated site files reside in `.build/` for production and
111`.build-dev/` for development.
112
113The deploy is `rsync --delete-before`, so files the build no longer
114produces are removed from the server. That is what makes the dry run
115worth having: a build that silently produced fewer pages would quietly
116delete the rest. Lines beginning `*deleting` in the dry-run output are
117what the real deploy would remove.
118
119Builds are incremental: orgo keeps an `.orgo-cache.json` inside the
120output directory and re-renders only what changed, so the directory is
121left in place between runs. Delete it for a clean build. The two
122environments use separate directories because production rewrites image
123URLs in the output and development does not.
124
125orgo can also build and preview on its own, without `build.py`:
126
127``` shell
128orgo serve content -o /tmp/preview
129```
130
131## Deployment
132
133Production builds rewrite image URLs to root-relative ones
134(`/img/blog/...`) instead of absolute `https://img.cleberg.net/` ones so
135the site renders standalone on the onion service without fetching assets
136off-onion. The stylesheet is already same-origin.
137
138This means the web server must serve the image store at `/img/` on the
139`cleberg.net` vhost. The images live at `/var/www/img/` (their own host,
140`img.cleberg.net`); expose them under `cleberg.net/img/` with a symlink:
141
142``` shell
143ln -s /var/www/img /var/www/cleberg.net/img
144```
145
146Without this, images 404 in production. Development builds keep the
147absolute `img.cleberg.net` URLs, so local previews load images from the
148live host and need no symlink.
149
150Once assets are same-origin, the vhost CSP can tighten `img-src`,
151`style-src`, and `font-src` back to `'self'`, and drop `bubbles.town`
152from `script-src`/`connect-src` (the vote widget was removed; only a
153plain link to Bubbles remains). After deploying, purge the Cloudflare
154cache (responses carry a 31-day `max-age`).
155
156## Creating New Blog Posts
157
158To add new blog content, follow this procedure within Emacs:
159
1601.  Open a new Org file (via `C-x C-f` or Doom\'s `SPC f f`).
1612.  Insert the contents of the post template with `C-x i`, sourcing from
162    `utils/template.org`.
1633.  Modify the new file as needed to add post content and metadata.
164
165This method streamlines content creation by reusing a preformatted
166template.