<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Forgejo on caleb's website</title><link>https://calebsharp.dev/tags/forgejo/</link><description>Recent content in Forgejo on caleb's website</description><generator>Hugo</generator><language>en-ca</language><managingEditor>me@calebsharp.dev (Caleb Sharp)</managingEditor><webMaster>me@calebsharp.dev (Caleb Sharp)</webMaster><copyright>© Caleb Sharp 2026</copyright><lastBuildDate>Wed, 15 Apr 2026 09:19:03 -0700</lastBuildDate><atom:link href="https://calebsharp.dev/tags/forgejo/index.xml" rel="self" type="application/rss+xml"/><item><title>How My Site Is Deployed</title><link>https://calebsharp.dev/posts/how-my-site-is-deployed/</link><pubDate>Wed, 15 Apr 2026 09:19:03 -0700</pubDate><author>me@calebsharp.dev (Caleb Sharp)</author><guid>https://calebsharp.dev/posts/how-my-site-is-deployed/</guid><description>&lt;h2 id="tldr"&gt;tl;dr&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Changes are pushed to a self-hosted forgejo instances&lt;/li&gt;
&lt;li&gt;Pushes to &lt;code&gt;main&lt;/code&gt; trigger an action that builds the site with &lt;code&gt;hugo&lt;/code&gt; and
copies it with rsync to another server.&lt;/li&gt;
&lt;li&gt;Caddy serves the static files at &lt;code&gt;/srv/calebsharp.dev&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="hugo"&gt;Hugo&lt;/h2&gt;
&lt;p&gt;This is pretty self-explanatory, but this site is built with
&lt;a href="https://gohugo.io/"&gt;Hugo&lt;/a&gt;. This is actually my first time trying it, and I&amp;rsquo;m
still getting used to it. For that reason, I decided to start with a theme and
ended up choosing this neat
&lt;a href="https://github.com/panr/hugo-theme-terminal"&gt;terminal theme by panr&lt;/a&gt;. I&amp;rsquo;ve
started to rip it apart and customize it to my liking and I expect to eventually
change most everything. At this point, I&amp;rsquo;m still trying to decide if it makes
more sense to treat my custom stuff as a &amp;ldquo;theme&amp;rdquo;, or just inline everything into
the main project. I get the feeling it only matters if I want to re-use the
theme on another site, and/or share it. Guess we&amp;rsquo;ll see!&lt;/p&gt;
&lt;p&gt;Other than that, I&amp;rsquo;ve been appreciating the authorship experience of Hugo. I
feel like I can focus on writing when I want to write, and focus on everything
but the posts when I want to tinker. It&amp;rsquo;s a nice separation of concerns that I
think stops me from getting too distracted.&lt;/p&gt;
&lt;h2 id="forgejo"&gt;Forgejo&lt;/h2&gt;
&lt;p&gt;I host my own Forgejo instance on an old PC I have at home. I use Tailscale to
connect to it (and holy crap what a useful tool that is). I have a cheap Hetzner
instance somewhere in Germany that I use as an actions runner (I&amp;rsquo;ll have to
write about that soon, it&amp;rsquo;s a bit finicky to set up, especially in my case where
I wanted to run the runner in podman &lt;em&gt;and&lt;/em&gt; run workflows in &amp;ldquo;nested&amp;rdquo;
containers). Other than that, it&amp;rsquo;s pretty stock.&lt;/p&gt;
&lt;p&gt;To have a nice domain/SSL, I don&amp;rsquo;t use Tailscale&amp;rsquo;s MagicDNS feature (I think the
domains are ugly!). Instead, I just have a public DNS record that resolves to
the internal Tailscale IP of the machine (&lt;code&gt;dig forgejo.ts.calebsharp.dev&lt;/code&gt;). If
you&amp;rsquo;re not on the tailnet, you can&amp;rsquo;t connect. I proxy Forgejo (+ all the other
things I run) through Caddy for automatic HTTPS.&lt;/p&gt;
&lt;p&gt;When I push new changes to the upstream repo, the runner kicks off a build job
that basically just installs some tools (TODO for myself: add tools to the
runner image) and runs &lt;code&gt;hugo build --minify&lt;/code&gt;. I&amp;rsquo;m using
&lt;a href="https://mise.jdx.dev/"&gt;mise&lt;/a&gt; to manage the versions of the tools I need, both
for local dev and in CI/CD (although I can&amp;rsquo;t get it to install hugo; there seems
to be some problem with the URL it tries to access for macOS builds). It then
copies the built static files with &lt;code&gt;rsync&lt;/code&gt; to my Hetzner VPS that&amp;rsquo;s actually
hosting the site. Since both the runner and server are both in my tailnet, it&amp;rsquo;s
trivial to let them connect via SSH without having to worry about exposing SSH
to the world. That&amp;rsquo;s it for deployment! It&amp;rsquo;s a little refreshing to not have a
stupidly complex build step with containers and linters and all that crap.&lt;/p&gt;
&lt;h2 id="caddy"&gt;Caddy&lt;/h2&gt;
&lt;p&gt;The static files deployed to the server are ultimately served by Caddy. Pretty
basic config, along with some automatic HTTPS and basic cache-control headers:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-caddyfile" data-lang="caddyfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;calebsharp.dev&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;root&lt;/span&gt; &lt;span class="nd"&gt;/srv/calebsharp.dev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;encode&lt;/span&gt; &lt;span class="s"&gt;zstd&lt;/span&gt; &lt;span class="s"&gt;gzip&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;file_server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;header&lt;/span&gt; &lt;span class="nd"&gt;/css/*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;Cache-Control&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;public, max-age=3600, must-revalidate&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;header&lt;/span&gt; &lt;span class="nd"&gt;/fonts/*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;Cache-Control&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;public, max-age=604800, must-revalidate&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="c1"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt; # API credentials for ACME DNS challenges
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;import&lt;/span&gt; porkbun
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And that&amp;rsquo;s it! I mentioned this in my first post, but it&amp;rsquo;s nice to have
something architecturally simple to let myself focus on writing when I want to.
On the other hand, I feel like I have quite a bit of flexibility to do whatever
cool stuff I want to try out. I think it strikes a nice balance.&lt;/p&gt;
&lt;p&gt;Thanks for reading! If you&amp;rsquo;re trying to do something similar and want to chat
about it, feel free to send me an email (info on the &lt;a href="https://calebsharp.dev/about/"&gt;about page&lt;/a&gt;).&lt;/p&gt;</description></item></channel></rss>