]> zackmdavis.net Git - An_Algorithmic_Lucidity.git/commitdiff
provisioning
authorZack M. Davis <code@zackmdavis.net>
Thu, 16 Jul 2026 02:06:43 +0000 (19:06 -0700)
committerZack M. Davis <code@zackmdavis.net>
Thu, 16 Jul 2026 02:06:43 +0000 (19:06 -0700)
provisioning/nginx_aal_month_map.conf [new file with mode: 0644]
provisioning/nginx_common_expires_map.conf [new file with mode: 0644]
provisioning/nginx_siteconf [new file with mode: 0644]
provisioning/robots.txt [new file with mode: 0644]
provisioning/root_index.html [new file with mode: 0644]
publishconf.py

diff --git a/provisioning/nginx_aal_month_map.conf b/provisioning/nginx_aal_month_map.conf
new file mode 100644 (file)
index 0000000..4320306
--- /dev/null
@@ -0,0 +1,40 @@
+# Translates the old WordPress site's two-digit month URLs
+# (/blog/2011/12/some-post/) onto Pelican's %b abbreviation
+# (/blog/2011/Dec/some-post/), matching ARTICLE_URL / MONTH_ARCHIVE_SAVE_AS
+# in pelicanconf.py. Referenced from the "location ~ ^/blog/..." redirect
+# block in nginx_siteconf.
+#
+# This is an aAL-specific legacy-URL concern (WordPress's permalink
+# structure), not a generally-shared one like nginx_common_expires_map.conf,
+# so the map name is namespaced ($aal_month_abbrev) rather than generic --
+# no reason another blog sharing this server would need an identically-named
+# map, but no reason to risk a collision either.
+#
+# Included once from nginx.conf's http{} block (map directives can't live
+# inside a server{} block).
+#
+# Keyed on $2 (the location regex's second capture group in nginx_siteconf),
+# not a named capture -- conf.d/*.conf loads before sites-enabled/* in
+# nginx.conf, so at the point this map is parsed, nginx doesn't yet know
+# about a named capture a later location block would define. $1-$9 are
+# built-in nginx variables, always predeclared, so they don't have that
+# ordering problem.
+map $2 $aal_month_abbrev {
+    # Passes unrecognized input through unchanged, so a URL with a
+    # malformed month degrades to an ordinary 404 rather than a redirect to
+    # a broken location.
+    default $2;
+
+    01 Jan;
+    02 Feb;
+    03 Mar;
+    04 Apr;
+    05 May;
+    06 Jun;
+    07 Jul;
+    08 Aug;
+    09 Sep;
+    10 Oct;
+    11 Nov;
+    12 Dec;
+}
diff --git a/provisioning/nginx_common_expires_map.conf b/provisioning/nginx_common_expires_map.conf
new file mode 100644 (file)
index 0000000..a0b2eca
--- /dev/null
@@ -0,0 +1,13 @@
+# Shared across all sites on a box (nginx errors on a duplicate `map` name
+# within the same http{} context) -- included once, from nginx.conf's http{}
+# block, not from any individual site's config. Kept as an identical copy in
+# each blog's own provisioning/ so each repo stays independently rebuildable;
+# only one of those copies is the one actually `include`d on a given server.
+#
+# Forces HTML responses to always revalidate (since a post's URL stays the
+# same across edits/redeploys, so a cached page could otherwise go stale
+# silently) while leaving normal caching behavior for everything else.
+map $sent_http_content_type $expires {
+    default                    off;
+    text/html                  epoch;
+}
diff --git a/provisioning/nginx_siteconf b/provisioning/nginx_siteconf
new file mode 100644 (file)
index 0000000..88ae4fc
--- /dev/null
@@ -0,0 +1,92 @@
+# $expires is defined by nginx_common_expires_map.conf, and $aal_month_abbrev
+# by nginx_aal_month_map.conf, both included once from nginx.conf's http{}
+# block (not here -- see those files for why).
+
+server {
+        listen 80;
+        listen [::]:80;
+
+        server_name zackmdavis.net www.zackmdavis.net;
+
+        expires $expires;
+
+        # The domain root is a small standalone landing page (plus docs/ and
+        # temporary/ carried over from the old NameCheap hosting) -- not part
+        # of the Pelican blog, which lives under /blog instead.
+        root /home/blogmistress/zackmdavis.net;
+        index index.html;
+
+        location / {
+            try_files $uri $uri/ =404;
+        }
+
+        location /docs {
+            autoindex on;
+        }
+
+        location /temporary {
+            autoindex on;
+        }
+
+        # Legacy WordPress URL compatibility, so old inbound/indexed links
+        # don't just 404 after the switch to Pelican.
+
+        # feed/rss/ and feed/atom/ are real generated directories now (see
+        # FEED_ALL_RSS/FEED_ALL_ATOM in publishconf.py), each handled by the
+        # ordinary /blog/ location's index.xml fallback below -- no special
+        # casing needed for either. But the bare .../feed/ (WordPress's old
+        # single-format URL, still what existing subscribers have bookmarked)
+        # has nothing to fall back to now that it's just two subdirectories,
+        # so it needs an explicit default: RSS, matching what /feed/ used to
+        # mean. Covers both the site-wide and per-category feeds.
+        location ~ "^(.*/feed)/$" {
+            return 301 $1/rss/;
+        }
+
+        # WordPress's permalinks were /blog/YYYY/MM/slug/ (two-digit month);
+        # Pelican's are /blog/YYYY/Mon/slug/ (see ARTICLE_URL in
+        # pelicanconf.py). A regex location takes precedence over the plain
+        # prefix location below regardless of ordering, so this only needs
+        # to exist, not to come first.
+        location ~ "^/blog/(\d{4})/(\d{2})/(.*)$" {
+            return 301 /blog/$1/$aal_month_abbrev/$3;
+        }
+
+        # location /blog/ below requires the trailing slash to match (it's
+        # what makes the alias line up), so the bare /blog on its own would
+        # otherwise fall through to location / above and 404.
+        location = /blog {
+            return 301 /blog/;
+        }
+
+        # The Pelican-generated blog itself. alias (not root) strips the
+        # /blog/ prefix so it maps onto the output directory's own top level,
+        # since Pelican has no idea it's being served from a subpath.
+        #
+        # index.xml as a second index fallback: feed directories (feed/,
+        # category/{slug}/feed/) contain only index.xml, no index.html, so
+        # this serves the feed directly at the bare directory URL --
+        # matching WordPress's own /feed/ format, with no redirect needed --
+        # while ordinary content directories are untouched since index.html
+        # always exists there and is tried first.
+        location /blog/ {
+            alias /home/blogmistress/An_Algorithmic_Lucidity/output/;
+            index index.html index.xml;
+            try_files $uri $uri/ =404;
+        }
+
+        location /blog/source {
+            alias /usr/share/gitweb/;
+            add_header X-Robots-Tag "noindex";
+            include fastcgi_params;
+            gzip off;
+            fastcgi_param SCRIPT_FILENAME /usr/share/gitweb/gitweb.cgi;
+            fastcgi_param GITWEB_CONFIG /etc/gitweb.conf;
+            fastcgi_pass  unix:/run/fcgiwrap.socket;
+        }
+
+        location /blog/static { # gitweb static files
+            alias /usr/share/gitweb/static/;
+            try_files $uri $uri/ =404;
+        }
+}
diff --git a/provisioning/robots.txt b/provisioning/robots.txt
new file mode 100644 (file)
index 0000000..cb10b4b
--- /dev/null
@@ -0,0 +1,3 @@
+User-Agent: *
+Content-Signal: search=yes, ai-input=yes, ai-train=yes
+Allow: /
diff --git a/provisioning/root_index.html b/provisioning/root_index.html
new file mode 100644 (file)
index 0000000..922af2a
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Zack M. Davis</title>
+<style type="text/css">
+
+
+p {
+position: relative;
+left: 10px;
+}
+
+table.box {
+margin-left:auto;
+margin-right:auto;
+border-width: 10px;
+border-spacing: 2px;
+border-style: ridge;
+border-color: rgb(104, 0, 173);
+border-collapse: separate;
+background-color: white;
+}
+table.box th {
+border-width: 4px;
+padding: 1px;
+border-style: none;
+border-color: white;
+background-color: white;
+-moz-border-radius: ;
+}
+table.box td {
+border-width: 4px;
+padding: 1px;
+border-style: none;
+border-color: white;
+background-color: white;
+-moz-border-radius: ;
+}</style>
+</head>
+<body bgcolor="#A777AB">
+<table class="box" border="10" width="400">
+<tbody>
+<tr>
+<td>
+<h1 align="center">Zack M. Davis</h1>
+<p align="center">my blog: <a href="blog"><em>An Algorithmic Lucidity</em></a></p>
+
+<p align="center">Elsewhere:<br />
+<a href="https://github.com/zackmdavis">GitHub</a><br />
+</p></td></tr></tbody></table>
+</body>
+</html>
+</content>
index 370438946c389ee27874f4bbdc78100aaaa18000..a6a1b34380615b3b55cbeee78b26cd22ee8eb6d4 100644 (file)
@@ -20,13 +20,14 @@ from pelicanconf import *
 # things like previewing over plain HTTP before a certificate exists.
 SITEURL = '/blog'
 
-# RSS (not Atom) to match the existing WordPress feed's format at
-# zackmdavis.net/blog/feed/. The output path is feed/index.xml rather than
-# a bare feed/ so it's a real static file; getting the URL down to exactly
-# /feed/ (no filename) needs a webserver directory-index or redirect rule,
-# which depends on whatever we end up hosting on.
-FEED_ALL_RSS = 'feed/index.xml'
-CATEGORY_FEED_RSS = 'category/{slug}/feed/index.xml'
+# Both RSS and Atom, at parallel paths (.../feed/rss/ and .../feed/atom/).
+# RSS keeps the WordPress-era /feed/ as its bare-directory default (an
+# nginx redirect, see provisioning/nginx_siteconf) since that's what
+# existing subscribers' bookmarks expect; Atom is new.
+FEED_ALL_RSS = 'feed/rss/index.xml'
+CATEGORY_FEED_RSS = 'category/{slug}/feed/rss/index.xml'
+FEED_ALL_ATOM = 'feed/atom/index.xml'
+CATEGORY_FEED_ATOM = 'category/{slug}/feed/atom/index.xml'
 
 # Feed readers fetch feed XML out of any page context, so its content
 # ideally wants absolute URLs -- but Pelican only uses FEED_DOMAIN for the