<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<title>mat.services</title>
	<subtitle>the personal website of mat ess</subtitle>
	<author>
		<name>mat ess</name>
		<email>mat@mat.services</email>
		<uri>https://www.mat.services</uri>
	</author>
	<link href="https://www.mat.services/atom.xml" rel="self" type="application/atom+xml"/>
	<icon>https://www.mat.services/image/favicon.svg</icon>
	<rights>&#169; 2022-2023 mat ess</rights>
	<generator uri="https://www.getzola.org/">Zola</generator>
	<updated>2022-10-17T00:00:00+00:00</updated>
	<id>https://www.mat.services/atom.xml</id>
	<entry xml:lang="en">
		<title>now on netlify</title>
		<published>2022-10-16T00:00:00+00:00</published>
		<updated>2022-10-16T00:00:00+00:00</updated>
		<link rel="alternate" href="https://www.mat.services/posts/now-on-netlify/" type="text/html"/>
		<id>https://www.mat.services/posts/now-on-netlify/</id>
		<summary>a short update regarding me packing up my static site and moving from fly.io to netlify</summary>
		<content type="html">
			<![CDATA[
  <figure>
    <img width=1024 height=512 class="hero" alt="A man packing up and leaving home to move to the city, luggage and boxes outside of his house, a moving truck idling in his driveway, gorgeous illustration, high quality art, masterpiece - generated using Stable Diffusion" src=hero.webp />
    <figcaption>
      <p><i>A man packing up and leaving home to move to the city, luggage and boxes outside of his house, a moving truck idling in his driveway, gorgeous illustration, high quality art, masterpiece</i> - generated using Stable Diffusion</p>
    </figcaption>
  </figure>
]]>
			&lt;p&gt;a short update today, and one that (unfortunately) obsoletes a lot of the work I put into &lt;a href=&quot;https:&#x2F;&#x2F;www.mat.services&#x2F;posts&#x2F;static-site-with-nix-and-caddy&#x2F;&quot;&gt;my last post on static site hosting&lt;&#x2F;a&gt;: this site is now hosted on netlify! after &lt;a href=&quot;https:&#x2F;&#x2F;www.mat.services&#x2F;posts&#x2F;command-line-flake-arguments&#x2F;&quot;&gt;my most recent article&lt;&#x2F;a&gt; ran into some accessibility issues for people outside of my fly.io deployment region, I decided to minimize the moving parts involved in keeping the site running. i moved my static content over to &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.netlify.com&#x2F;&quot;&gt;netlify&lt;&#x2F;a&gt;, a well-liked PaaS for deploying webapps and static sites (they also offer other things I don&#x27;t care about, such as &amp;quot;Serverless&amp;quot; and FaaS offerings). &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.netlify.com&#x2F;configure-builds&#x2F;file-based-configuration&#x2F;&quot;&gt;netlify&#x27;s configuration file&lt;&#x2F;a&gt; supports all the same headers and redirects options that I was using in caddy, so the transition was extremely smooth.&lt;&#x2F;p&gt;
&lt;p&gt;fly.io is still running my goatcounter analytics instance, as well as my gitea instance, and I don&#x27;t intend to stop using it for my other cloud deployment needs. ultimately, i didn&#x27;t want to debug what could have been going wrong with the server on fly.io, nor did i want to think hard about scaling up into multiple regions or similar strategies. netlify seems like a good fit for straightforward and performant static site hosting.&lt;&#x2F;p&gt;
&lt;p&gt;my lingering quibble with netlify, along with many of the hosted PaaS and CI&#x2F;CD solutions out there, is one of interoperability. in order to make use of continuous deployment functionality, virtually every one of these tools or platforms requires source code to be hosted on Github or Gitlab. this seems pretty arbitrary to me: couldn&#x27;t most platforms just make use of git and webhooks directly? support could be easily extended then beyond Github and Gitlab to self managed git hosting instances, such as Gitea.&lt;&#x2F;p&gt;
&lt;p&gt;am I missing something obvious here?&lt;&#x2F;p&gt;

		</content>
	</entry>
	
	<entry xml:lang="en">
		<title>passing command line arguments to nix flakes</title>
		<published>2022-10-10T00:00:00+00:00</published>
		<updated>2022-10-10T00:00:00+00:00</updated>
		<link rel="alternate" href="https://www.mat.services/posts/command-line-flake-arguments/" type="text/html"/>
		<id>https://www.mat.services/posts/command-line-flake-arguments/</id>
		<summary>a tutorial on 'breaking' the hermeticity of nix flakes by adding convenient command line flags</summary>
		<content type="html">
			<![CDATA[
  <figure>
    <img width=1024 height=512 class="hero" alt="A rogue program hacking through the firewall, in the style of Tron Legacy, cyberpunk vibe, digital render, 8k uhd, unreal engine - generated using Stable Diffusion" src=hero.webp />
    <figcaption>
      <p><i>A rogue program hacking through the firewall, in the style of Tron Legacy, cyberpunk vibe, digital render, 8k uhd, unreal engine</i> - generated using Stable Diffusion</p>
    </figcaption>
  </figure>
]]>
			&lt;p&gt;&lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;serokell.io&#x2F;blog&#x2F;practical-nix-flakes&quot;&gt;Nix flakes&lt;&#x2F;a&gt; are very useful, but the feature of a &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bazel.build&#x2F;basics&#x2F;hermeticity&quot;&gt;fully hermetic build&lt;&#x2F;a&gt; also means that they carry with them a certain degree of inflexibility. &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NixOS&#x2F;nix&#x2F;issues&#x2F;2861#issuecomment-891521971&quot;&gt;Users have asked for a mechanism to parameterize flakes&lt;&#x2F;a&gt;, but there seems to be no interest from the Nix maintainers in adding such a feature.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;While many readers will be very familiar with the concept of a function and the idea of parameterizing some piece of code or data, others might appreciate a bit of background. &lt;a href=&quot;https:&#x2F;&#x2F;www.mat.services&#x2F;posts&#x2F;command-line-flake-arguments&#x2F;#appendix&quot;&gt;Take a look at the appendix for a tangential explainer of some fundamental ideas referenced throughout this post.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;div id=jumpback&gt;&lt;&#x2F;div&gt;
