commit - 1e8bbfd29490bbfdcd5b60871d37a7b660b7db72
commit + 5eea0e0d740ad0e56fb262cfa2434369e9df6a3e
blob - 788891334100a2237867cf6af095160e0ab198f0
blob + f4be7b5091f28e4bbe44252e58a633020d2ca517
--- .ssg.template
+++ .ssg.template
<!DOCTYPE html>
<html lang="en">
-<head>
-<meta charset="utf-8">
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<link rel="stylesheet" href="/style.css">
-<title>{{#title}}{{title}} — {{/title}}wiki.voidq.xyz</title>
-</head>
-<body>
-<nav>
-<a href="/">home</a>
-<a href="/about.html">about</a>
-</nav>
-<main>
-{{content}}
-</main>
-<footer>wiki.voidq.xyz — got + ssg + lowdown</footer>
-</body>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="/style.css">
+ <title>{{#title}}{{title}} — {{/title}}wiki.voidq.xyz</title>
+ </head>
+ <body>
+ <nav>
+ <a href="/">home</a>
+ <a href="/about.html">about</a>
+ </nav>
+ <main>
+ {{content}}
+ </main>
+ <footer>wiki.voidq.xyz — got + ssg + lowdown</footer>
+ </body>
</html>
blob - /dev/null
blob + 3ac59a23e5c2cba03aaf24818136cd9f78be5686 (mode 644)
--- /dev/null
+++ guides/wiki-setup.md
+# how to build this wiki
+
+a minimal wiki running on openbsd using got, ssg, and lowdown.
+no database. no php. no runtime process at the web layer.
+
+---
+
+## what you need
+
+- an openbsd vps with a domain pointing to it
+- let's encrypt certificates via acme-client(8)
+- nsd(8) for dns
+- relayd(8) and httpd(8) already configured for tls
+
+---
+
+## stack overview
+
+| tool | purpose |
+|------|---------|
+| gotd | git server daemon, receives pushes over ssh |
+| got | version control client, used locally |
+| ssg | posix shell static site generator |
+| lowdown | markdown to html converter, written in c |
+| httpd | serves static html files |
+| relayd | tls termination and http redirect |
+| cron | triggers rebuild every minute |
+
+nothing runs at request time. every page is pre-built html.
+
+---
+
+## step 1 — install packages on the server
+
+only two packages needed:
+
+ doas pkg_add gotd lowdown
+
+install ssg — a single shell script, no package required:
+
+ ftp -Vo ~/bin/ssg.sh https://romanzolotarev.com/ssg/ssg.sh
+ chmod +x ~/bin/ssg.sh
+ doas cp ~/bin/ssg.sh /usr/local/bin/ssg
+
+verify:
+
+ ssg
+ # usage: ssg.sh <src> <dst>
+
+---
+
+## step 2 — set up gotd
+
+gotd(8) is the git server. it speaks ssh, uses pledge(2) and unveil(2),
+and requires no git package.
+
+create the bare repository:
+
+ doas mkdir -p /var/got/wiki.git
+ doas chown -R _gotd:_gotd /var/got
+ doas -u _gotd got init /var/got/wiki.git
+
+write /etc/gotd.conf:
+
+ user _gotd
+ listen on "/var/run/gotd.sock"
+
+ repository "wiki" {
+ path "/var/got/wiki.git"
+ permit rw yourusername
+ notify {
+ email to you@example.com
+ email to root
+ }
+ }
+
+check config and enable:
+
+ doas gotd -n
+ doas rcctl enable gotd
+ doas rcctl start gotd
+
+add to /etc/ssh/sshd_config:
+
+ AcceptEnv GOT_PROTO_VERSION
+
+restart sshd:
+
+ doas rcctl restart sshd
+
+---
+
+## step 3 — prepare directories
+
+ doas mkdir -p /var/www/wiki/src
+ doas mkdir -p /var/www/wiki/dst
+ doas chown -R _gotd:_gotd /var/www/wiki
+
+check out the initial worktree as _gotd:
+
+ doas -u _gotd got checkout /var/got/wiki.git /var/www/wiki/src
+
+---
+
+## step 4 — the rebuild script
+
+create /usr/local/bin/wiki-rebuild:
+
+ #!/bin/sh
+ set -e
+ cd /var/www/wiki/src
+ got update -q
+ /usr/local/bin/ssg /var/www/wiki/src /var/www/wiki/dst
+
+make it executable:
+
+ doas chmod +x /usr/local/bin/wiki-rebuild
+
+note: this version of gotd does not support exec in notify blocks.
+a cron job triggers the rebuild instead.
+
+add to crontab:
+
+ crontab -e
+
+add this line:
+
+ * * * * * /usr/local/bin/wiki-rebuild >> /var/log/wiki-rebuild.log 2>&1
+
+---
+
+## step 5 — configure httpd
+
+write /etc/httpd.conf:
+
+ server "wiki.voidq.xyz" {
+ listen on 127.0.0.1 port 8080
+ root "/wiki/dst"
+ gzip-static
+ }
+
+---
+
+## step 6 — configure relayd
+
+add to /etc/relayd.conf:
+
+ http protocol "wiki" {
+ tls { no client-renegotiation }
+ match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
+ match request header set "X-Forwarded-Proto" value "https"
+ }
+
+ relay "wiki_https" {
+ listen on egress port 443 tls \
+ certificate "/etc/ssl/wiki.voidq.xyz.fullchain.pem" \
+ key "/etc/ssl/private/wiki.voidq.xyz.key"
+ protocol "wiki"
+ forward to 127.0.0.1 port 8080
+ }
+
+ relay "wiki_http" {
+ listen on egress port 80
+ protocol http
+ block return 301 "https://wiki.voidq.xyz$REQUEST_URI"
+ }
+
+enable and restart:
+
+ doas rcctl enable httpd relayd
+ doas rcctl restart httpd relayd
+
+---
+
+## step 7 — local setup
+
+install got on your local machine:
+
+ pkg_add got
+
+set your author identity:
+
+ echo 'export GOT_AUTHOR="Your Name <you@example.com>"' >> ~/.profile
+ . ~/.profile
+
+clone the repository from the server:
+
+ got clone ssh://yourusername@wiki.voidq.xyz/wiki ~/wiki
+ cd ~/wiki
+
+---
+
+## step 8 — create the template
+
+ssg wraps every markdown page with .ssg.template.
+create ~/wiki/.ssg.template:
+
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="/style.css">
+ <title>{{#title}}{{title}} — {{/title}}wiki.voidq.xyz</title>
+ </head>
+ <body>
+ <nav>
+ <a href="/">home</a>
+ <a href="/about.html">about</a>
+ <a href="/guides/wiki-setup.html">wiki setup</a>
+ </nav>
+ <main>
+ {{content}}
+ </main>
+ <footer>wiki.voidq.xyz — got + ssg + lowdown</footer>
+ </body>
+ </html>
+
+---
+
+## step 9 — create style.css
+
+create ~/wiki/style.css:
+
+ *,*::before,*::after{box-sizing:border-box}
+ body{
+ background:#1a1a18;
+ color:#b4b09c;
+ font-family:'Courier New',Courier,monospace;
+ font-size:15px;
+ line-height:1.7;
+ max-width:680px;
+ margin:2rem auto;
+ padding:0 1.5rem;
+ }
+ a{color:#8ab4a0;text-decoration:underline}
+ a:hover{color:#b8d4c0}
+ nav{
+ font-size:13px;
+ margin-bottom:2.5rem;
+ padding-bottom:1rem;
+ border-bottom:1px solid #2e2e2a;
+ }
+ nav a{color:#7a9e8a;text-decoration:none;margin-right:1.2rem}
+ nav a:hover{color:#a8c8b4}
+ h1{font-size:1.3rem;font-weight:normal;color:#e8e4d0;margin:0 0 1.5rem}
+ h2{font-size:1rem;font-weight:normal;color:#a8a494;margin:2rem 0 .75rem}
+ h3{font-size:.95rem;font-weight:normal;color:#8a8678;margin:1.5rem 0 .5rem}
+ p{margin:0 0 1rem;color:#b4b09c}
+ pre{
+ background:#111110;
+ border:1px solid #2a2a26;
+ padding:1rem;
+ overflow-x:auto;
+ border-radius:3px;
+ font-size:13px;
+ color:#8ab47a;
+ margin:1rem 0;
+ }
+ code{
+ background:#111110;
+ border:1px solid #242420;
+ padding:.1em .35em;
+ border-radius:2px;
+ font-size:13px;
+ color:#8ab47a;
+ }
+ pre code{border:none;padding:0;background:transparent}
+ ul,ol{padding-left:1.2rem;color:#b4b09c;margin:0 0 1rem}
+ li::marker{color:#4a4a42}
+ blockquote{
+ border-left:2px solid #3a3a34;
+ margin:1rem 0;
+ padding:.5rem 1rem;
+ color:#7a7a6e;
+ }
+ table{border-collapse:collapse;width:100%;margin:1rem 0;font-size:14px}
+ th{text-align:left;color:#6a6a5e;border-bottom:1px solid #2e2e2a;padding:.4rem .6rem}
+ td{padding:.4rem .6rem;border-bottom:1px solid #222220;color:#b4b09c}
+ hr{border:none;border-top:1px solid #2e2e2a;margin:2rem 0}
+ footer{
+ margin-top:3rem;
+ padding-top:1rem;
+ border-top:1px solid #2e2e2a;
+ font-size:12px;
+ color:#4a4a42;
+ }
+
+---
+
+## step 10 — first commit and push
+
+ cd ~/wiki
+ got add .
+ got commit -m "initial wiki"
+ got send
+
+within one minute cron runs wiki-rebuild and the site goes live.
+visit https://wiki.voidq.xyz to confirm.
+
+---
+
+## daily workflow
+
+edit an existing page:
+
+ vi index.md
+ got commit -m "update index"
+ got send
+
+add a new page:
+
+ vi guides/newpage.md
+ got add guides/newpage.md
+ got commit -m "add newpage"
+ got send
+
+view history:
+
+ got log
+
+see what changed before committing:
+
+ got diff
+
+force a full rebuild on the server (if something looks stale):
+
+ doas -u _gotd rm -rf /var/www/wiki/dst/*
+ doas -u _gotd /usr/local/bin/wiki-rebuild
+
+---
+
+## troubleshooting
+
+check all services are running:
+
+ doas rcctl check gotd httpd relayd
+
+check httpd error log:
+
+ doas tail /var/www/logs/error.log
+
+check rebuild log:
+
+ tail /var/log/wiki-rebuild.log
+
+check worktree is in sync:
+
+ cd /var/www/wiki/src && got status
+
+check dst was populated:
+
+ ls /var/www/wiki/dst/
+
+stale gzip files — force full rebuild:
+
+ doas -u _gotd rm -rf /var/www/wiki/dst/*
+ doas -u _gotd /usr/local/bin/wiki-rebuild
+
+---
+
+## what runs on the server at request time
+
+nothing. httpd serves pre-built static files directly.
+the only active processes are gotd (ssh), httpd, and relayd.
+no interpreter, no database, no application server.
+
+---
+
+## see also
+
+- [got(1)](https://gameoftrees.org)
+- [ssg](https://romanzolotarev.com/ssg/)
+- [lowdown](https://kristaps.bsd.lv/lowdown/)
+- [httpd(8)](https://man.openbsd.org/httpd.8)
+- [relayd(8)](https://man.openbsd.org/relayd.8)
+- [gotd(8)](https://man.openbsd.org/gotd.8)
+- [gotd.conf(5)](https://man.openbsd.org/gotd.conf.5)