[7jun2026] setting up self-hosted static org-mode website
Table of Contents
1. Problem
Want alternative publishing destination to https://rconybea.github.io/web/
2. Plan
Expand on rented droplet git hosting
| org-mode source | https://conybeare.us/git/org-howto |
| host html | /var/www/org-howto |
Ingredients:
| nginx | /etc/nginx/nginx.conf |
| env | https://conybeare.us/git/org-howto/shell.nix |
| script | https://conybeare.us/git/org-howto/bin/howto-publish |
2.1. Html Location
Provide a place for static html content
$ sudo mkdir -p /var/www/org-howto $ chown forgejo-runner:forgejo-runner /var/www/org-howto
2.2. Nginx
Add a new location to nginx configuration, inside the 443 server block
# /etc/nginx/nginx.conf events { } http { server { listen 443 ...; ... location /git/ { ... } location /web/ { alias /var/www/org-howto/; index index.html; } } }Tell nginx to reload its configuration
$ sudo systemctl reload nginx
2.3. Nix environment
Reproducible environment for batch-mode org2html pipeline.
# org-howto/shell.nix
{ pkgs ? import <nixpkgs> {} }:
let
emacs = (pkgs.emacsPackagesFor pkgs.emacs30).emacsWithPackages (ep: [
ep.htmlize
]);
in
pkgs.mkShell {
buildInputs = [ emacs ];
}
Relying on htmlize for highlighting e.g. in bash source blocks.
2.4. Publishing script
Simple bash script for now.
org-howto/bin/howto-publish:
#!/usr/bin/env bash set -euo pipefail src_dir="$(cd "$(dirname "$0")/.." && pwd)" dest_dir="${1:?usage: howto-publish DEST_DIR}" mkdir -p "${dest_dir}" emacs --batch \ --eval "(require 'ox-publish)" \ --eval "(setq org-publish-project-alist '((\"org-howto\" :components (\"org-howto-notes\" \"org-howto-static\")) (\"org-howto-notes\" :base-directory \"${src_dir}\" :base-extension \"org\" :publishing-directory \"${dest_dir}\" :recursive t :publishing-function org-html-publish-to-html :auto-preamble t) (\"org-howto-static\" :base-directory \"${src_dir}\" :base-extension \"css|html|js|svg|ico|png|jpg|gif|pdf\" :publishing-directory \"${dest_dir}\" :recursive t :publishing-function org-publish-attachment)))" \ --eval "(org-publish \"org-howto\" t)"
2.5. Runner setup
We already have a self-hosted runner for https://conybeare.us/git, with persistent /nix/store access.
All that remains is to give that runner a new workflow:
#+begin_src yaml
name: Deploy
on: push: branches: [main]
jobs: publish: runs-on: host steps:
- name: Setup PATH run: | echo "nix/var/nix/profiles/default/bin" >> $GITHUB_PATH echo "/var/lib/forgejo-runner.nix-profile/bin" >> $GITHUB_PATH
- name: checkout run: | git clone –quiet –depth=1 $GITHUB_SERVER_URL/roland/org-howto.git .
- name: publish run: | nix-shell shell.nix –run "./bin/howto-publish /var/www/org-howto"
#+end_src yaml