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