<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="/simple-atom.xslt"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
  <title>joshua.seigler.net - selfhosting</title>
  <subtitle>Personal homepage of Joshua Seigler</subtitle>
  <link href="https://joshua.seigler.net/feeds/selfhosting.xml" rel="self" />
  <link href="https://joshua.seigler.net/" />
  <updated>2026-07-06T00:00:00Z</updated>
  <id>https://joshua.seigler.net/</id>
  <author>
    <name></name>
  </author>
    <entry>
      <title>I made myself a Recipe Label Generator</title>
      <link href="https://joshua.seigler.net/posts/i-made-myself-a-recipe-label-generator/" />
      <updated>2026-07-02T00:00:00Z</updated>
      <id>https://joshua.seigler.net/posts/i-made-myself-a-recipe-label-generator/</id>
      <content type="html">&lt;p&gt;I have been dissatisfied with some of the recipe label generators online (except for &lt;a href=&quot;https://tools.myfooddata.com/nutrition-facts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MyFoodData&lt;/a&gt;, which is fantastic, but I wanted something simpler, purpose-built for my site). I also wanted a small personal software project to preserve my familiarity with &lt;a href=&quot;https://www.solidjs.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SolidJS&lt;/a&gt;. So I made &lt;a href=&quot;https://recipelabels.pages.seigler.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;my own recipe label generator&lt;/a&gt;. (Since one purpose of this project is skill-building, of course I did this without an LLM.)&lt;/p&gt;
&lt;p&gt;I used &lt;a href=&quot;https://docs.solidjs.com/solid-start&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SolidStart&lt;/a&gt; to scaffold an empty SolidJS TypeScript project with Vite. I downloaded the “SR Legacy” data set from &lt;a href=&quot;https://fdc.nal.usda.gov/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;the USDA FoodData Central site&lt;/a&gt;. This data set is fairly complete, but it’s still small enough that I can serve and load a condensed version for fully client-side lookups. I used &lt;a href=&quot;https://www.fusejs.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;FuseJS&lt;/a&gt; to search this data set - its tuneable fuzzy search and small bundle size were perfect for the project’s needs.&lt;/p&gt;
&lt;p&gt;This was my first experience with &lt;a href=&quot;https://docs.solidjs.com/concepts/stores&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SolidJS stores&lt;/a&gt;, and I found the developer experience wonderful. It turned out to be an efficient and simple way to reactively manage the dynamic form state I required.&lt;/p&gt;
&lt;p&gt;I adapted &lt;a href=&quot;https://stackoverflow.com/a/73848584&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;a fraction-parsing script&lt;/a&gt; from StackExchange user &lt;code&gt;machineghost&lt;/code&gt; to allow the quantity to be written as a mixed fraction. And that was it. You can see the results at the bottom of my &lt;a href=&quot;https://joshua.seigler.net/recipes/bread-pudding&quot;&gt;bread pudding&lt;/a&gt; and &lt;a href=&quot;https://joshua.seigler.net/recipes/breakfast-strata&quot;&gt;breakfast strata&lt;/a&gt; posts.&lt;/p&gt;
&lt;h3 id=&quot;recipe-label-maker&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/i-made-myself-a-recipe-label-generator/#recipe-label-maker&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; &lt;a href=&quot;https://recipelabels.pages.seigler.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Recipe Label Maker&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://git.apps.seigler.net/joshua/recipelabels.pages.seigler.net&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Source code&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It could be interesting to try to parse an entire pasted ingredients list. I would need to fabricate simplified alternatives to the FoodData food names (e.g. “milk” -&amp;gt; “Milk, whole, 3.25% milkfat, with added vitamin D”) and have a good way to disambiguate less obvious ingredients. Ideally this could be accomplished client-side as well, without integrating the Everything Tool (tokenization, vector embeddings). A task for another day.&lt;/p&gt;
</content>
    </entry>
    <entry>
      <title>My Very Own GitHub Pages</title>
      <link href="https://joshua.seigler.net/posts/my-very-own-github-pages/" />
      <updated>2025-06-15T00:00:00Z</updated>
      <id>https://joshua.seigler.net/posts/my-very-own-github-pages/</id>
      <content type="html">&lt;p&gt;I recently started self-hosting &lt;a href=&quot;https://forgejo.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Forgejo&lt;/a&gt;, but I wanted something to replace GitHub pages, which has been very convenient for publishing little website projects. My server runs Debian, so I decided to use &lt;a href=&quot;https://github.com/adnanh/webhook&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;webhook&lt;/a&gt; and &lt;a href=&quot;https://caddyserver.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Caddy&lt;/a&gt;. I’m very happy how it turned out.&lt;/p&gt;
&lt;h2 id=&quot;the-objective&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#the-objective&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; The objective&lt;/h2&gt;
&lt;p&gt;When I push a &lt;code&gt;gh-pages&lt;/code&gt; branch to any public repository on my Forgejo instance, the name of the repo is used as a domain name (e.g. &lt;a href=&quot;https://marklink.pages.seigler.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;marklink.pages.seigler.net&lt;/a&gt;) and the branch contents are automatically served with SSL. If I push updates to the branch, they are automatically published. If the branch or repo is deleted, the site is taken down.&lt;/p&gt;
&lt;h2 id=&quot;how-to-do-it&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#how-to-do-it&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; How to do it&lt;/h2&gt;
&lt;h3 id=&quot;debian-server-preparation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#debian-server-preparation&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Debian server preparation&lt;/h3&gt;
&lt;p&gt;In case you don’t have a basic server setup routine yet, this is a good start:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change the default root password.&lt;/li&gt;
&lt;li&gt;Create a new user and add it to the sudo group. In my examples below the user is &lt;code&gt;joshua&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;ssh-copy-id&lt;/code&gt; to install your ssl pubkey for easier login.&lt;/li&gt;
&lt;li&gt;Disable/lock root’s password.&lt;/li&gt;
&lt;li&gt;Disable root login over ssh and change the SSL port number. Pick a new port lower than 1024.&lt;/li&gt;
&lt;li&gt;Edit your local &lt;code&gt;~/.ssh/config&lt;/code&gt; so you don’t have to specify the port number every time you connect.&lt;/li&gt;
&lt;li&gt;On the server, install and enable &lt;code&gt;ufw&lt;/code&gt; and &lt;code&gt;fail2ban&lt;/code&gt;. In addition to allowing your custom SSL port, be sure to enable ports 80 and 443 with &lt;code&gt;sudo ufw allow &amp;quot;WWW Full&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;caddy&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#caddy&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Caddy&lt;/h3&gt;
&lt;p&gt;I usually use nginx, but I wanted to give Caddy a shot, and it has been a great experience. I installed Caddy using the &lt;a href=&quot;https://caddyserver.com/docs/install&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;official instructions&lt;/a&gt;.&lt;br&gt;
Here is the Caddyfile I made—you will need to change the domain names and the email. Email could be removed, but it is there so that SSL certificate issuers can contact you if there is a problem with your certificates.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/caddy/Caddyfile&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;shiki css-variables&quot; style=&quot;background-color:var(--shiki-background);color:var(--shiki-foreground)&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-Caddyfile&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# Global options block&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt;	email&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; you@example.com&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt; #### CHANGE THIS ####&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt;	on_demand_tls&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;		ask http://localhost/check&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# Webhooks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;https://webhooks.subdomain.here.tld&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt; #### CHANGE THIS ####&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	reverse_proxy&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; localhost:9000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# Filter for which SSL certs we will create. Prevents abuse.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;http&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;//localhost&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	handle&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; /check&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;		root&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;/var/www&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;		@deny&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; not file /&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;{query.domain}&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;		respond&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; @deny&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 404&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# This automatically handles upgrading http:// requests with a redirect&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;https&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	tls&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;		on_demand&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	root&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; /var/www&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	rewrite&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; /&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;{host}{uri}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	@forbidden&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;		path&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; /.*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	respond&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; @forbidden&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 404&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;	file_server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# Refer to the Caddy docs for more information:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# https://caddyserver.com/docs/caddyfile&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# This config based on information at&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# https://caddy.community/t/on-demand-tls-with-dynamic-content-paths/18140&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# checked and corrected with `caddy validate`&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also took ownership of &lt;code&gt;/var/www&lt;/code&gt; with &lt;code&gt;chown -R joshua:joshua /var/www&lt;/code&gt; since the webhooks will run as my login account.&lt;/p&gt;
&lt;h3 id=&quot;webhooks&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#webhooks&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Webhooks&lt;/h3&gt;
&lt;p&gt;In my home directory I defined two hook scripts:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~/webhooks/update-pages.sh&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;shiki css-variables&quot; style=&quot;background-color:var(--shiki-background);color:var(--shiki-foreground)&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# parameter 1 is repo name, parameter 2 is clone url&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[[ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ]] &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[[ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;..&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ]] &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[[ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ]] &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; [ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/var/www/$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ]; &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;  cd&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/var/www/$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;  git&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; origin&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; gh-pages&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;  git&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; reset&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; --hard&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; origin/gh-pages&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;  exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;fi&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; clone&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; -b&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; gh-pages&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; --single-branch&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;$2&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;~/webhooks/remove-pages.sh&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;shiki css-variables&quot; style=&quot;background-color:var(--shiki-background);color:var(--shiki-foreground)&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-comment)&quot;&gt;# parameter 1 is repo name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[[ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ]] &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[[ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;..&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ]] &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[[ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ]] &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[ &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/var/www/$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; ] &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt; exit&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-constant)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/var/www&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-function)&quot;&gt;rm&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string)&quot;&gt; -rf&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/var/www/$1&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To trigger these hooks I am using &lt;code&gt;webhook&lt;/code&gt; which is in the default Debian repository.&lt;/p&gt;
&lt;p&gt;Here are the hook definitions: one for creating/updating a site, and one for deleting. You will need to generate one or two secret values that the server can use to know that the webhook is authorized to run. I used linux command &lt;code&gt;uuidgen -r&lt;/code&gt; to create mine. Save these values so you can enter them in Forgejo later.&lt;/p&gt;
&lt;p&gt;Also make sure to replace your execute-command lines with ones referencing your username and script paths.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/webhook.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;shiki css-variables&quot; style=&quot;background-color:var(--shiki-background);color:var(--shiki-foreground)&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;update-pages&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;execute-command&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/usr/bin/sudo&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;pass-arguments-to-command&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;-u&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;joshua&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/home/joshua/webhooks/update-pages.sh&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;payload&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;repository.name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;payload&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;repository.clone_url&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;    ]&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;trigger-rule&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;      &quot;and&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;          &quot;match&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;payload-hmac-sha256&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;secret&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;(omitted)&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;parameter&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;              &quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;header&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;              &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;X-Forgejo-Signature&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;        }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;          &quot;match&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;refs/heads/gh-pages&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;parameter&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;              &quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;payload&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;              &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;ref&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;  }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;remove-pages&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;execute-command&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/usr/bin/sudo&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;pass-arguments-to-command&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;-u&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;joshua&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;/home/joshua/webhooks/remove-pages.sh&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      { &lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;payload&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt; &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;repository.name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;    ]&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;    &quot;trigger-rule&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;      &quot;and&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;          &quot;match&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;payload-hmac-sha256&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;secret&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;(omitted)&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;            &quot;parameter&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;              &quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;header&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-token-keyword)&quot;&gt;              &quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--shiki-token-string-expression)&quot;&gt; &quot;X-Forgejo-Signature&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--shiki-foreground)&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;forgejo&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#forgejo&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Forgejo&lt;/h3&gt;
&lt;p&gt;Forgejo supports running webhooks conditionally triggered by certain conditions.&lt;br&gt;
Under my main user settings I set up each webhook:&lt;/p&gt;
&lt;h4 id=&quot;update-pages&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#update-pages&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Update pages&lt;/h4&gt;
&lt;p&gt;Target URL: https:// &lt;em&gt;your domain here&lt;/em&gt; /hooks/update-pages&lt;br&gt;
HTTP Method: &lt;code&gt;POST&lt;/code&gt; (the default)&lt;br&gt;
POST content type: &lt;code&gt;application/json&lt;/code&gt; (the default)&lt;br&gt;
Secret: &lt;em&gt;omitted, use your own&lt;/em&gt;&lt;br&gt;
Trigger on: Push events&lt;br&gt;
Branch filter: &lt;code&gt;gh-pages&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&quot;remove-pages&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#remove-pages&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Remove pages&lt;/h4&gt;
&lt;p&gt;Target URL: https:// &lt;em&gt;your domain here&lt;/em&gt; /hooks/remove-pages&lt;br&gt;
HTTP Method: &lt;code&gt;POST&lt;/code&gt; (the default)&lt;br&gt;
POST content type: &lt;code&gt;application/json&lt;/code&gt; (the default)&lt;br&gt;
Secret: &lt;em&gt;omitted, use your own&lt;/em&gt;&lt;br&gt;
Trigger on: Custom Events &amp;gt; Repository &amp;gt; Delete&lt;br&gt;
Branch filter: &lt;code&gt;gh-pages&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://joshua.seigler.net/posts/my-very-own-github-pages/#conclusion&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt; Conclusion&lt;/h2&gt;
&lt;p&gt;It works!&lt;br&gt;
Here is &lt;a href=&quot;https://git.apps.seigler.net/joshua/marklink.pages.seigler.net&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;the marklink repo in my Forgejo instance&lt;/a&gt; and &lt;a href=&quot;https://marklink.pages.seigler.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;its contents on my Caddy server&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That repo is just HTML and JS with only a gh-pages branch, but for repos with npm build scripts, I use &lt;a href=&quot;https://www.npmjs.com/package/gh-pages&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;gh-pages @ npm&lt;/a&gt; to push the build to a gh-pages branch and up to the server.&lt;/p&gt;
&lt;p&gt;I’m putting off rolling my own CI server, but I imagine that’s the next stage here. Stay tuned.&lt;/p&gt;
</content>
    </entry>
</feed>