&lt;p&gt;From outside of a flake&#x27;s Nix expression, the flake is a black box, a mapping from its input sources to the artifacts that it outputs. There is no built-in way to pass an arbitrary value, a boolean flag or string, from the command line in order to override a deeply nested configuration embedded in your flake. In most cases, this is fine, and you can work around many apparent needs for a one off override by building separate outputs for different purposes. Your flakes will probably come out better designed if you can use them strictly as intended.&lt;&#x2F;p&gt;
&lt;p&gt;A real-life use case where a command line override would come in handy comes from my own &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;daiderd.com&#x2F;nix-darwin&#x2F;&quot;&gt;nix-darwin&lt;&#x2F;a&gt; configuration, where I have my &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;brew.sh&#x2F;&quot;&gt;homebrew&lt;&#x2F;a&gt; formulas and casks specified. I like to let Nix manage installing and upgrading these packages, but unfortunately the process to check for updates eats up a bit of time. When I&#x27;m testing a new change to some other part of my nix-darwin setup, I don&#x27;t like to waste time repeatedly checking for homebrew updates. I could manually disable homebrew updates, but then I&#x27;d have to remember to flip it back on. Wouldn&#x27;t it be nice to have two commands? Something like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; rebuild the full system flake, when we want to perform homebrew updates
&lt;&#x2F;span&gt;&lt;span&gt;darwin-rebuild switch --flake &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;flake-path&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; rebuild without homebrew, for testing changes more quickly
&lt;&#x2F;span&gt;&lt;span&gt;darwin-rebuild switch --flake &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;flake-path&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;--no-homebrew
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ab-using-nix-flake-inputs-to-pass-overrides&quot;&gt;(Ab)using Nix flake inputs to pass overrides&lt;&#x2F;h2&gt;
&lt;p&gt;As mentioned, flakes are roughly equivalent to pure functions from their (aptly named) inputs to their outputs. Typically, our inputs are Nix expressions or source code that we want to use in our flake, but they can be used to smuggle in any old source code tree we want. What if we parameterized our flake with a special source input that we just use to control some behavior of the build?&lt;&#x2F;p&gt;
&lt;p&gt;While Nix has no generalized mechanism for command line overrides to flakes, there is a mechanism for &lt;em&gt;overriding flake inputs&lt;&#x2F;em&gt;: combine that with an input that we use for the special purpose of gating a feature or setting a value, and we have what we want.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;command-line-flags-for-flakes&quot;&gt;Command line flags for flakes&lt;&#x2F;h3&gt;
&lt;p&gt;I have totally lost track of my initial encounter with this method, but at some point I came across the &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;boolean-option&quot;&gt;&lt;code&gt;boolean-option&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; Github account that includes two repositories of interest: &lt;code&gt;true&lt;&#x2F;code&gt; and &lt;code&gt;false&lt;&#x2F;code&gt;. Upon inspection, each repo includes a trivial flake with a single output &lt;code&gt;value&lt;&#x2F;code&gt;, a boolean Nix value that matches the name of the repo. You can add a command line flag with a desired default value like so:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;my-flag&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;github:boolean-option&#x2F;true&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  };
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;outputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;my-flag }: {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;message &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;my-flag&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;value
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;then &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;it&amp;#39;s good!&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;it&amp;#39;s bad..&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you can build this flake and control the output message from the command line:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;nix eval --raw &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.#message&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;it&amp;#39;s good!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;nix eval --override-input my-flag github:boolean-option&#x2F;false --raw &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.#message&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;it&amp;#39;s bad..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So far, every flake-oriented Nix command I have tried supports the &lt;code&gt;override-input&lt;&#x2F;code&gt; flag, so this is a pretty reliable mechanism for passing in overrides where needed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git.mat.services&#x2F;mat&#x2F;dotfiles.nix&#x2F;src&#x2F;branch&#x2F;main&#x2F;flake.nix#L16-L17&quot;&gt;Take a look&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git.mat.services&#x2F;mat&#x2F;dotfiles.nix&#x2F;src&#x2F;branch&#x2F;main&#x2F;flake.nix#L256&quot;&gt;at how I use this&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git.mat.services&#x2F;mat&#x2F;dotfiles.nix&#x2F;src&#x2F;branch&#x2F;main&#x2F;darwin&#x2F;homebrew.nix#L31&quot;&gt;in my own system flake&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix&quot;&gt;Appendix&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.mat.services&#x2F;posts&#x2F;command-line-flake-arguments&#x2F;#jumpback&quot;&gt;Go back to the article&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;functions&quot;&gt;Functions&lt;&#x2F;h3&gt;
&lt;p&gt;In mathematics, a function is a mapping from some domain to a range. This can be expressed another way by saying that a function is a relationship between the elements of two sets, the inputs (or the domain) and the outputs (or the range). Take this simple function for example:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#393939;color:#dedede;&quot;&gt;&lt;code&gt;&lt;span&gt;f(x) = x * 2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The mapping can be expressed explicitly to reveal the two sets:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Input &#x2F; Domain &#x2F; &lt;code&gt;x&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;th&gt;Output &#x2F; Range &#x2F; &lt;code&gt;f(x)&lt;&#x2F;code&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;-1&lt;&#x2F;td&gt;&lt;td&gt;-2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Functions in programs bear some similarities to mathematical functions, and many mathematical functions can be expressed simply and directly in most programming languages:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span&gt;(x):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#87d6d5;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Most programming languages, however, do not enforce many (or any) of the laws governing mathematical functions. Functions which depend on global variables, mutable state, and side effects like user input are referred to as &lt;em&gt;impure functions&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;history &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;impure&lt;&#x2F;span&gt;&lt;span&gt;():
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; global variables
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffb9d;&quot;&gt;global &lt;&#x2F;span&gt;&lt;span&gt;x
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; user input
&lt;&#x2F;span&gt;&lt;span&gt;    y &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;give me y!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; mutable state
&lt;&#x2F;span&gt;&lt;span&gt;    history.append((x, y))
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; user output, also a side effect
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;y)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;builds-as-functions&quot;&gt;Builds as Functions&lt;&#x2F;h3&gt;
&lt;p&gt;In many ways, the process of building software can be compared to a function. In the simplest case, the method of building a particular piece of software could be viewed as a function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;build&lt;&#x2F;span&gt;&lt;span&gt;(source)
&lt;&#x2F;span&gt;&lt;span&gt;    software &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;compile&lt;&#x2F;span&gt;&lt;span&gt;(source)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;software
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For many build systems, the source inputs are taken from the local working directory, and additional parameters can be passed from the command line or environment. For example, &lt;code&gt;make&lt;&#x2F;code&gt; allows you to override variables in the &lt;code&gt;Makefile&lt;&#x2F;code&gt; by passing them along with the rule name:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;make clone BRANCH=dev
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;docker&lt;&#x2F;code&gt; allows argument and environment variable overrides to be passed to &lt;code&gt;Dockerfile&lt;&#x2F;code&gt; builds, container runs, and &lt;code&gt;docker-compose&lt;&#x2F;code&gt; stacks:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;docker[-compose] build --build-arg HTTP_PROXY=http:&#x2F;&#x2F;123.123.123.123:123
&lt;&#x2F;span&gt;&lt;span&gt;docker[-compose] run   --env       DOMAIN_NAME=foo.bar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;nix-flakes-as-pure-functions&quot;&gt;Nix flakes as Pure Functions&lt;&#x2F;h3&gt;
&lt;p&gt;If software builds are functions, then Nix flakes are pure functions. Indeed, the structure of a Nix flake is this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;description &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;Because functions are confusing without names and explanations&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;builder&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;...&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  };
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;outputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;source }: {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;software &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;builder&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;build source;
&lt;&#x2F;span&gt;&lt;span&gt;  };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which is not too far off from this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;flake&lt;&#x2F;span&gt;&lt;span&gt;(builder, source):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;builder.build(source)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nix flakes are truly pure, and Nix code running in the context of a flake is unable to access things like &lt;code&gt;builtins.currentTime&lt;&#x2F;code&gt;, which would be a side effect.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameters-and-arguments&quot;&gt;Parameters and Arguments&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;Parameters&lt;&#x2F;em&gt; and &lt;strong&gt;arguments&lt;&#x2F;strong&gt; are closely related—indeed, they are often confused or conflated entirely. I like to distinguish between them in terms of &lt;em&gt;abstract&lt;&#x2F;em&gt; inputs and &lt;strong&gt;concrete&lt;&#x2F;strong&gt; inputs.&lt;&#x2F;p&gt;
&lt;p&gt;Consider our same function from above: &lt;code&gt;x&lt;&#x2F;code&gt; stands in for any given value that our function might receive, without representing a specific value. &lt;code&gt;x&lt;&#x2F;code&gt; is &lt;em&gt;abstract&lt;&#x2F;em&gt;, and also the &lt;em&gt;parameter&lt;&#x2F;em&gt; of our function.&lt;&#x2F;p&gt;
&lt;p&gt;On the other hand, specific values of our domain, like -1, 0, and 1 (and actually many other numbers) are &lt;strong&gt;concrete&lt;&#x2F;strong&gt; values that can be supplied to the function to receive a specific output. Any specific value that is passed to our function is an &lt;strong&gt;argument&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;parameterizing-a-build&quot;&gt;Parameterizing a Build&lt;&#x2F;h3&gt;
&lt;p&gt;Now let&#x27;s tie it all together.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Builds are a bit like functions: &lt;code&gt;build(source) -&amp;gt; software&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Most builds are impure, and let you do whatever you want: access the filesystem and network, check the time of day, flip a coin: &lt;code&gt;build(source, anythingElse) -&amp;gt; software&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Nix flakes are pure, meaning we can&#x27;t depend on things besides our explicitly specified inputs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For an &amp;quot;impure&amp;quot; regular build, parameterizing is easy. Define a new variable or argument and pass it at the command line:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#393939;color:#dedede;&quot;&gt;&lt;code&gt;&lt;span&gt;make install PREFIX=$HOME
&lt;&#x2F;span&gt;&lt;span&gt;docker build --build-arg VERSION v1.2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With Nix flakes, we have to parameterize our build with an additional source input. This is definitely a bit of a hack, but it can be very useful when you need it!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.mat.services&#x2F;posts&#x2F;command-line-flake-arguments&#x2F;#jumpback&quot;&gt;Go back to the article&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Thank you to &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rrbutani&quot;&gt;Rahul Butani&lt;&#x2F;a&gt;, the creator of the &lt;code&gt;boolean-option&lt;&#x2F;code&gt; Github account!&lt;&#x2F;li&gt;
&lt;li&gt;Thank you to Hollis Druhet, my official copy editor, who has been unofficially helping out with blog edits up until now.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

		</content>
	</entry>
	
	<entry xml:lang="en">
		<title>cellular automata toys in löve2d</title>
		<published>2022-09-15T00:00:00+00:00</published>
		<updated>2022-09-15T00:00:00+00:00</updated>
		<link rel="alternate" href="https://www.mat.services/posts/cellular-automata-toys/" type="text/html"/>
		<id>https://www.mat.services/posts/cellular-automata-toys/</id>
		<summary>a short announcement post for a few interactive cellular automata toys written in lua</summary>
		<content type="html">
			<![CDATA[
  <figure>
    <img width=1024 height=512 class="hero" alt="The oracle reading the future from Conway&#x27;s Game of Life, technomancer aesthetic, digital illustration, 8k uhd - generated using Stable Diffusion" src=hero.webp />
    <figcaption>
      <p><i>The oracle reading the future from Conway&#x27;s Game of Life, technomancer aesthetic, digital illustration, 8k uhd</i> - generated using Stable Diffusion</p>
    </figcaption>
  </figure>
]]>
			&lt;p&gt;after reading &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;healeycodes.com&#x2F;virtual-ants&quot;&gt;Andrew Healey&#x27;s blog post about Langton&#x27;s Ant&lt;&#x2F;a&gt;, i found myself inspired to reimplement some of his work. i&#x27;ve read numerous rave reviews of löve2d for writing simple toys, so i decided to give that a shot here as well. Langton&#x27;s Ant went well enough that i also implemented Life and Wireworld.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;git.mat.services&#x2F;mat&#x2F;love-cellular-automata&quot;&gt;check the toys out here; there are instructions for running with löve2d directly or using nix&lt;&#x2F;a&gt;. the code is hosted on a personal instance of gitea, so if you want to collaborate or share feedback, you&#x27;ll have to request an account or shoot me an email.&lt;&#x2F;p&gt;

		</content>
	</entry>
	
	<entry xml:lang="en">
		<title>hosting a static site on fly.io with nix and caddy</title>
		<published>2022-09-04T00:00:00+00:00</published>
		<updated>2022-10-17T00:00:00+00:00</updated>
		<link rel="alternate" href="https://www.mat.services/posts/static-site-with-nix-and-caddy/" type="text/html"/>
		<id>https://www.mat.services/posts/static-site-with-nix-and-caddy/</id>
		<summary>a post from mat&#x27;s blog.</summary>
		<content type="html">&lt;p&gt;&lt;strong&gt;UPDATE&lt;&#x2F;strong&gt;
most of the information on this page is no longer accurate for my blog, &lt;a href=&quot;https:&#x2F;&#x2F;www.mat.services&#x2F;posts&#x2F;now-on-netlify&#x2F;&quot;&gt;which has since moved to netlify&lt;&#x2F;a&gt;. it should still work, or get you close, but i recommend checking out &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;LutrisEng&#x2F;nix-fly-template&quot;&gt;&lt;code&gt;nix-fly-template&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;&#x2F;h2&gt;
&lt;p&gt;So, &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sfconservancy.org&#x2F;GiveUpGitHub&#x2F;&quot;&gt;you&#x27;ve ditched Github and friends&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;www.mat.services&#x2F;posts&#x2F;gitea-on-fly-io&#x2F;&quot;&gt;set up your own Gitea instance&lt;&#x2F;a&gt;, and there&#x27;s just one (read: at least one) thing left for you to take care of—that snazzy static site you had up on Github Pages.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pages-and-static-site-hosting&quot;&gt;Pages and Static Site Hosting&lt;&#x2F;h3&gt;
&lt;p&gt;Github Pages, and the identically named product from Gitlab, have been a part of my personal site workflow for about as long as I have been maintaining a personal site. I can remember how empowering it felt when I finally realized how much utility Github had packed into the Pages product. I went through a gleeful week of churning out Vue.js templates, starry-eyed with how easy Pages made the deployment process.&lt;&#x2F;p&gt;
&lt;p&gt;Fast forward to today, and my migration away from Github and Gitlab has me once again pondering the question of an easy-to-use static site host. The tech industry has left me spoiled for choice here. Aside from Pages products from Github and Gitlab, the major cloud infrastructure providers all have their own take on static site hosting. More specialized companies like Netlify, Vercel, and Render offer a lot to hobbyist developers in terms of static hosting resources, with some going even further to provide Serverless-style &amp;quot;Functions-as-a-Service&amp;quot; products. &lt;&#x2F;p&gt;
&lt;p&gt;Some of these options were ruled out for me by requiring source code to be hosted on Github and friends, while others were much more heavyweight than what my requirements demanded. I was also motivated by an urge to consolidate: I already had projects running on Fly.io, as well as some important configuration and infrastructure on DigitalOcean, which made me hesitant to bring another third party into the mix.&lt;&#x2F;p&gt;
&lt;p&gt;As you may have guessed from the title, my ultimate decision was to take inspiration from &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fly.io&#x2F;docs&#x2F;getting-started&#x2F;static&#x2F;&quot;&gt;a Fly.io tutorial document&lt;&#x2F;a&gt; explaining how to deploy a very simple vanilla HTML site on Fly using a Go-powered webserver. I&#x27;m going to expand on their design a bit by introducing two major components: &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nixos.org&quot;&gt;Nix&lt;&#x2F;a&gt;, to give us the power to build our site with whatever static site generator (or other build process) we want to use; and &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;caddyserver.com&quot;&gt;Caddy&lt;&#x2F;a&gt;, to give us a more flexible and extensible platform for actually serving the content.&lt;&#x2F;p&gt;
&lt;p&gt;For the purposes of this article, I&#x27;ll assume you already have your static site ready to go. Whether you&#x27;re writing pure HTML by hand, or using a cutting-edge Javascript framework that renders down to static resources, you&#x27;ll be able to package it up with Nix and serve it with Caddy, all hosted on Fly.io.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;before-you-deploy-nix&quot;&gt;Before You Deploy: Nix&lt;&#x2F;h2&gt;
&lt;p&gt;Much like static site hosts, static site &lt;strong&gt;generators&lt;&#x2F;strong&gt; are everywhere, and it seems like one of those things where people have particularly strong opinions on what workflow fits them best. Some people eschew a &amp;quot;generator&amp;quot; entirely and chain more purpose-built tools together to achieve the perfect bespoke website output. Whatever your personal choice is for generating the content for your static site, it helps to have a sort of &amp;quot;universal entry point&amp;quot; to actually kick off the build process. Github and Gitlab each have their own custom Continuous Integration&#x2F;Continuous Delivery systems where the build for the site can be configured. &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Make_(software)#Makefile&quot;&gt;Makefiles&lt;&#x2F;a&gt; can declare a set of commands to run in a generic way, but they don&#x27;t help us pull in dependencies from the outside. &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.docker.com&#x2F;engine&#x2F;reference&#x2F;builder&#x2F;&quot;&gt;Dockerfiles&lt;&#x2F;a&gt; are another generic build specification that also make it easy to fetch any buildtime dependencies we need. Nix, a declarative package manager, is another option that we can use to specify our build and dependencies, without necessarily requiring us to actually make a container (although we can if we want!). Nix also offers more guarantees in terms of reproducibility and hermeticity than Docker. I already use Nix flakes for virtually all of my personal work, so that&#x27;s how we&#x27;ll specify our build step today.&lt;&#x2F;p&gt;
&lt;p&gt;Nix is a very powerful tool, but it can be intimidating to use, and I&#x27;ve encountered many people saying that the documentation is too sparse to be useful. I&#x27;ll keep the Nix details minimal, and try to include enough explanation for what we&#x27;re doing that even unfamiliar readers can follow along, but I would encourage anyone who wants some more background on Nix and Nix flakes to check out &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xeiaso.net&#x2F;blog&#x2F;nix-flakes-1-2022-02-21&quot;&gt;these&lt;&#x2F;a&gt; &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xeiaso.net&#x2F;blog&#x2F;nix-flakes-2-2022-02-27&quot;&gt;posts&lt;&#x2F;a&gt; from Xe Iaso&#x27;s blog.&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t already have Nix installed, we&#x27;ll start with that:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; macOS
&lt;&#x2F;span&gt;&lt;span&gt;sh &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;(curl -L https:&#x2F;&#x2F;nixos.org&#x2F;nix&#x2F;install)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Linux multi-user install (recommended by Nix)
&lt;&#x2F;span&gt;&lt;span&gt;sh &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;(curl -L https:&#x2F;&#x2F;nixos.org&#x2F;nix&#x2F;install) --daemon
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Linux single-user install (required when using SELinux)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; also Windows via WSL2
&lt;&#x2F;span&gt;&lt;span&gt;sh &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;(curl -L https:&#x2F;&#x2F;nixos.org&#x2F;nix&#x2F;install) --no-daemon
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Docker
&lt;&#x2F;span&gt;&lt;span&gt;docker run -it nixos&#x2F;nix
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next up, we&#x27;ll enable Nix flakes as a feature, since they are still disabled by default. You can do this the easy way, by editing one of &lt;code&gt;~&#x2F;.config&#x2F;nix&#x2F;nix.conf&lt;&#x2F;code&gt; or &lt;code&gt;&#x2F;etc&#x2F;nix&#x2F;nix.conf&lt;&#x2F;code&gt; (if you&#x27;re using a multi-user install, you&#x27;ll also need to restart &lt;code&gt;nix-daemon&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;conf&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-conf &quot;&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;&lt;span&gt;experimental-features &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; nix&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;command flakes
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you enjoy pain, you can do this the hard way by remembering to type this at the beginning of all your Nix commands, or setting an alias:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; one off
&lt;&#x2F;span&gt;&lt;span&gt;nix --experimental-features &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;nix-command flakes&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; build
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; sort of consistent but also not really
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;alias nix&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;nix &lt;&#x2F;span&gt;&lt;span&gt;--experimental-features &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;nix-command flakes&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can mosey on over to our site source. You might already be managing the source with Git, but if not, let&#x27;s do that now:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span&gt; site
&lt;&#x2F;span&gt;&lt;span&gt;git init
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Be careful not to commit anything secret! Git will keep a record of it
&lt;&#x2F;span&gt;&lt;span&gt;git add important&#x2F;stuff but&#x2F;no&#x2F;secrets
&lt;&#x2F;span&gt;&lt;span&gt;git commit -m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;TODO: pithy quip about starting a new endeavor&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nix flakes require you to be using some form of source control that Nix understands, which means (to my understanding) either Git or Mercurial. Everything tracked by source control will end up going into the Nix store, so be doubly sure that you haven&#x27;t committed any secrets, tokens, or manifestos that you don&#x27;t want leaking out.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;flake-nix-entry-point&quot;&gt;&lt;code&gt;flake.nix&lt;&#x2F;code&gt;: Entry Point&lt;&#x2F;h3&gt;
&lt;p&gt;We finally have all the foundations in place to put our site&#x27;s source into a flake. We can get a fresh flake by using the default template:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;nix flake init
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will leave us with the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;description &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;A very basic flake&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;outputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;nixpkgs }: {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;x86_64-linux&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;hello &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;nixpkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;legacyPackages&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;x86_64-linux&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hello;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;defaultPackage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;x86_64-linux &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;x86_64-linux&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hello;
&lt;&#x2F;span&gt;&lt;span&gt;  };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hmm. Well, that&#x27;s a VERY basic flake. It&#x27;s also seemingly out of date, as the latest advice I&#x27;ve seen recommends &lt;code&gt;packages.${system}.default&lt;&#x2F;code&gt; over &lt;code&gt;defaultPackage.${system}&lt;&#x2F;code&gt;. Let&#x27;s scrap that and pull in a template from the &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;flake.parts&quot;&gt;&lt;code&gt;flake-parts&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; (&lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;hercules-ci&#x2F;flake-parts&quot;&gt;Github&lt;&#x2F;a&gt;), a flake that bills itself as the &lt;em&gt;&amp;quot;Core of a distributed framework for writing Nix flakes&amp;quot;&lt;&#x2F;em&gt;. &lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;rm flake.nix
&lt;&#x2F;span&gt;&lt;span&gt;nix flake init --template github:hercules-ci&#x2F;flake-parts
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In my experience, &lt;code&gt;flake-parts&lt;&#x2F;code&gt; is an extremely helpful tool that provides some Nix functions that drastically reduce the amount of boilerplate you need for a working flake:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;description &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;Description for the project&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;flake-parts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;nixpkgs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;follows &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;nixpkgs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;nixpkgs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;github:NixOS&#x2F;nixpkgs&#x2F;nixos-unstable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  };
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;outputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}:
&lt;&#x2F;span&gt;&lt;span&gt;    flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;lib&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mkFlake { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inherit self&lt;&#x2F;span&gt;&lt;span&gt;; } {
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;imports &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# To import a flake module
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# 1. Add foo to inputs
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# 2. Add foo as a parameter to the outputs function
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# 3. Add here: foo.flakeModule
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      ];
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;systems &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;x86_64-linux&amp;quot; &amp;quot;aarch64-darwin&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;perSystem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;self&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;inputs&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}: {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# Per-system attributes can be defined here. The self&amp;#39; and inputs&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# module parameters provide easy access to attributes of the same
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# system.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# Equivalent to  inputs&amp;#39;.nixpkgs.legacyPackages.hello;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;default &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hello;
&lt;&#x2F;span&gt;&lt;span&gt;      };
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;flake &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# The usual flake attributes can be defined here, including system-
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# agnostic ones like nixosModule and system-enumerating ones, although
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# those are more easily expressed in perSystem.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      };
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All we&#x27;re going to need is &lt;code&gt;systems&lt;&#x2F;code&gt; and &lt;code&gt;perSystem&lt;&#x2F;code&gt;, so let&#x27;s clean up the template to look something like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;description &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;Statically generated site&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;nixpkgs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;github:NixOS&#x2F;nixpkgs&#x2F;nixos-unstable&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;flake-parts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;github:hercules-ci&#x2F;flake-parts&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;flake-parts&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;nixpkgs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;follows &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;nixpkgs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  };
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;outputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}:
&lt;&#x2F;span&gt;&lt;span&gt;    flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;lib&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mkFlake { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inherit self&lt;&#x2F;span&gt;&lt;span&gt;; } {
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# modify these as needed if you&amp;#39;re using a different system
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;systems &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;x86_64-linux&amp;quot; &amp;quot;aarch64-darwin&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;perSystem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;self&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;inputs&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}: {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;devShells&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;default &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.&#x2F;shell.nix &lt;&#x2F;span&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inherit pkgs&lt;&#x2F;span&gt;&lt;span&gt;; };
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;default &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;callPackage &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.&#x2F;site.nix &lt;&#x2F;span&gt;&lt;span&gt;{};
&lt;&#x2F;span&gt;&lt;span&gt;      };
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This won&#x27;t build right away. First we&#x27;re going to have to add the two &lt;code&gt;.nix&lt;&#x2F;code&gt; files we used.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shell-nix-reproducible-development-environment&quot;&gt;&lt;code&gt;shell.nix&lt;&#x2F;code&gt;: Reproducible Development Environment&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;shell.nix&lt;&#x2F;code&gt; is a common feature of many Nix builds, and typically specifies the packages that are used for developing and iterating on a project. If you haven&#x27;t used Nix before, you likely have the dependencies and tools for your static site installed using your system package manager, or using a language-specific build tool. By switching to &lt;code&gt;shell.nix&lt;&#x2F;code&gt;, you can decouple the project development environment from your local system, akin to using a Docker container for development. If you don&#x27;t want or need any special tools to build your site, you can mostly ignore this file, but here&#x27;s what this might look like for a simple static site:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{ pkgs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;lt;nixpkgs&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;}:
&lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mkShell {
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;buildInputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# build your static site with one of these
&lt;&#x2F;span&gt;&lt;span&gt;    pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;hugo
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# or pkgs.zola or pkgs.jekyll
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# deploy with fly
&lt;&#x2F;span&gt;&lt;span&gt;    pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flyctl
&lt;&#x2F;span&gt;&lt;span&gt;  ];
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;site-nix-reproducible-site-build&quot;&gt;&lt;code&gt;site.nix&lt;&#x2F;code&gt;: Reproducible Site Build&lt;&#x2F;h3&gt;
&lt;p&gt;We&#x27;ll write &lt;code&gt;site.nix&lt;&#x2F;code&gt; as a function from packages in &lt;code&gt;nixpkgs&lt;&#x2F;code&gt; to a derivation, which will let us call it more conveniently with &lt;code&gt;pkgs.callPackage&lt;&#x2F;code&gt;, as we did above in &lt;code&gt;flake.nix&lt;&#x2F;code&gt;. Here&#x27;s an example of a site build with &lt;code&gt;hugo&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{ stdenv&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;hugo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;scour }:
&lt;&#x2F;span&gt;&lt;span&gt;stdenv&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mkDerivation {
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;name &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;static-site&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;src &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.&#x2F;.&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;nativeBuildInputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# specify site build dependencies here
&lt;&#x2F;span&gt;&lt;span&gt;    hugo
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# optimize SVGs
&lt;&#x2F;span&gt;&lt;span&gt;    scour
&lt;&#x2F;span&gt;&lt;span&gt;  ];
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;buildPhase &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;#39;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;    # prepare and build the site
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;    scour -i favicon-original.svg -o favicon.svg
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;    hugo -D
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;  &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;installPhase &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;#39;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;    # install the Hugo output
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;    cp -r public $out
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;  &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we need to build any other auxiliary outputs, like Docker images (hint!), we can add them here. For now, let&#x27;s just save our progress:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;git add flake.nix shell.nix site.nix
&lt;&#x2F;span&gt;&lt;span&gt;nix flake lock
&lt;&#x2F;span&gt;&lt;span&gt;git add flake.lock
&lt;&#x2F;span&gt;&lt;span&gt;git commit -m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;Initialize Nix flake&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can test that our flake works with &lt;code&gt;nix build&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;nix build
&lt;&#x2F;span&gt;&lt;span&gt;ls result
&lt;&#x2F;span&gt;&lt;span&gt;index.html main.css ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;serving-caddy&quot;&gt;Serving: Caddy&lt;&#x2F;h2&gt;
&lt;p&gt;We can reliably build our site, but now we need a way to serve it on the &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xkcd.com&#x2F;181&#x2F;&quot;&gt;blagoblag&lt;&#x2F;a&gt;. Let&#x27;s use Caddy! The syntax is marginally less arcane than Apache or Nginx, and it has cool features like HTTPS-by-default!&lt;&#x2F;p&gt;
&lt;p&gt;Sadly, the first thing we&#x27;re going to have to do in our &lt;code&gt;Caddyfile&lt;&#x2F;code&gt; is turn that off:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Caddyfile&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-Caddyfile &quot;&gt;&lt;code class=&quot;language-Caddyfile&quot; data-lang=&quot;Caddyfile&quot;&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# fly.io handles https for us
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  auto_https off
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;:8080 {
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;root&lt;&#x2F;span&gt;&lt;span&gt; * &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#d6d6ae;&quot;&gt;{$SITE_ROOT}
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt; gzip
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;file_server
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# redirect to your custom 404 page
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;handle_errors&lt;&#x2F;span&gt;&lt;span&gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    @404 {
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;expression&lt;&#x2F;span&gt;&lt;span&gt; {http.error.status_code} == 404
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;rewrite&lt;&#x2F;span&gt;&lt;span&gt; @404 &#x2F;404.html
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;file_server
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can test this by adding &lt;code&gt;caddy&lt;&#x2F;code&gt; to your &lt;code&gt;shell.nix&lt;&#x2F;code&gt; file or else installing it locally, and running something like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;nix build
&lt;&#x2F;span&gt;&lt;span&gt;env SITE_ROOT=result caddy validate
&lt;&#x2F;span&gt;&lt;span&gt;2022&#x2F;08&#x2F;27 19:40:48.724 WARN    http    automatic HTTPS is completely disabled for server       {&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;server_name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;srv0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;Valid configuration
&lt;&#x2F;span&gt;&lt;span&gt;env SITE_ROOT=result caddy run
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should be able to browse to your site at &lt;code&gt;127.0.0.1:8080&lt;&#x2F;code&gt; and load it, although some resources may load improperly or not at all if they are expected to be accessed at a particular hostname. When we deploy to Fly, however, everything should be working. Add the Caddyfile to git:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;git add Caddyfile
&lt;&#x2F;span&gt;&lt;span&gt;git commit -m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;Add Caddyfile&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;deploying-fly-io&quot;&gt;Deploying: Fly.io&lt;&#x2F;h2&gt;
&lt;p&gt;We can scaffold a new Fly app in the usual way:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl launch \
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; something unique, doesn&amp;#39;t matter if you&amp;#39;re going to use a custom domain
&lt;&#x2F;span&gt;&lt;span&gt;  --name seals-meander-daringly
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; region where the app runs, don&amp;#39;t supply this option if you want to interactively choose a region \
&lt;&#x2F;span&gt;&lt;span&gt;	--region ewr \
&lt;&#x2F;span&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; don&amp;#39;t immediately deploy, we need to edit our fly.toml first \
&lt;&#x2F;span&gt;&lt;span&gt;	--no-deploy
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;git add fly.toml
&lt;&#x2F;span&gt;&lt;span&gt;git commit -m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;Initialize Fly app&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We need to find some way for Fly to build a VM from our application and Caddyfile. Fly supports Dockerfiles, so let&#x27;s just go ahead and start with that:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Dockerfile&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-Dockerfile &quot;&gt;&lt;code class=&quot;language-Dockerfile&quot; data-lang=&quot;Dockerfile&quot;&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; nixos&#x2F;nix:latest
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;WORKDIR &lt;&#x2F;span&gt;&lt;span&gt;&#x2F;code
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;ADD &lt;&#x2F;span&gt;&lt;span&gt;. &#x2F;code
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;RUN &lt;&#x2F;span&gt;&lt;span&gt;nix \
&lt;&#x2F;span&gt;&lt;span&gt;  --extra-experimental-features nix-command \
&lt;&#x2F;span&gt;&lt;span&gt;  --extra-experimental-features flakes \
&lt;&#x2F;span&gt;&lt;span&gt;  build
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; caddy:latest
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; Caddyfile &#x2F;etc&#x2F;caddy&#x2F;Caddyfile
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;COPY&lt;&#x2F;span&gt;&lt;span&gt; --from=0 &#x2F;code&#x2F;result &#x2F;var&#x2F;www
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;ENV &lt;&#x2F;span&gt;&lt;span&gt;SITE_ROOT=&#x2F;var&#x2F;www
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;RUN &lt;&#x2F;span&gt;&lt;span&gt;caddy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can use a multi-stage build to run the Nix build first, then copy that into a container with the Caddyfile and run that. We&#x27;re set to deploy!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl deploy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can set up a custom domain if we want:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl ips list
&lt;&#x2F;span&gt;&lt;span&gt;VERSION	IP                 	TYPE  	REGION	CREATED AT           
&lt;&#x2F;span&gt;&lt;span&gt;v4     	1.2.3.4       	    public	global	2022-08-09T02:19:27Z	
&lt;&#x2F;span&gt;&lt;span&gt;v6     	aaaa:bbbb:1::a:cccc	public	global	2022-08-09T02:19:29Z	
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; add DNS A and AAAA records for the above addresses
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; e.g., using doctl for digitalocean
&lt;&#x2F;span&gt;&lt;span&gt;doctl compute domain records create \
&lt;&#x2F;span&gt;&lt;span&gt;  --record-type A \
&lt;&#x2F;span&gt;&lt;span&gt;  --record-name my
&lt;&#x2F;span&gt;&lt;span&gt;  --record-data 1.2.3.4 \
&lt;&#x2F;span&gt;&lt;span&gt;  static.site
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;doctl compute domain records create\
&lt;&#x2F;span&gt;&lt;span&gt;  --record-type AAAA \
&lt;&#x2F;span&gt;&lt;span&gt;  --record-name my
&lt;&#x2F;span&gt;&lt;span&gt;  --record-data aaaa:bbbb:1::a:cccc \
&lt;&#x2F;span&gt;&lt;span&gt;  static.site
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; get a certificate
&lt;&#x2F;span&gt;&lt;span&gt;flyctl certs add my.static.site
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A small addition to the Caddyfile will be helpful, as well:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Caddyfile&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-Caddyfile &quot;&gt;&lt;code class=&quot;language-Caddyfile&quot; data-lang=&quot;Caddyfile&quot;&gt;&lt;span&gt;http:&#x2F;&#x2F;seals-meander-daringly.fly.dev {
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;redir&lt;&#x2F;span&gt;&lt;span&gt; https:&#x2F;&#x2F;my.static.site
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Don&#x27;t forget to &lt;code&gt;flyctl deploy&lt;&#x2F;code&gt; again!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-round-configure-everything-in-nix&quot;&gt;Bonus Round: Configure Everything in Nix&lt;&#x2F;h2&gt;
&lt;p&gt;&amp;quot;But mat!&amp;quot; you&#x27;re shouting in anguish, &amp;quot;Why do we have to write a crummy Dockerfile to build our software? You said several sections ago that Nix could be the universal entry point, and that it was better than Docker for some important sounding reasons!&amp;quot;&lt;&#x2F;p&gt;
&lt;p&gt;I know. What&#x27;s more is, you&#x27;re entirely right. We DON&#x27;T have to settle for a Dockerfile! Nix has some tooling available to build our Docker images for us, and we can plug that right into our Fly.io application.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s add a &lt;code&gt;container.nix&lt;&#x2F;code&gt; file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{ dockerTools&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;caddy&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;site }: 
&lt;&#x2F;span&gt;&lt;span&gt;  dockerTools&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;buildLayeredImage {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;name &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;static-site&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;tag &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;2022-08-28&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;  
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;config &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;Cmd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;caddy&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&#x2F;bin&#x2F;caddy&amp;quot; &amp;quot;run&amp;quot; &amp;quot;-config&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.&#x2F;Caddyfile&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;Env &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;SITE_ROOT=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;site&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      ];
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;  }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add it to source control:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;git add container.nix
&lt;&#x2F;span&gt;&lt;span&gt;git commit -m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;Add Docker image build&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And then refer to that in our &lt;code&gt;flake.nix&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;outputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}:
&lt;&#x2F;span&gt;&lt;span&gt;    flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;lib&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mkFlake { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inherit self&lt;&#x2F;span&gt;&lt;span&gt;; } {
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;perSystem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;self&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;inputs&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}: {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;container &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;callPackage &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.&#x2F;container.nix &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;site &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;default;
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;      };
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can test that the build works like so, including running it if you have a local Docker installation:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;nix build .#container
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; if you have a working Docker installation
&lt;&#x2F;span&gt;&lt;span&gt;docker load &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; result
&lt;&#x2F;span&gt;&lt;span&gt;docker run -itp 8080:8080 static-site:2022-08-28
&lt;&#x2F;span&gt;&lt;span&gt;curl http:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;:8080
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some people, myself included, don&#x27;t care to run Docker engine on their Macbooks, so the easiest way for us to test this would be to package up the deployment step into a script and run it on a Linux host with Docker, such as in a container on a CI&#x2F;CD server.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s add another &lt;code&gt;callPackage&lt;&#x2F;code&gt; friendly Nix file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{ lib&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;flyctl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;formats&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;writeShellScriptBin&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;dockerImage }:
&lt;&#x2F;span&gt;&lt;span&gt;writeShellScriptBin &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;quot;deploy&amp;quot; &amp;#39;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;  set -euxo pipefail
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;  export PATH=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;lib&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;makeBinPath [(docker&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;override { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;clientOnly &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#d6d6ae;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;; }) flyctl]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;:$PATH&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;  archive=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;${&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;dockerImage&lt;&#x2F;span&gt;&lt;span style=&quot;color:#898989;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;  image=$(docker load &amp;lt; $archive | awk &amp;#39;{ print $3; }&amp;#39;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;  flyctl deploy -i $image
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;&amp;#39;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And plug it into the flake:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;nix&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-nix &quot;&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;outputs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}:
&lt;&#x2F;span&gt;&lt;span&gt;    flake-parts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;lib&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mkFlake { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;inherit self&lt;&#x2F;span&gt;&lt;span&gt;; } {
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;perSystem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{ config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;self&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;inputs&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;system&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;, ... &lt;&#x2F;span&gt;&lt;span&gt;}: {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt;# ...
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;apps&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;deploy &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;callPackage &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;.&#x2F;deploy.nix &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;dockerImage &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;container;
&lt;&#x2F;span&gt;&lt;span&gt;        };
&lt;&#x2F;span&gt;&lt;span&gt;      };
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you should be able to use a command like this on a Docker-friendly host, and your site will be up and running before long:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;nix run .#deploy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;future-directions&quot;&gt;Future Directions&lt;&#x2F;h3&gt;
&lt;p&gt;There is just a touch of boilerplate left in &lt;code&gt;flake.nix&lt;&#x2F;code&gt;, required to thread the correct nixpkgs context through (&lt;code&gt;callPackage&lt;&#x2F;code&gt;, passing &lt;code&gt;site&lt;&#x2F;code&gt; and &lt;code&gt;dockerImage&lt;&#x2F;code&gt; explicitly). We could easily package that up in a &lt;code&gt;flake-module.nix&lt;&#x2F;code&gt; and add it to the &lt;code&gt;imports&lt;&#x2F;code&gt; argument of &lt;code&gt;flake-parts.lib.mkFlake&lt;&#x2F;code&gt;. I&#x27;ll probably try to make another blog post out of the process of packaging up the Nix glue, so keep your eyes peeled!&lt;&#x2F;p&gt;
&lt;p&gt;Thanks for reading!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;LutrisEng&#x2F;nix-fly-template&quot;&gt;Thanks to Lutris, Inc. for their &lt;code&gt;nix-fly-template&lt;&#x2F;code&gt;, which was very influential in the writing of this post.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Thanks to Hollis Druhet for reading the draft of this post and offering feedback!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

		</content>
	</entry>
	
	<entry xml:lang="en">
		<title>diy code hosting with gitea and fly.io</title>
		<published>2022-08-07T00:00:00+00:00</published>
		<updated>2022-09-04T00:00:00+00:00</updated>
		<link rel="alternate" href="https://www.mat.services/posts/gitea-on-fly-io/" type="text/html"/>
		<id>https://www.mat.services/posts/gitea-on-fly-io/</id>
		<summary>a post from mat&#x27;s blog.</summary>
		<content type="html">&lt;h2 id=&quot;setting-the-scene&quot;&gt;Setting the Scene&lt;&#x2F;h2&gt;
&lt;p&gt;Inspired by the &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;sfconservancy.org&#x2F;GiveUpGitHub&#x2F;&quot;&gt;Give Up Github campaign&lt;&#x2F;a&gt;, I recently decided I wanted to spin up my own instance of &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gitea.io&#x2F;&quot;&gt;Gitea&lt;&#x2F;a&gt;. There are free (as in beer), free (as in freedom), public instances of Gitea and other FOSS-leaning code forges, but self-hosted Gitea struck me as a nice way to take even a bit more ownership over my own code.&lt;&#x2F;p&gt;
&lt;p&gt;I maintain a small PC running in my home as a server for a few services running via Proxmox, but I am really dissatisfied with my workflows for managing that box lately (picture SSHing into LXC containers and manually editing systemd configurations... yuck). I recently read a couple of different articles singing the praises of &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fly.io&#x2F;&quot;&gt;Fly.io&lt;&#x2F;a&gt;, a platform as a service (PaaS) that replicates most of the good parts of the classic Heroku developer experience. Further enticed by their ample free tier, I took the plunge and created a Fly.io account.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;&#x2F;h2&gt;
&lt;p&gt;First things first: in order to interact with Fly.io, we primarily use the &lt;code&gt;flyctl&lt;&#x2F;code&gt; command line tool. It&#x27;s available from a variety of sources:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Nix
&lt;&#x2F;span&gt;&lt;span&gt;nix-shell --packages flyctl
&lt;&#x2F;span&gt;&lt;span&gt;nix-env --install --attr nixpkgs.flyctl
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; macOS
&lt;&#x2F;span&gt;&lt;span&gt;brew install flyctl
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Linux + non-Homebrew users
&lt;&#x2F;span&gt;&lt;span&gt;curl -L https:&#x2F;&#x2F;fly.io&#x2F;install.sh &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;sh
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Windows users
&lt;&#x2F;span&gt;&lt;span&gt;iwr https:&#x2F;&#x2F;fly.io&#x2F;install.ps1 -useb &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;iex
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;flyctl&lt;&#x2F;code&gt; can handle signing up for a Fly.io account if you haven&#x27;t done that, otherwise you can use it to sign in:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Opens your browser to set up an account
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; This step requires a credit card, in the event you exceed the free tier limits
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; See https:&#x2F;&#x2F;fly.io&#x2F;docs&#x2F;about&#x2F;pricing&#x2F; for details
&lt;&#x2F;span&gt;&lt;span&gt;flyctl auth signup
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Opens your browser to sign in
&lt;&#x2F;span&gt;&lt;span&gt;flyctl auth login
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;configuring-apps-with-flyctl&quot;&gt;Configuring Apps with &lt;code&gt;flyctl&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;In order to avoid even the appearance of disorganization, we&#x27;ll start off with a git repository for tracking our Fly.io configurations:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;mkdir fly-apps&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span&gt; fly-apps
&lt;&#x2F;span&gt;&lt;span&gt;git init
&lt;&#x2F;span&gt;&lt;span&gt;mkdir gitea&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fffd87;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span&gt; gitea
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next up, we create our app configuration and register it with Fly.io. &lt;code&gt;flyctl&lt;&#x2F;code&gt; takes care of this for us in a single command, &lt;code&gt;flyctl launch&lt;&#x2F;code&gt;. The command will prompt you interactively for some input, but here we&#x27;ll just pass some flags directly:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl launch \
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; use the official Gitea docker image \
&lt;&#x2F;span&gt;&lt;span&gt;  --image gitea&#x2F;gitea:latest \
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; give our instance a unique name, this will be used to generate a development hostname like gitea-mat-services.fly.dev \
&lt;&#x2F;span&gt;&lt;span&gt;  --name gitea-mat-services \
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; region where the app runs, don&amp;#39;t supply this option if you want to interactively choose a region \
&lt;&#x2F;span&gt;&lt;span&gt;  --region ewr \
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; don&amp;#39;t immediately deploy, we need to edit our fly.toml first \
&lt;&#x2F;span&gt;&lt;span&gt;  --no-deploy
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; don&amp;#39;t forget to commit!
&lt;&#x2F;span&gt;&lt;span&gt;git add fly.toml
&lt;&#x2F;span&gt;&lt;span&gt;git commit -m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;Add default generated configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We will also need a volume for persisting git repositories:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Create a 3GB volume
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Note: this will consume your entire free tier allotment for volume storage!
&lt;&#x2F;span&gt;&lt;span&gt;flyctl volumes create gitea_data
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a0cfa1;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color:#87ae86;&quot;&gt; Alternatively, create a smaller volume
&lt;&#x2F;span&gt;&lt;span&gt;flyctl volumes create gitea_data --size 1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now our app is ready to deploy, but first we&#x27;re going to make some changes to the &lt;code&gt;fly.toml&lt;&#x2F;code&gt; configuration that was generated for us. &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.gitea.io&#x2F;2022&#x2F;04&#x2F;running-gitea-on-fly.io&#x2F;&quot;&gt;Gitea has their own post on Fly.io which includes a sample configuration&lt;&#x2F;a&gt;, and we can reference that to end up with something like the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-diff &quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;&amp;lt;snip&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;[env]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   GITEA____APP_NAME = &amp;quot;git.mat.services: Gitea for me&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   GITEA__database__DB_TYPE = &amp;quot;sqlite3&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   GITEA__database__PATH = &amp;quot;&#x2F;data&#x2F;gitea&#x2F;gitea.db&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   GITEA__server__DOMAIN = &amp;quot;gitea-on-fly.fly.dev&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   GITEA__server__SSH_DOMAIN = &amp;quot;gitea-on-fly.fly.dev&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   GITEA__server__ROOT_URL = &amp;quot;https:&#x2F;&#x2F;gitea-on-fly.fly.dev&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   GITEA__security__INSTALL_LOCK = &amp;quot;true&amp;quot; # Don&amp;#39;t show installer
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   # GITEA__service__DISABLE_REGISTRATION = &amp;quot;true&amp;quot; # TODO: uncomment once you have created your first user
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+ [mounts]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   destination = &amp;quot;&#x2F;data&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   source = &amp;quot;gitea_data&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;&amp;lt;snip&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+ # ssh traffic
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+ [[services]]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   internal_port = 22
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   protocol = &amp;quot;tcp&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   [[services.ports]]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+     port = 22
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;[[services]]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;&amp;lt;snip&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ca7172;&quot;&gt;-   internal_port = 8080
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#60b38a;&quot;&gt;+   internal_port = 3000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ffffff;&quot;&gt;&amp;lt;snip&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Don&#x27;t forget to save your work!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;git add fly.toml
&lt;&#x2F;span&gt;&lt;span&gt;git commit -m &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;Add Gitea specific configuration&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;liftoff&quot;&gt;Liftoff!&lt;&#x2F;h2&gt;
&lt;p&gt;The stars are aligned. The witching hour has arrived. Let&#x27;s deploy our app:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl deploy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After &lt;code&gt;flyctl&lt;&#x2F;code&gt; does its thing, your Gitea instance should be up and running at &lt;code&gt;https:&#x2F;&#x2F;&amp;lt;your-app-name&amp;gt;.fly.dev&lt;&#x2F;code&gt;! For the extremely lazy, &lt;code&gt;flyctl&lt;&#x2F;code&gt; will do the work for you:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl open
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you can register your account! If you want to keep your Gitea instance private, uncomment the last line in the &lt;code&gt;env&lt;&#x2F;code&gt; section and rerun &lt;code&gt;flyctl deploy&lt;&#x2F;code&gt; after registering.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus-round-configuring-your-custom-domain-with-fly-io&quot;&gt;Bonus Round: Configuring Your Custom Domain with Fly.io&lt;&#x2F;h2&gt;
&lt;p&gt;Some, like myself, will not be satisfied accessing their Gitea instances with a &lt;code&gt;.fly.dev&lt;&#x2F;code&gt; URL. Thankfully, Fly.io makes it a breeze to configure a secure custom domain with the help of &lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;letsencrypt.org&#x2F;&quot;&gt;LetsEncrypt&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Fly.io and &lt;code&gt;flyctl&lt;&#x2F;code&gt; seem to offer tooling for managing your domains and DNS records entirely within the Fly.io system, but I personally didn&#x27;t explore this route, as my own domains and DNS records are managed elsewhere. Whatever you use to manage your own domains and DNS, you will need to create two records for your domain name corresponding with the IPv4 and IPv6 addresses of the application:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl ips list
&lt;&#x2F;span&gt;&lt;span&gt;TYPE ADDRESS             REGION CREATED AT           
&lt;&#x2F;span&gt;&lt;span&gt;v4   1.2.3.4             global 2022-07-03T04:39:18Z 
&lt;&#x2F;span&gt;&lt;span&gt;v6   dead:beef:1::a:a    global 2022-07-03T04:39:19Z 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Create an A record for the v4 address, and an AAAA record for the v6 address. With those records in place, &lt;code&gt;flyctl&lt;&#x2F;code&gt; can automatically perform the necessary setup with LetsEncrypt to secure your domain:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl certs add git.mat.services
&lt;&#x2F;span&gt;&lt;span&gt;flyctl open
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now it&#x27;s time to revel in your new code hosting powers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-first-push-or-256mb-just-isn-t-enough-sometimes&quot;&gt;The First Push (or, 256MB just isn&#x27;t enough sometimes)&lt;&#x2F;h3&gt;
&lt;p&gt;With everything now set up, let&#x27;s go ahead and kick the tires on our new Gitea installation. We can push our &lt;code&gt;fly-apps&lt;&#x2F;code&gt; repository to Gitea as a test. Create a new blank repository on Gitea with an appropriate name, then add that as a remote for your local repo:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;git remote add origin git@git.mat.services:mat&#x2F;fly-apps.git
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now it&#x27;s as easy as one simple command!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;git push --set-upstream origin main
&lt;&#x2F;span&gt;&lt;span&gt;Enumerating objects: 3, done.
&lt;&#x2F;span&gt;&lt;span&gt;Counting objects: 100&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; (3&#x2F;3), done.
&lt;&#x2F;span&gt;&lt;span&gt;Writing objects: 100&lt;&#x2F;span&gt;&lt;span style=&quot;color:#fed6af;&quot;&gt;%&lt;&#x2F;span&gt;&lt;span&gt; (3&#x2F;3), 195 bytes &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;195.00 KiB&#x2F;s, done.
&lt;&#x2F;span&gt;&lt;span&gt;Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
&lt;&#x2F;span&gt;&lt;span&gt;remote: 
&lt;&#x2F;span&gt;&lt;span&gt;remote: Gitea: Internal Server Error
&lt;&#x2F;span&gt;&lt;span&gt;Gitea: Internal error
&lt;&#x2F;span&gt;&lt;span&gt;To git.mat.services:mat&#x2F;fly-apps.git
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;! &lt;&#x2F;span&gt;&lt;span&gt;[remote rejected] main -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ececec;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; main (pre-receive hook declined)
&lt;&#x2F;span&gt;&lt;span&gt;error: failed to push some refs to &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d68686;&quot;&gt;git.mat.services:mat&#x2F;fly-apps.git&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d6d6d680;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Uh. Hm. I just got an email saying a Fly.io instance ran out of memory and crashed. Let&#x27;s peek at our Fly.io dashboards:&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Fly.io memory dashboard&quot; src=fly-io-memory-dashboard.webp &#x2F;&gt;
&lt;figcaption&gt;&lt;p&gt;Fly.io memory dashboard&lt;&#x2F;p&gt;&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;That doesn&#x27;t look so great. It seems like Gitea idles just under the amount of memory we have with a default instance size, and operations like &lt;code&gt;git push&lt;&#x2F;code&gt; can bump it over the threshold to an out-of-memory error. Let&#x27;s check out the &amp;quot;Scale&amp;quot; section of the dashboard, and increase the memory allotment for this VM:&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;img alt=&quot;Fly.io VM scaling interface&quot; src=fly-io-scale-vm.webp &#x2F;&gt;
&lt;figcaption&gt;&lt;p&gt;Fly.io VM scaling interface&lt;&#x2F;p&gt;&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;You can also use &lt;code&gt;flyctl&lt;&#x2F;code&gt; to scale your app!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#393939;color:#dedede;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span&gt;flyctl scale memory 512
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I have been running my Gitea install on a 512MB instance since the first day I started using it, which seems to be plenty of headroom for personal use. If you open up your Gitea installation to the public and it starts to get popular, you might end up needing to scale up further.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s worth noting that scaling up to 512 MB means you will start accruing a Fly.io balance, but so far this has never been more than a $2 monthly bill for me. If that&#x27;s too steep for you, consider that Fly.io doesn&#x27;t (at the time of this writing) charge for monthly bills below $5, or else check out some of the competing PaaS options out there.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xeiaso.net&#x2F;blog&#x2F;fly.io-heroku-replacement&quot;&gt;Thank you to Xe Iaso for xer blog post on Fly.io that inspired me to try it in the first place!&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.gitea.io&#x2F;2022&#x2F;04&#x2F;running-gitea-on-fly.io&#x2F;&quot;&gt;Thank you to techknowlogick for their instructive post on running Gitea on Fly.io!&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

		</content>
	</entry>
	
</feed>