<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jasper</title>
    <description>The latest articles on DEV Community by Jasper (@jasper-clarke).</description>
    <link>https://dev.to/jasper-clarke</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1432477%2F79429cc0-c031-465c-bb47-0e144761d0ce.JPG</url>
      <title>DEV Community: Jasper</title>
      <link>https://dev.to/jasper-clarke</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jasper-clarke"/>
    <language>en</language>
    <item>
      <title>Integrating Svelte 5 with GSAP 3</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Sun, 09 Mar 2025 02:26:50 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/integrating-svelte-5-with-gsap-3-54no</link>
      <guid>https://dev.to/jasper-clarke/integrating-svelte-5-with-gsap-3-54no</guid>
      <description>&lt;p&gt;&lt;em&gt;Inspired by &lt;a href="https://dev.to/manyeya/how-i-integrate-svelte-with-gsap-3-4ll0"&gt;this post&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;GSAP is, in my opinion, the go-to library for creating page animations.&lt;/p&gt;

&lt;p&gt;If however you have ever tried to use GSAP with Svelte you will know that it can be a cluttered mess of code and a bit fidgety to use.&lt;br&gt;
I mean just take a look at the code I was using for my website.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;heroSection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;philosophySection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;projectsSection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;experienceSection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;contactSection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;onMount&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ScrollTrigger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Hero section animations&lt;/span&gt;
        &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heroSection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heroSection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.hero-text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// and so on...&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously there is a better way to do this, after finding the post I linked above it already made things a lot easier!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// animate.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gsap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- +page.svelte --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
  &lt;span class="na"&gt;use:animate=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;from&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expo.inOut&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Link&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is still a problem with this though. Since it's in JavaScript, there is no type checking and you can't use the autocomplete in your IDE.&lt;/p&gt;

&lt;p&gt;After making a few changes it now fully supports TypeScript and meets all the requirements of a Svelte action so the LSP doesn't complain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// animate.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gsap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AnimationType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AnimationOptions&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;GSAPTweenVars&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AnimationType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AnimationOptions&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TweenTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GSAPTweenVars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;GSAPTween&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`GSAP method "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" does not exist.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Create the animation&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tween&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Kill the animation when the element is removed&lt;/span&gt;
            &lt;span class="nx"&gt;tween&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But there is still one more issue, the scrollTrigger option doesn't work!&lt;br&gt;
And adding &lt;code&gt;gsap.registerPlugin(ScrollTrigger);&lt;/code&gt; to your &lt;code&gt;onMount&lt;/code&gt; function doesn't work either. A little extra work is needed to get this working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// animate.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gsap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ScrollTrigger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gsap/ScrollTrigger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Register the ScrollTrigger plugin with GSAP&lt;/span&gt;
&lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ScrollTrigger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AnimationType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AnimationOptions&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;GSAPTweenVars&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AnimationType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;ScrollTrigger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Vars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AnimationOptions&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TweenTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GSAPTweenVars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;GSAPTween&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`GSAP method "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" does not exist.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Create the animation with ScrollTrigger if provided&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tween&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;scrollTrigger&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Kill the animation when the element is removed&lt;/span&gt;
            &lt;span class="nx"&gt;tween&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// If using ScrollTrigger, make sure to kill that instance too&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scrollTrigger&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;tween&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;tween&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This updated code registers the ScrollTrigger plugin with GSAP and allows you to pass in a &lt;code&gt;scrollTrigger&lt;/code&gt; option to the &lt;code&gt;animate&lt;/code&gt; function. In doing this it will automatically set the element you have used this action on as the &lt;code&gt;scrollTrigger.trigger&lt;/code&gt; element!&lt;/p&gt;

&lt;p&gt;Now you can use it like this and have full type checking in your IDE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"overflow-hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"font-serif text-7xl font-medium"&lt;/span&gt;
    &lt;span class="na"&gt;use:animate=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;from&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;yPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;power4.out&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;scrollTrigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;top 70%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;top 20%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;toggleActions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;play none none reverse&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="err"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Other content
  &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope this helps and massive shoutout to &lt;a href="https://dev.to/manyeya"&gt;Khutso Siema&lt;/a&gt; for the original post.&lt;/p&gt;

</description>
      <category>gsap</category>
      <category>svelte</category>
      <category>sveltekit</category>
      <category>webdev</category>
    </item>
    <item>
      <title>NixOS Full Disk Encryption with USB/SD-Card/Password Unlock</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Fri, 01 Nov 2024 07:11:50 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/nixos-full-disk-encryption-with-usbsd-cardpassword-unlock-4mg</link>
      <guid>https://dev.to/jasper-clarke/nixos-full-disk-encryption-with-usbsd-cardpassword-unlock-4mg</guid>
      <description>&lt;p&gt;Not long ago I had some super secure data on my server and I wanted it to survive just about anything from a network attack to a physical theft.&lt;br&gt;
Now the NixOS documentation is a bit lacking on this topic, but I've found a few resources that helped me to get this working.&lt;br&gt;
Here you go guys, finally a single guide with all the steps.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://qfpl.io/posts/installing-nixos/" rel="noopener noreferrer"&gt;Queensland FP Lab - Installing NixOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.nixos.org/wiki/Full_Disk_Encryption" rel="noopener noreferrer"&gt;Full Disk Encryption - NixOS Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This guide does expect that you are in the minimal ISO and have connected to your network via Ethernet or &lt;code&gt;wpa_cli&lt;/code&gt;.&lt;br&gt;
If you want to know how to setup NixOS from the very beginning, check out my &lt;a href="https://jasperclarke.com/blog/nixos-homelab-the-install" rel="noopener noreferrer"&gt;NixOS Homelab Install Guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Partitioning
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In the following snippets I will refer to the drive we are encrypting as &lt;code&gt;/dev/sda&lt;/code&gt; but yours might be &lt;code&gt;/dev/nvme0n1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you haven't already, switch to the root user with &lt;code&gt;sudo -i&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Open gdisk on the disk we're installing on&lt;/span&gt;
gdisk /dev/sda

&lt;span class="c"&gt;# -----------------------&lt;/span&gt;
&lt;span class="c"&gt;# BEGIN GDISK COMMANDS&lt;/span&gt;

&lt;span class="c"&gt;# print the partitions on the disk&lt;/span&gt;
Command: p

&lt;span class="c"&gt;# Delete a partition. Select the partition number when prompted.&lt;/span&gt;
&lt;span class="c"&gt;# Repeat for all partitions.&lt;/span&gt;
Command: d

&lt;span class="c"&gt;# Create the EFI boot partition&lt;/span&gt;
Command: n
Partition number: 1
First sector: &amp;lt;enter &lt;span class="k"&gt;for &lt;/span&gt;default&amp;gt;
Last sector: +1G       &lt;span class="c"&gt;# make a 1 gigabyte partition&lt;/span&gt;
Hex code or GUID: ef00 &lt;span class="c"&gt;# this is the EFI System type&lt;/span&gt;

&lt;span class="c"&gt;# Create the LVM partition&lt;/span&gt;
Command: n
Partition number: 2
First sector: &amp;lt;enter &lt;span class="k"&gt;for &lt;/span&gt;default&amp;gt;
Last sector: &amp;lt;enter &lt;span class="k"&gt;for &lt;/span&gt;default - rest of disk&amp;gt;
Hex code or GUID: 8e00 &lt;span class="c"&gt;# Linux LVM type&lt;/span&gt;

&lt;span class="c"&gt;# Write changes and quit&lt;/span&gt;
Command: w

&lt;span class="c"&gt;# END GDISK COMMANDS&lt;/span&gt;
&lt;span class="c"&gt;# ---------------------&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want more of an explanation on what these commands are doing please look at the &lt;a href="https://qfpl.io/posts/installing-nixos/" rel="noopener noreferrer"&gt;Queensland FP Lab - Installing NixOS&lt;/a&gt; post as it is really good!&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting and Encryption
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;$LVM_PARTITION&lt;/code&gt; is &lt;code&gt;/dev/nvme0n1p2&lt;/code&gt; or &lt;code&gt;/dev/sda2&lt;/code&gt;, this is the second partition we just created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# You will be asked to enter your passphrase - DO NOT FORGET THIS&lt;/span&gt;
cryptsetup luksFormat &lt;span class="nv"&gt;$LVM_PARTITION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to decrypt the drive on boot without input you can write a decryption key to a USB or SD Card.&lt;br&gt;
As an example if you only ever access this computer via SSH you will want the computer to be able to boot independantly without needing a password input.&lt;/p&gt;

&lt;p&gt;Note this method will make the decryption drive unusuable for anything else.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a random key&lt;/span&gt;
&lt;span class="nb"&gt;dd &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/random &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hdd.key &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4096 &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="c"&gt;# Append the key to the list of secure keys that can unlock the drive.&lt;/span&gt;
cryptsetup luksAddKey &lt;span class="nv"&gt;$LVM_PARTITION&lt;/span&gt; ./hdd.key

&lt;span class="c"&gt;# Now write the key to your USB or SD Card, find it from lsblk.&lt;/span&gt;
&lt;span class="nb"&gt;dd &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hdd.key &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/REPLACE-HERE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continue here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SKIP TO HERE IF NOT USING USB UNLOCKING.&lt;/span&gt;
&lt;span class="c"&gt;# Decrypt the encrypted partition and call it nixos-enc. The decrypted partition&lt;/span&gt;
&lt;span class="c"&gt;# will get mounted at /dev/mapper/nixos-enc&lt;/span&gt;
cryptsetup luksOpen &lt;span class="nv"&gt;$LVM_PARTITION&lt;/span&gt; nixos-enc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create the LVM physical volume using nixos-enc&lt;/span&gt;
pvcreate /dev/mapper/nixos-enc

&lt;span class="c"&gt;# Create a volume group that will contain our root and swap partitions&lt;/span&gt;
vgcreate nixos-vg /dev/mapper/nixos-enc

&lt;span class="c"&gt;# Create a swap partition that is 16G in size - the amount of RAM on this machine&lt;/span&gt;
&lt;span class="c"&gt;# Volume is labeled "swap"'&lt;/span&gt;
lvcreate &lt;span class="nt"&gt;-L&lt;/span&gt; 16G &lt;span class="nt"&gt;-n&lt;/span&gt; swap nixos-vg

&lt;span class="c"&gt;# Create a logical volume for our root filesystem from all remaining free space.&lt;/span&gt;
&lt;span class="c"&gt;# Volume is labeled "root"&lt;/span&gt;
lvcreate &lt;span class="nt"&gt;-l&lt;/span&gt; 100%FREE &lt;span class="nt"&gt;-n&lt;/span&gt; root nixos-vg

&lt;span class="c"&gt;# $BOOT_PARTITION is your first partition, so `/dev/nvme0n1p1` or `/dev/sda1`&lt;/span&gt;

&lt;span class="c"&gt;# Create a FAT32 filesystem on our boot partition&lt;/span&gt;
mkfs.vfat &lt;span class="nt"&gt;-n&lt;/span&gt; boot &lt;span class="nv"&gt;$BOOT_PARTITION&lt;/span&gt;

&lt;span class="c"&gt;# Create an ext4 filesystem for our root partition&lt;/span&gt;
mkfs.ext4 &lt;span class="nt"&gt;-L&lt;/span&gt; nixos /dev/nixos-vg/root

&lt;span class="c"&gt;# Tell our swap partition to be a swap&lt;/span&gt;
mkswap &lt;span class="nt"&gt;-L&lt;/span&gt; swap /dev/nixos-vg/swap

&lt;span class="c"&gt;# Turn the swap on before install&lt;/span&gt;
swapon /dev/nixos-vg/swap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's mount the file system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mount /dev/nixos-vg/root /mnt
&lt;span class="nb"&gt;mkdir&lt;/span&gt; /mnt/boot
&lt;span class="c"&gt;# $BOOT_PARTITION is your first partition, so `/dev/nvme0n1p1` or `/dev/sda1`&lt;/span&gt;
mount &lt;span class="nv"&gt;$BOOT_PARTITION&lt;/span&gt; /mnt/boot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here just generate a new configuration and replace the existing &lt;code&gt;boot&lt;/code&gt; options with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;boot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;efi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;canTouchEfiVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;grub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;efiSupport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nodev"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nv"&gt;initrd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;kernelModules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"usb_storage"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nv"&gt;luks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;devices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;cryptroot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/dev/second-partition-of-your-drive"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;preLVM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c"&gt;# If using a USB or SD Card for decryption include the following.&lt;/span&gt;
      &lt;span class="nv"&gt;allowDiscards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;keyFileSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c"&gt;# This is the disk id of your USB or SD Card.&lt;/span&gt;
      &lt;span class="c"&gt;# Get this by running `ls -l /dev/disk/by-id`,&lt;/span&gt;
      &lt;span class="c"&gt;# and copy the long string into the spot below.&lt;/span&gt;
      &lt;span class="nv"&gt;keyFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/dev/disk/by-id/REPLACE-HERE"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c"&gt;# Use this if you want to fallback to the encryption password&lt;/span&gt;
      &lt;span class="c"&gt;# when the drive can't be found. HIGHLY RECCOMENDED!!!!&lt;/span&gt;
      &lt;span class="nv"&gt;fallbackToPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just setup your configuration and run &lt;code&gt;nixos-install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that is it! Full Disk Encryption and remote unlocking with a flash drive.&lt;br&gt;
Again if your looking for more info or run into any issue check the two links at the top of this guide.&lt;/p&gt;

&lt;p&gt;This has been Jasper, until next time 👋&lt;/p&gt;

</description>
      <category>linux</category>
      <category>nixos</category>
    </item>
    <item>
      <title>What Language Should I Choose?</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Fri, 11 Oct 2024 11:49:14 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/what-language-should-i-choose-5ob</link>
      <guid>https://dev.to/jasper-clarke/what-language-should-i-choose-5ob</guid>
      <description>&lt;p&gt;Whether your just getting started with programming or you have been learning for many years now, the most common question you have probably asked yourself is: What language should I choose?&lt;br&gt;
I asked myself that question quite often for a long time, but now I have the answer and I'm here to tell you it!&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Consider What You Enjoy
&lt;/h3&gt;

&lt;p&gt;Maybe it sounds obvious but, how much you enjoy writing/testing/debugging in a language plays a huge role in your confidence and in turn ability to code with that tool-set.&lt;br&gt;
When you find a language piquing your interest you want to learn more and more about it, you get that drive to dive deeper and deeper down the rabbit hole.&lt;/p&gt;

&lt;p&gt;One language that really gave me that feeling was &lt;a href="https://gleam.run" rel="noopener noreferrer"&gt;Gleam&lt;/a&gt;, it managed to wrap everything I liked about languages such as JS, &lt;a href="https://rust-lang.org" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; and even &lt;a href="https://java.com" rel="noopener noreferrer"&gt;Java&lt;/a&gt; into one brilliant type-safe package.&lt;br&gt;
Not for a long time before I met Gleam had I wanted to try creating so many different things just to get to the bottom of how this language ticked, as it were.&lt;/p&gt;

&lt;p&gt;So let's say you want to do web development, you watched some YouTube's and all the cool kids are using &lt;a href="https://react.dev" rel="noopener noreferrer"&gt;React&lt;/a&gt; and &lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Next.JS&lt;/a&gt;, maybe you decided you would go another route like &lt;a href="https://go.dev" rel="noopener noreferrer"&gt;Golang&lt;/a&gt; with &lt;a href="https://htmx.org" rel="noopener noreferrer"&gt;HTMX&lt;/a&gt;. Whatever it is, you have inadvertently joined a cult, welcome!&lt;/p&gt;

&lt;p&gt;All jokes aside the framework or language you start with can typically stick with you the longest, like Javascript or perhaps Python. From that point you have options, you could do what I did and just follow demand or like some others have done and just tried absolutely everything their language had to offer (that means all frameworks too).&lt;/p&gt;

&lt;p&gt;Maybe you decided you would stick a limb out and jump on the Rust bandwagon, ride off into the sunset and crash into the borrow checker inevitably a few hundred times.&lt;/p&gt;

&lt;p&gt;The point I want to make is, if you have an itch for a certain language or tool, go ahead and try it. And once you find something you love, stick to it!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Demand in the Industry
&lt;/h3&gt;

&lt;p&gt;The second key decider is simple: &lt;em&gt;Is it in demand?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When choosing a language or framework, you want to make sure your skills align with industry needs, unless you're freelancing. Freelance work typically gives you more flexibility in your choice of tech stack since, at the end of the day, clients care more about results than the tools used to get them. For instance, Martha who just wants to share her 56 cats with the world via a blog that automatically gets cat photos from her phone and posts them will not understand the difference between a backend in Rust or VisualBasic when she is using her site. If it works, it works. If you love what your doing, your on the right track.&lt;/p&gt;

&lt;p&gt;If though your looking to join the next big unicorn startup, it's worth understanding the tech trends in your desired industry. A large amount of startups have been using Javascript frameworks like React or it's many delineations such as Next.js or Remix. So your best bet will be learning as much as you can about Javascript and trying out a few frameworks for yourself.&lt;/p&gt;

&lt;p&gt;If your looking for maybe a more backend focused position though at a startup I have heard Golang is becoming more and more popular, but make sure to &lt;a href="https://survey.stackoverflow.co/2024/" rel="noopener noreferrer"&gt;check your facts&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;In general my advice is, if your going freelance, do exactly what you want to do! Use Rust and Dioxus, use Gleam and Lustre, use Python and Django, whatever your heart desires follow it.&lt;br&gt;
If you though want to go after startups or just a company in general, do some research into companies in your local area if that is an option where you live or start doing market research into the most sort positions and compare the requested skills with what you enjoy, that will help you make a better guided decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Importance of Experimentation
&lt;/h3&gt;

&lt;p&gt;Ultimately, there’s no substitute for hands-on experience. One of the best ways to learn and grow as a developer is by &lt;em&gt;trying&lt;/em&gt; different languages and frameworks. Each one will teach you new concepts and offer unique insights into how problems can be solved.&lt;/p&gt;

&lt;p&gt;Over the years, I've gone from Java to JS, dipped my toes into Rust, and many others, all while picking up knowledge along the way. The more languages you experiment with, the broader your problem-solving toolkit becomes. Concepts like concurrency in Go, type safety in Rust, or the asynchronous, non-blocking, dare I say rage inducing, nature of JavaScript all build your understanding and make you a more versatile developer.&lt;/p&gt;

&lt;p&gt;If you’re interested in a language other than the one your currently the best at, give it a go! The only way to know if you like something is to try it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;When deciding which language or framework to learn next, balance personal enjoyment with practicality. If you like a language, you'll naturally lean toward mastering it. At the same time take a good look for the opportunities available for you and how they align with your interests.&lt;/p&gt;

&lt;p&gt;No matter what you choose, whether it's diving deeper into a familiar stack or venturing into new territory with a brand new language, the key takeaway is this: &lt;em&gt;Experiment, learn, and apply.&lt;/em&gt; Every language you learn contributes to your growth as a developer, and in the end, it’s not about the language itself but how well you can use it to solve problems and in turn make the world a better place.&lt;/p&gt;

&lt;p&gt;This has been Jasper, until next time 👋&lt;/p&gt;

</description>
      <category>newbie</category>
      <category>help</category>
      <category>developer</category>
    </item>
    <item>
      <title>The Cleanest Icons for your next README.</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Fri, 16 Aug 2024 07:08:05 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/the-cleanest-icons-for-your-next-readme-1f0h</link>
      <guid>https://dev.to/jasper-clarke/the-cleanest-icons-for-your-next-readme-1f0h</guid>
      <description>&lt;p&gt;Just a quick post today but one I really wanted to make.&lt;/p&gt;

&lt;p&gt;A while ago I came across a repository called &lt;a href="https://github.com/Nighty3098/DevIcons" rel="noopener noreferrer"&gt;DevIcons&lt;/a&gt; and instantly fell in love with the clean pastel colors on the minimalist iconography.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Nighty3098" rel="noopener noreferrer"&gt;
        Nighty3098
      &lt;/a&gt; / &lt;a href="https://github.com/Nighty3098/DevIcons" rel="noopener noreferrer"&gt;
        DevIcons
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Dev icons
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
    &lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIconsbanner.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIconsbanner.png" width="90%"&gt;&lt;/a&gt;
    &lt;br&gt;
    &lt;br&gt;
    &lt;br&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b236e9b90ac07326109d5870d8cf6e501c7bda21f8201106a37f68e9def71e75/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7265706f2d73697a652f4e6967687479333039382f44657649636f6e733f7374796c653d666f722d7468652d626164676526636f6c6f723d656139646537266c6f676f436f6c6f723d443945304545266c6162656c436f6c6f723d313731623232"&gt;&lt;img src="https://camo.githubusercontent.com/b236e9b90ac07326109d5870d8cf6e501c7bda21f8201106a37f68e9def71e75/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7265706f2d73697a652f4e6967687479333039382f44657649636f6e733f7374796c653d666f722d7468652d626164676526636f6c6f723d656139646537266c6f676f436f6c6f723d443945304545266c6162656c436f6c6f723d313731623232"&gt;&lt;/a&gt;
    &lt;a href="https://github.com/Nighty3098/DevIcons./LICENSE.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eded86d2053ca56c046af827d81a58986a2a9e511dabdf2d7ed4a9710120aeb7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f4e6967687479333039382f44657649636f6e733f7374796c653d666f722d7468652d626164676526636f6c6f723d613665306238266c6f676f436f6c6f723d666666666666266c6162656c436f6c6f723d316331633239"&gt;&lt;/a&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/1cd51a02a0ea2cf2260912168b165697e2c8e70dc0e6639614233c77acbc3d9a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f4e6967687479333039382f44657649636f6e733f7374796c653d666f722d7468652d626164676526636f6c6f723d646262366564266c6f676f436f6c6f723d666666666666266c6162656c436f6c6f723d316331633239"&gt;&lt;img src="https://camo.githubusercontent.com/1cd51a02a0ea2cf2260912168b165697e2c8e70dc0e6639614233c77acbc3d9a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f4e6967687479333039382f44657649636f6e733f7374796c653d666f722d7468652d626164676526636f6c6f723d646262366564266c6f676f436f6c6f723d666666666666266c6162656c436f6c6f723d316331633239"&gt;&lt;/a&gt;
    &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/d64fb3c43935c3f99d67b911b8c3f0089c1c9e85dc0c923aab5144c839d31ae8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f4e6967687479333039382f44657649636f6e733f7374796c653d666f722d7468652d626164676526636f6c6f723d656564343966266c6f676f436f6c6f723d443945304545266c6162656c436f6c6f723d316331633239"&gt;&lt;img src="https://camo.githubusercontent.com/d64fb3c43935c3f99d67b911b8c3f0089c1c9e85dc0c923aab5144c839d31ae8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f4e6967687479333039382f44657649636f6e733f7374796c653d666f722d7468652d626164676526636f6c6f723d656564343966266c6f676f436f6c6f723d443945304545266c6162656c436f6c6f723d316331633239"&gt;&lt;/a&gt;
    &lt;br&gt;&lt;br&gt;
    &lt;a href="https://discord.gg/6xEc5WFK" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bd723f12b1381b7d94902ac8aa5e7919af37c482533c4a178da98c67be93f739/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f313233383835383138323430333535393530352e7376673f6c6162656c3d446973636f7264266c6f676f3d446973636f7264267374796c653d666f722d7468652d626164676526636f6c6f723d663561376130266c6f676f436f6c6f723d464646464646266c6162656c436f6c6f723d316331633239"&gt;&lt;/a&gt;
    &lt;br&gt;&lt;br&gt;&lt;br&gt;
    &lt;a href="https://t.me/DXS_TechSupport_bot" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_TechSupport.png" height="35px"&gt;&lt;/a&gt;
    &lt;br&gt;&lt;br&gt;
&lt;p&gt;&lt;code&gt;Ctrl+F to find the badge&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;icon&lt;/th&gt;
&lt;th&gt;Badge name&lt;/th&gt;
&lt;th&gt;link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_Portfolio.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_Portfolio.png%3Fraw%3Dtrue" height="40px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Portfolio&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_Portfolio.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_discord_server.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_discord_server.png%3Fraw%3Dtrue" height="40px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Discord server&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_discord_server.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_blog.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_blog.png%3Fraw%3Dtrue" height="40px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Blog&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_blog.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_LinkedIn_badge.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_LinkedIn_badge.png%3Fraw%3Dtrue" height="40px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;LinkedIn&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_LinkedIn_badge.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_Site.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_Site.png%3Fraw%3Dtrue" height="40px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Site&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_Site.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_TechSupport.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_TechSupport.png" height="40px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tech Support&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_TechSupport.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

Social
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;icon&lt;/th&gt;
&lt;th&gt;Badge name&lt;/th&gt;
&lt;th&gt;link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_reddit.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_reddit.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Reddit&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_reddit.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_telegram.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_telegram.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Telegram&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_telegram.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_discord.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_discord.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Discord&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_discord.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_signal.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_signal.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Signal&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_signal.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_x.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_x.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_x.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_youtube.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_youtube.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;YouTube&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_youtube.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_linkedIn.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_linkedIn.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;LinkedIn&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_linkedIn.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_matrix.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_matrix.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Matrix&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_matrix.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


Languages
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;icon&lt;/th&gt;
&lt;th&gt;Badge name&lt;/th&gt;
&lt;th&gt;link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_bash.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_bash.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;BASH&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_bash.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_cpp.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_cpp.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_cpp.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_c.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_c.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_c.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_css.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_css.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;CSS&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_css.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_html.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_html.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;HTML&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_html.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_javascript.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_javascript.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;JS&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_javascript.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_markdown.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_markdown.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_markdown.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_python.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_python.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_python.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_typescript.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_typescript.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_typescript.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_rust.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_rust.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;rust&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_rust.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_lua.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_lua.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;lua&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_lua.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_ruby.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_ruby.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ruby&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_ruby.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_php.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_php.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;php&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_php.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_gleam.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_gleam.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;gleam&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_gleam.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_java.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_java.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;java&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_java.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_golang.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_golang.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;golang&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_golang.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


BD
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;icon&lt;/th&gt;
&lt;th&gt;Badge name&lt;/th&gt;
&lt;th&gt;link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sql.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_sql.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;SQL&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sql.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sqlite.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_sqlite.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;SQLite&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sqlite.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sql.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_sql.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;MySql&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sql.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_firebase.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_firebase.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;firebase&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_firebase.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_pocketbase.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_pocketbase.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;pocketbase&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_pocketbase.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_supabase.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_supabase.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;supabase&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_supabase.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


Dev
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;icon&lt;/th&gt;
&lt;th&gt;Badge name&lt;/th&gt;
&lt;th&gt;link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_docker.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_docker.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_dev.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_dev.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_dev.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Dev To&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_dev.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sfml.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_sfml.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;sfml&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_sfml.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_qt.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_qt.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;QT&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_qt.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_react.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_react.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;react&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_react.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_api.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_api.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Api&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_api.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_git.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_git.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Git&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_git.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_svelte.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_svelte.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;SvelteKit&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_svelte.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_gitlab.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_gitlab.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;gitlab&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_gitlab.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_stack_overflow.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_stack_overflow.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;stack_overflow&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_stack_overflow.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_prisma.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_prisma.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;prisma&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_prisma.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_HackTheBox.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_HackTheBox.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;HackTheBox&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_HackTheBox.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_Jupyter.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_Jupyter.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Jupyter&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_Jupyter.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_OpenSource.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_OpenSource.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;OpenSource&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_OpenSource.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_postman.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_postman.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;postman&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_postman.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_laravel.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_laravel.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;laravel&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_laravel.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_ton.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_ton.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ton&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_ton.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


Apps
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;icon&lt;/th&gt;
&lt;th&gt;Badge name&lt;/th&gt;
&lt;th&gt;link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_replit.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_replit.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;replit&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_replit.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_inkdrop.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_inkdrop.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;inkdrop&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_inkdrop.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_spotify.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_spotify.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;spotify&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_spotify.png?raw=true" rel="noopener noreferrer"&gt; &lt;br&gt; Open &lt;br&gt; &lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Nighty3098/DevIcons/blob/main/badges/badges_notion.png?raw=true"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FNighty3098%2FDevIcons%2Fraw%2Fmain%2Fbadges%2Fbadges_notion.png%3Fraw%3Dtrue" width="60px"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Notion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Nighty3098/DevIcons" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I have seen many, many, MANY, icon libraries in an attempt to find one suitable for myself, but never before until now have I found one that I could say was the best.&lt;br&gt;
Just recently too 5 new icons were added! (at my request ;3)&lt;/p&gt;

&lt;p&gt;Just a quick shout out but I think a lot of Minimalists like myself will value this post.&lt;br&gt;
Thanks all and catch you next time,&lt;br&gt;
Jasper&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>github</category>
      <category>writing</category>
    </item>
    <item>
      <title>I Changed My Mind - NixOS is NOT the Best Linux</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Sun, 11 Aug 2024 01:46:12 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/i-changed-my-mind-nixos-is-not-the-best-linux-1cpj</link>
      <guid>https://dev.to/jasper-clarke/i-changed-my-mind-nixos-is-not-the-best-linux-1cpj</guid>
      <description>&lt;p&gt;Well I didn't expect to be writing this post, ever.&lt;/p&gt;

&lt;p&gt;Most of my posts on here have just been NixOS and praising its glory to all but recently I have been greatly disliking NixOS more and more.&lt;/p&gt;

&lt;p&gt;But what does this mean for you? It could mean nothing, or it could mean everything...&lt;/p&gt;

&lt;h2&gt;
  
  
  NixOS Pros
&lt;/h2&gt;

&lt;p&gt;I can't say NixOS isn't great, it has so many amazingly useful features that just make using Linux so much easier.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All packages are version locked. (Easy to roll back versions)&lt;/li&gt;
&lt;li&gt;All package dependencies are per package so version conflicts are prevented.&lt;/li&gt;
&lt;li&gt;Thousands of services are now easily configurable from the ground up thanks to NixOS Options.&lt;/li&gt;
&lt;li&gt;It provides a similar format to docker in that your whole system is a container that can be perfectly and precisely replicated anywhere!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These have been the reasons I stuck with NixOS for the past year.&lt;br&gt;
But the way NixOS does some of these things has also been its downfall for me.&lt;/p&gt;
&lt;h2&gt;
  
  
  NixOS Cons
&lt;/h2&gt;

&lt;p&gt;The greatest problem I have experienced with NixOS is actually development.&lt;br&gt;
Working with anything that requires external libraries like &lt;code&gt;C&lt;/code&gt;, &lt;code&gt;Java&lt;/code&gt; or even &lt;code&gt;Rust&lt;/code&gt; has been so much of a pain I have just given up on projects because of it.&lt;/p&gt;

&lt;p&gt;But what is the problem exactly?&lt;br&gt;
NixOS makes it very difficult to simply, install a library and have it accessible to the rest of your system.&lt;/p&gt;

&lt;p&gt;On Arch setting up a OpenGL environment for &lt;code&gt;C&lt;/code&gt; is as easy as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; gcc cmake make glfw glew libglv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On NixOS you can't just add these packages to your package list and call it a day, you need to setup whatever &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;s are and even then I couldn't get it to work.&lt;/p&gt;

&lt;p&gt;It turns a simple idea of, "Hey I'm going to have a crack at some C and write a OpenGL program", to, "I literally don't understand how to even get this setup, at this point I haven't even wrote any code and I'm burnt out".&lt;/p&gt;

&lt;p&gt;I got so fed up I started looking into switching Distro's entirely.&lt;br&gt;
&lt;em&gt;"Where did that lead you, back to me" - Arch Linux"&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Arch, dangerous but simple
&lt;/h2&gt;

&lt;p&gt;Now don't worry I'm not actually abandoning NixOS. But I will be using an Arch Virtual Machine to do any kind of graphics or library dependent development.&lt;/p&gt;

&lt;p&gt;Thanks to my &lt;a href="https://dev.to/jasper-at-windswept/the-definitive-guide-to-installing-arch-linux-5gg1"&gt;guide on installing Arch&lt;/a&gt; is was really easy to setup and like I illustrated earlier it took my around 30 seconds to get my environment ready and I could just start coding, wonderful!&lt;/p&gt;

&lt;p&gt;Arch does make it slightly more tedious to setup the actual operating system, but its a sacrifice I can make for being able to quickly spin  up any development environment I want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Arch makes the operating system tedious, but the development environment easy.&lt;br&gt;
NixOS makes the operating system easy, but the development environment torture.&lt;/p&gt;

&lt;p&gt;It really seems like there is no perfect Linux distribution. Not yet at least.&lt;/p&gt;

&lt;p&gt;Until next time, thank for tuning in.&lt;br&gt;
Jasper out.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>archlinux</category>
      <category>nixos</category>
      <category>productivity</category>
    </item>
    <item>
      <title>This Language has just Solved Concurrency in your Backend Services.</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Sun, 21 Jul 2024 04:37:55 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/this-language-has-just-solved-concurrency-in-your-backend-services-1043</link>
      <guid>https://dev.to/jasper-clarke/this-language-has-just-solved-concurrency-in-your-backend-services-1043</guid>
      <description>&lt;p&gt;&lt;em&gt;Ok Jasper what is this post about, wait it isn't NixOS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's right, today I'm covering my new love language &lt;a href="https://gleam.run" rel="noopener noreferrer"&gt;Gleam&lt;/a&gt;, "a friendly language for building type-safe systems that scale".&lt;/p&gt;

&lt;p&gt;So not long ago I was scrolling through YouTube and on my home page I saw this video by Isaac Harris-Holt. And I was blown away, "Wait I don't have to use Rust to make highly performant non-crashing services?".&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/D88S_RdagP8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I immediately fell in love with the language and proceeded to the &lt;a href="https://tour.gleam.run/" rel="noopener noreferrer"&gt;Gleam Language Tour&lt;/a&gt; and besides the &lt;a href="https://learn.svelte.dev/tutorial/welcome-to-svelte" rel="noopener noreferrer"&gt;SvelteKit Tutorial&lt;/a&gt;, this is the best language guide I had ever seen. After only 2 days I felt I had a full grasp on the language.&lt;/p&gt;

&lt;p&gt;"Ok Jasper cool, you have a crush on a new vague language I have never heard on, why do I care again?"&lt;/p&gt;

&lt;p&gt;You care, my friend, because you no longer have to learn Rust to ensure your backend doesn't crash and you don't need to learn Go for high concurrency. You get both benefits in just one language.&lt;/p&gt;

&lt;p&gt;And before anyone decides to smoke me in the comments, I do understand that Go and Rust are lower level languages whereas Gleam is sort of a mid-level language as it runs on the BEAM Virtual Machine. &lt;/p&gt;

&lt;p&gt;However I have seen the great argument that the only way to make a backend that doesn't crash is with something like Rust for ultimate type-safety and protection from memory errors (which isn't foolproof). But after using Gleam for around a month I can say you really don't need Rust for that, Gleam has incredible type safety and  the fault tolerance of the Erlang runtime to power it in creating efficient and scalable backend infrastructure. &lt;/p&gt;

&lt;p&gt;I mean WhatsApp uses it, it must be good! &lt;em&gt;(this is a joke lol)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With Gleam's recent v1.3 release we now have auto-import for the LSP which is a great assistance to developers, aswell as &lt;a href="https://gleam.run/news/auto-imports-and-tolerant-expressions/" rel="noopener noreferrer"&gt;many more features&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If it wasn't already clear this is a very opinionated post but I really just wanted to share this language and help get others into it because I truly believe this language will help power the future of backend development. &lt;em&gt;Typescript has to die soon right?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So if this post interested you at all please check out &lt;a href="https://gleam.run" rel="noopener noreferrer"&gt;Gleam&lt;/a&gt; and &lt;a href="https://www.youtube.com/@IsaacHarrisHolt" rel="noopener noreferrer"&gt;Isaac's channel&lt;/a&gt; because I think he is single-handedly providing the best gleam education currently available.&lt;/p&gt;

&lt;p&gt;That's all from me this post, until next time.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>webdev</category>
      <category>backenddevelopment</category>
      <category>rust</category>
    </item>
    <item>
      <title>The Definitive Guide to Installing Arch Linux</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Thu, 18 Jul 2024 23:26:47 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/the-definitive-guide-to-installing-arch-linux-5gg1</link>
      <guid>https://dev.to/jasper-clarke/the-definitive-guide-to-installing-arch-linux-5gg1</guid>
      <description>&lt;p&gt;My better judgement told me not to make this post. But here we are, a definitive, beginner friendly guide to install Arch Linux.&lt;/p&gt;

&lt;p&gt;Before we continue I just wanted to give everyone a little back story as to my Arch Linux adventures. Well starting off, Arch was my very first Linux distribution. Yeah I didn't start with something easy like Ubuntu or Linux Mint.&lt;/p&gt;

&lt;p&gt;And the only reason I somewhat survived this is because of the amazing help of an old friend &lt;a href="https://solomon.tech" rel="noopener noreferrer"&gt;@SolomonTech&lt;/a&gt;. He is the craziest Linux user I know and he has mained Arch Linux for the last 4+ years. And Sol if you read this, I am writing this guide in your memory.&lt;/p&gt;

&lt;p&gt;Alright so back to the actual reason for this post, installing Arch Linux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated as of: July 2024&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Live ISO
&lt;/h2&gt;

&lt;p&gt;Ok so let's download the ISO and flash it to a spare 8-16GB USB.&lt;br&gt;
First download the arch ISO from &lt;a href="https://archlinux.org/downloads" rel="noopener noreferrer"&gt;this link&lt;/a&gt;, scroll down to the countries and find your closest one, download the file ending with &lt;code&gt;.iso&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Linux Users
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Check &lt;code&gt;lsblk&lt;/code&gt; for your USB flash drive, for example mine will be &lt;code&gt;/dev/sdb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Still in the terminal navigate to the folder where the ISO is and run:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo dd &lt;/span&gt;&lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;archlinux.iso &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdb &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress &lt;span class="nv"&gt;oflag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;sync&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Make sure to change &lt;code&gt;archlinux.iso&lt;/code&gt; to the file name of the ISO you just downloaded and change &lt;code&gt;/dev/sdb&lt;/code&gt; to your flash drives identifier.&lt;/p&gt;
&lt;h3&gt;
  
  
  Windows Users
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Get Rufus&lt;/li&gt;
&lt;li&gt;Install Rufus, select the ISO and your flash drive and click Start, then run in ISO mode. You don't need to change any other settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ok so now that we have our boot-able flash drive let's plug it into the computer you want to install Arch on and reboot it.&lt;br&gt;
I'm sure for anyone reading this you do know how to do stuff like entering BIOS and booting a flash drive but for those who are not familiar just hold DEL or F12 on your keyboard whilst your computer is turning on to bring up the boot menu, this key can be different depending on your motherboard so if your having trouble lookup the motherboard brand to find the key to open the "Boot Menu".&lt;/p&gt;

&lt;p&gt;From there select your flash drive, then when the Arch installer boots just press enter on the first option.&lt;/p&gt;

&lt;p&gt;You should have been greeted with "Welcome to Arch" or something similar and now be in a terminal with some instructions printed at the top.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiylpc0t1pmkzebk45kp6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiylpc0t1pmkzebk45kp6.png" alt="arch linux terminal greeter" width="634" height="323"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Networking
&lt;/h2&gt;

&lt;p&gt;If you have a ethernet cable connected to your computer, internet will work out of the box but if you have Wi-Fi only stick around for this next short bit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enter the IWD shell by typing:&lt;/span&gt;
iwctl

&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# BEGIN IWD SHELL COMMANDS&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;

&lt;span class="c"&gt;# List your wireless devices&lt;/span&gt;
device list

&lt;span class="c"&gt;# Replace $NAME with the name of your wifi device&lt;/span&gt;

&lt;span class="c"&gt;# Power on your adapter if it isn't already&lt;/span&gt;
device &lt;span class="nv"&gt;$NAME&lt;/span&gt; set-property Powered on

&lt;span class="c"&gt;# Scan for networks and list them&lt;/span&gt;
station &lt;span class="nv"&gt;$NAME&lt;/span&gt; get-networks

&lt;span class="c"&gt;# Remember the SSID value outputted here&lt;/span&gt;

&lt;span class="c"&gt;# Connect to an available network with password&lt;/span&gt;
station &lt;span class="nv"&gt;$NAME&lt;/span&gt; connect &lt;span class="nv"&gt;$SSID&lt;/span&gt;

&lt;span class="c"&gt;# Should have been successful, exit shell&lt;/span&gt;
&lt;span class="nb"&gt;exit&lt;/span&gt;

&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# END IWD SHELL COMMANDS&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with that you should be connected, if your not for any reason please check out the Arch Wiki on &lt;a href="https://wiki.archlinux.org/title/Iwd" rel="noopener noreferrer"&gt;IWD&lt;/a&gt; and &lt;a href="https://wiki.archlinux.org/title/Network_configuration/Wireless" rel="noopener noreferrer"&gt;Networking&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partitioning
&lt;/h2&gt;

&lt;p&gt;Before we jump right into partitioning though let's set our timezone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List available timezones, Navigate the list using `j` for down `k` for up and `q` to exit.&lt;/span&gt;
timedatectl list-timezones

&lt;span class="c"&gt;# Replace Country and City with yours&lt;/span&gt;
timedatectl set-timezone Country/City
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can partition,&lt;br&gt;
However I need to explain some basic fundamental concepts of drive labels.&lt;br&gt;
All drives are prefixed with &lt;code&gt;/dev/&lt;/code&gt;&lt;br&gt;
SATA Drives like SSD's or HDD's will always be &lt;code&gt;/dev/sdX&lt;/code&gt; the &lt;code&gt;X&lt;/code&gt; is a letter between A and Z to identify your drive.&lt;br&gt;
So the first SATA drive will always be &lt;code&gt;/dev/sda&lt;/code&gt; and the second might be &lt;code&gt;/dev/sdb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;SATA drives show their partition number by a number right after the label, so partition 1 on &lt;code&gt;/dev/sda&lt;/code&gt; would be &lt;code&gt;/dev/sda1&lt;/code&gt; and so forth.&lt;/p&gt;

&lt;p&gt;NVME Drives or &lt;code&gt;M.2&lt;/code&gt; drives will always be &lt;code&gt;/dev/nvme0nX&lt;/code&gt; where &lt;code&gt;X&lt;/code&gt; is the number that orders these drives. So if you have 2 NVME drives and want the second one that would be &lt;code&gt;/dev/nvme0n2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;NVME drives show their partition number by a &lt;code&gt;p&lt;/code&gt; then a number right after the label, so partition 1 on &lt;code&gt;/dev/nvme0n2&lt;/code&gt; would be &lt;code&gt;/dev/nvme0n2p1&lt;/code&gt; and so forth.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find your drive identifier&lt;/span&gt;
lsblk

&lt;span class="c"&gt;# You can typically tell which drive is the one &lt;/span&gt;
&lt;span class="c"&gt;# you want to install on by the size and whether &lt;/span&gt;
&lt;span class="c"&gt;# it is `nvme` being a M.2 drive or `sdX` being &lt;/span&gt;
&lt;span class="c"&gt;# a SATA drive as explained earlier&lt;/span&gt;

&lt;span class="c"&gt;# Going forward I'll be using `/dev/sda`&lt;/span&gt;

&lt;span class="c"&gt;# Enter the fdisk utility&lt;/span&gt;
fdisk /dev/sda

&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# BEGIN FDISK COMMANDS&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;

&lt;span class="c"&gt;# Create a new GPT label&lt;/span&gt;
Command: g

&lt;span class="c"&gt;# Print the current partition table&lt;/span&gt;
Command: p

&lt;span class="c"&gt;# If any partitions exist just press `d` and Enter until they are all gone.&lt;/span&gt;

&lt;span class="c"&gt;# Create a new EFI boot partition&lt;/span&gt;
Command: n
Number: 1
Primary or Extended: p
First Sector: Enter
Last Sector: +1G

&lt;span class="c"&gt;# Now select the EFI system type&lt;/span&gt;
Command: t
Number: 1
&lt;span class="c"&gt;# Type capital L to see all types, EFI System should&lt;/span&gt;
&lt;span class="c"&gt;# be the first&lt;/span&gt;
Partition Type: 1

&lt;span class="c"&gt;# Create a new swap partition&lt;/span&gt;
Command: n
Number: 2
Primary or Extended: p
First Sector: Enter
Last Sector: +4G

&lt;span class="c"&gt;# Now use the Linux swap type&lt;/span&gt;
Command: t
Number: 2
&lt;span class="c"&gt;# Type capital L to see all types, Linux swap should&lt;/span&gt;
&lt;span class="c"&gt;# be number 19&lt;/span&gt;
Partition Type: 19

&lt;span class="c"&gt;# Create the root partition&lt;/span&gt;
Command: n
Number: 3
Primary or Extended: p
First Sector: Enter
Last Sector: Enter

&lt;span class="c"&gt;# Use Linux root x86-64 type&lt;/span&gt;
Command: t
Number: 3
&lt;span class="c"&gt;# Type capital L to see all types, Linux root x86-64 &lt;/span&gt;
&lt;span class="c"&gt;# should be number 23&lt;/span&gt;
Partition Type: 23

&lt;span class="c"&gt;# Now save changes and quit&lt;/span&gt;
Command: w

&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# END FDISK COMMANDS&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now running &lt;code&gt;fdisk -l&lt;/code&gt; should show the following&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6i2f8rexjb4mxr2b733.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6i2f8rexjb4mxr2b733.png" alt="fdisk output" width="555" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally we need to format these partitions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Format the root partition&lt;/span&gt;
mkfs.ext4 /dev/sda3

&lt;span class="c"&gt;# Format the swap partition&lt;/span&gt;
mkswap /dev/sda2

&lt;span class="c"&gt;# Format the EFI partition&lt;/span&gt;
mkfs.fat &lt;span class="nt"&gt;-F&lt;/span&gt; 32 /dev/sda1

&lt;span class="c"&gt;# Now mount the drives&lt;/span&gt;
&lt;span class="c"&gt;# Mount the root partition&lt;/span&gt;
mount /dev/sda3 /mnt

&lt;span class="c"&gt;# Mount the EFI partition to boot&lt;/span&gt;
mount &lt;span class="nt"&gt;--mkdir&lt;/span&gt; /dev/sda1 /mnt/boot

&lt;span class="c"&gt;# Turn on swap for the swap partition&lt;/span&gt;
swapon /dev/sda2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congrats you are now half way through!&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing to the Drive
&lt;/h2&gt;

&lt;p&gt;First we need the closest servers for the package manager so we have the best speeds.&lt;/p&gt;

&lt;p&gt;Quick heads up for Vim usage, press &lt;code&gt;i&lt;/code&gt; to enter insert mode, &lt;code&gt;ESC&lt;/code&gt; to exit insert mode, and &lt;code&gt;:wq&lt;/code&gt; to "Write" and "Quit".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace AU with your country identifier&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://archlinux.org/mirrorlist/?country=AU&amp;amp;protocol=https&amp;amp;use_mirror_status=on"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/pacman.d/mirrorlist

&lt;span class="c"&gt;# Edit the mirrorlist file and un-comment the lines # with Server, see the example below&lt;/span&gt;
vim /etc/pacman.d/mirrorlist

&lt;span class="c"&gt;# Exit vim with :wq when your done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an example change this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Australia
#Server = https://syd.mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
#Server = https://sydney.mirror.pkgbuild.com/$repo/os/$arch
## Australia
#Server = https://au.mirrors.cicku.me/archlinux/$repo/os/$arch
## Australia
#Server = https://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
## Australia
#Server = https://archlinux.mirror.digitalpacific.com.au/$repo/os/$arch
## Australia
#Server = https://gsl-syd.mm.fcix.net/archlinux/$repo/os/$arc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Australia
Server = https://syd.mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
Server = https://sydney.mirror.pkgbuild.com/$repo/os/$arch
## Australia
Server = https://au.mirrors.cicku.me/archlinux/$repo/os/$arch
## Australia
Server = https://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
## Australia
Server = https://archlinux.mirror.digitalpacific.com.au/$repo/os/$arch
## Australia
Server = https://gsl-syd.mm.fcix.net/archlinux/$repo/os/$arc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our mirrors are setup lets install all the core packages into the new system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install linux kernel and firmware&lt;/span&gt;
pacstrap &lt;span class="nt"&gt;-K&lt;/span&gt; /mnt base linux linux-firmware &lt;span class="nb"&gt;sudo &lt;/span&gt;vim dhcpcd networkmanager

&lt;span class="c"&gt;# Generate fstab from system config to new system&lt;/span&gt;
genfstab &lt;span class="nt"&gt;-U&lt;/span&gt; /mnt &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Steps
&lt;/h2&gt;

&lt;p&gt;Now we are ready to switch into the new install via &lt;code&gt;arch-chroot&lt;/code&gt; and set the final things up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Chroot into the new system&lt;/span&gt;
arch-chroot /mnt

&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# BEGIN CHROOT COMMANDS&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;

&lt;span class="c"&gt;# Copy timezone info, replace Country and City&lt;/span&gt;
&lt;span class="c"&gt;# just like before&lt;/span&gt;
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-sf&lt;/span&gt; /usr/share/zoneinfo/Country/City /etc/localtime

&lt;span class="c"&gt;# Sync clock&lt;/span&gt;
hwclock &lt;span class="nt"&gt;--systohc&lt;/span&gt;

&lt;span class="c"&gt;# Generate locals&lt;/span&gt;
locale-gen

&lt;span class="c"&gt;# Set your system hostname, this will be your &lt;/span&gt;
&lt;span class="c"&gt;# systems name on the network and show in the terminal&lt;/span&gt;
&lt;span class="c"&gt;# like `user@hostname`&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$HOSTNAME&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/hostname

&lt;span class="c"&gt;# Generate initramfs image&lt;/span&gt;
mkinitcpio &lt;span class="nt"&gt;-P&lt;/span&gt;

&lt;span class="c"&gt;# Set root user password&lt;/span&gt;
passwd

&lt;span class="c"&gt;# Install packages for bootloader and networking in &lt;/span&gt;
&lt;span class="c"&gt;# the new system&lt;/span&gt;
pacman &lt;span class="nt"&gt;-S&lt;/span&gt; grub efibootmgr

&lt;span class="c"&gt;# Mount the EFI partition&lt;/span&gt;
mount /dev/sda1 /boot

&lt;span class="c"&gt;# Install grub&lt;/span&gt;
grub-install &lt;span class="nt"&gt;--target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x86_64-efi &lt;span class="nt"&gt;--efi-directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/boot &lt;span class="nt"&gt;--bootloader-id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;grub-boot

&lt;span class="c"&gt;# Intialize bootloader configuration&lt;/span&gt;
grub-mkconfig &lt;span class="nt"&gt;-o&lt;/span&gt; /boot/grub/grub.cfg

&lt;span class="c"&gt;# All done, exit the chroot&lt;/span&gt;
&lt;span class="nb"&gt;exit&lt;/span&gt;

&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# END CHROOT COMMANDS&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it! Now just run the following before rebooting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Umount drives&lt;/span&gt;
umount &lt;span class="nt"&gt;-R&lt;/span&gt; /mnt

&lt;span class="c"&gt;# Reboot!&lt;/span&gt;
reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When your screen turns off you can unplug the USB and hold the boot menu key, then select Arch.&lt;/p&gt;

&lt;p&gt;Once in you will be prompted with a login screen, enter &lt;code&gt;root&lt;/code&gt; for the user and whatever the password is you set earlier.&lt;/p&gt;

&lt;p&gt;Congrats you are now in your new Arch Linux system!&lt;/p&gt;

&lt;h2&gt;
  
  
  Post Install Notes
&lt;/h2&gt;

&lt;p&gt;Now if I covered everything for the post install this guide would be go on forever so I'll just cover the important things.&lt;/p&gt;

&lt;p&gt;Now that your logged in as root run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl start dhcpcd.service

&lt;span class="c"&gt;# IF ETHERNET&lt;/span&gt;
&lt;span class="c"&gt;# Get the name of your adapter, example: enp0s3&lt;/span&gt;
ip &lt;span class="nb"&gt;link&lt;/span&gt;

&lt;span class="c"&gt;# Start it and the dhcpcd service&lt;/span&gt;
ip &lt;span class="nb"&gt;link set &lt;/span&gt;enp0s3 up
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;dhcpcd@enp0s3.service

&lt;span class="c"&gt;# IF WIFI&lt;/span&gt;
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;NetworkManager
systemctl start NetworkManager
&lt;span class="c"&gt;# In the TUI do Activate a connection&lt;/span&gt;
nmtui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last thing we need to do is create a user and give it privileges.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create user with wheel group and bash shell&lt;/span&gt;
&lt;span class="c"&gt;# Replace $USERNAME with yours&lt;/span&gt;
useradd &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="nt"&gt;-G&lt;/span&gt; wheel &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash &lt;span class="nv"&gt;$USERNAME&lt;/span&gt;

&lt;span class="c"&gt;# Set the password for the user.&lt;/span&gt;
passwd &lt;span class="nv"&gt;$USERNAME&lt;/span&gt;

&lt;span class="c"&gt;# Edit the sudoers file so the user has perms&lt;/span&gt;
&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;vim visudo

&lt;span class="c"&gt;# Add the following to a new line&lt;/span&gt;
%wheel &lt;span class="nv"&gt;ALL&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;ALL:ALL&lt;span class="o"&gt;)&lt;/span&gt; ALL

&lt;span class="c"&gt;# Exit and save with&lt;/span&gt;
:wq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can &lt;code&gt;exit&lt;/code&gt; and login to your new user with &lt;code&gt;sudo&lt;/code&gt; permissions! Start installing some packages with &lt;code&gt;sudo pacman -S&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed and benefited from this guide, again huge shoutout to my man SolomonTech.&lt;br&gt;
If you liked this post please leave a like and maybe even a comment, I love responding to them all!&lt;/p&gt;

&lt;p&gt;Until next time, bye!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>archlinux</category>
    </item>
    <item>
      <title>Self Hosting Supabase with Docker - Guide</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Tue, 09 Jul 2024 05:15:12 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/self-hosting-supabase-with-docker-guide-5ela</link>
      <guid>https://dev.to/jasper-clarke/self-hosting-supabase-with-docker-guide-5ela</guid>
      <description>&lt;h1&gt;
  
  
  Self Hosting Supabase
&lt;/h1&gt;

&lt;p&gt;This is a quick guide for self hosting Supabase, of course.&lt;br&gt;
If I'm being honest the official guide is pretty bad so I'm going to try to make this better.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A knowledge of how to use the terminal&lt;/li&gt;
&lt;li&gt;A server with at least 2GB of RAM&lt;/li&gt;
&lt;li&gt;A knowledge of your server's IP address&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Installing Supabase
&lt;/h2&gt;

&lt;p&gt;I assume you can login to your server via SSH and have &lt;code&gt;docker&lt;/code&gt; and &lt;code&gt;git&lt;/code&gt; installed.&lt;br&gt;
If not check your distribution's documentation for how to install them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Change into your home directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~

&lt;span class="c"&gt;# Clone the supabase repo&lt;/span&gt;
git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 1 https://github.com/supabase/supabase ~/temp-supabase

&lt;span class="c"&gt;# Make your project directory&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/supabase-project

&lt;span class="c"&gt;# Copy over the docker stuff&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/temp-supabase/docker/&lt;span class="k"&gt;*&lt;/span&gt; ~/supabase-project
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/temp-supabase/docker/.env.example ~/supabase-project/.env


&lt;span class="c"&gt;# Change into the supabase directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/supabase-project

&lt;span class="c"&gt;# Download the docker images&lt;/span&gt;
docker compose pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to modify the &lt;code&gt;.env&lt;/code&gt; file to setup JWT secrets and studio credentials.&lt;/p&gt;

&lt;p&gt;Head to &lt;a href="https://jwtsecret.com/generate" rel="noopener noreferrer"&gt;Generate JWT Secrets&lt;/a&gt; and generate a 32 or 64 character secret.&lt;br&gt;
Copy the secret into the &lt;code&gt;JWT_SECRET&lt;/code&gt; field in the &lt;code&gt;~/supabase-project/.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Now go to &lt;a href="https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaXNzIjoic3VwYWJhc2UiLCJpYXQiOjE3MTQ5NzUyMDAsImV4cCI6MTg3Mjc0MTYwMH0.94n1skq8ijf6a1yZU7by1jyH-_Y21MXIpEcmc4m_jW4" rel="noopener noreferrer"&gt;this link&lt;/a&gt; and switch to the decoded tab. Change the token under &lt;code&gt;verify signature&lt;/code&gt; to you JWT token you just generate earlier. Save the output on the left as &lt;code&gt;SERVICE_ROLE_KEY&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Now for the &lt;code&gt;ANON_KEY&lt;/code&gt; go to &lt;a href="https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzE0OTc1MjAwLCJleHAiOjE4NzI3NDE2MDB9.pYtda94wDevZj92OG6a6ILutRu2AgZB9Wwm885sGNjE" rel="noopener noreferrer"&gt;this link&lt;/a&gt; and repeat the step before, replace &lt;code&gt;your-secret-key-HERE&lt;/code&gt; with the JWT key you generated before, and put the generate string for the value &lt;code&gt;ANON_KEY&lt;/code&gt; in the &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Generate 1 more JWT key that is 32 chars for the &lt;code&gt;POSTGRES_PASSWORD&lt;/code&gt; on &lt;a href="https://jwtsecret.com/generate" rel="noopener noreferrer"&gt;Generate JWT Secrets&lt;/a&gt; and put the generated string for the value &lt;code&gt;POSTGRES_PASSWORD&lt;/code&gt; in the &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Last thing before we start the docker containers is to setup a username and password for the studio page.&lt;/p&gt;

&lt;p&gt;Do this by changing &lt;code&gt;DASHBOARD_USERNAME&lt;/code&gt; and &lt;code&gt;DASHBOARD_PASSWORD&lt;/code&gt; in the &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Now we can start the docker containers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start the supabase instance in the background&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/supabase-project
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# Stop the supabase instance&lt;/span&gt;
docker compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can access the studio at &lt;code&gt;http://your-server-ip:3000&lt;/code&gt; and login with the username and password you set in the &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing the Database
&lt;/h2&gt;

&lt;p&gt;If your using a ORM like Prisma or Drizzle you will probably want to access the database directly.&lt;br&gt;
To do these use the following URL:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;
POSTGRES_DB defaults to &lt;code&gt;postgres&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres://postgres:[your-POSTGRES_PASSWORD]@[your-server-ip]:5432/[POSTGRES_DB]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>supabase</category>
      <category>cloud</category>
      <category>selfhosting</category>
    </item>
    <item>
      <title>The Ultimate NixOS Homelab Guide - Flakes, Modules and Fail2Ban w/ Cloudflare</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Tue, 02 Jul 2024 02:17:39 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/the-ultimate-nixos-homelab-guide-flakes-modules-and-fail2ban-w-cloudflare-25ba</link>
      <guid>https://dev.to/jasper-clarke/the-ultimate-nixos-homelab-guide-flakes-modules-and-fail2ban-w-cloudflare-25ba</guid>
      <description>&lt;p&gt;Welcome back everyone to the NixOS homelab guide, today we will be moving all our configurations into a very simple flake, setting up Vaultwarden with Fail2Ban and finally modularizing our configuration ready for future self hosted apps.&lt;/p&gt;

&lt;p&gt;Sorry for the huge wait, I had some issues and personal problems that cropped up but I'm back!&lt;/p&gt;

&lt;h2&gt;
  
  
  Flake Setup
&lt;/h2&gt;

&lt;p&gt;Moving our configuration to a flake is pretty easy so let's get straight to it.&lt;/p&gt;

&lt;p&gt;Make a new directory in your home folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ~/.flake
cd ~/.flake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create a new &lt;code&gt;flake.nix&lt;/code&gt; file at the root of that directory and open it in your text editor of choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim flake.nix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now fill out the file with the following, then I'll explain and break it down.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"A very basic flake"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:nixos/nixpkgs/nixpkgs-unstable"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt;
    &lt;span class="nv"&gt;system&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"x86_64-linux"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"24.11"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"your-username"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"homelab"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;pkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;allowUnfree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nv"&gt;lib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;nixosConfigurations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixosSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;specialArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;hostname&lt;/span&gt; &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="nv"&gt;modules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="sx"&gt;./nix/configuration.nix&lt;/span&gt;
        &lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We initialize a flake, add the unstable nixpkgs source, set some variables we can use through our entire config (make sure to set the hostname and user variables to whatever username and hostname you used in your &lt;code&gt;configuration.nix&lt;/code&gt;, we set that file up in the last post) and then create the nixosSystem inheriting our variables and then importing &lt;code&gt;configuration.nix&lt;/code&gt; which we will move into our flake directory right now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/.flake/nix
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /etc/nixos/&lt;span class="k"&gt;*&lt;/span&gt; ~/.flake/nix
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt;:users ~/.flake/nix/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;a+rw ~/.flake/nix/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those commands will copy our existing configurations to our new flake directory and then make sure our user have all the write permissions.&lt;/p&gt;

&lt;p&gt;You should now have this directory structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.flake
├── flake.nix
└── nix
    ├── configuration.nix
    └── hardware-configuration.nix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to update our &lt;code&gt;configuration.nix&lt;/code&gt; to work with our flake and also add some utilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;imports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="c"&gt;# Include the results of the hardware scan.&lt;/span&gt;
      &lt;span class="sx"&gt;./hardware-configuration.nix&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="nv"&gt;boot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;kernelPackages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;linuxPackages_latest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;efi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;canTouchEfiVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;grub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;efiSupport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nodev"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;nix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# Enable flakes!&lt;/span&gt;
    &lt;span class="nv"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;experimental-features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"nix-command"&lt;/span&gt; &lt;span class="s2"&gt;"flakes"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="nv"&gt;auto-optimise-store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;allowUnfree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;networking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;hostName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;networkmanager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c"&gt;# Your timezone&lt;/span&gt;
  &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;timeZone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Australia/Sydney"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;isNormalUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;extraGroups&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"wheel"&lt;/span&gt; &lt;span class="s2"&gt;"docker"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c"&gt;# Enable ‘sudo’ for the user with wheel.&lt;/span&gt;
    &lt;span class="nv"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;shell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;zsh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;programs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# Personal preference&lt;/span&gt;
    &lt;span class="nv"&gt;zsh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;nh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.flake"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;systemPackages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nv"&gt;vim&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c"&gt;# Enable the OpenSSH daemon.&lt;/span&gt;
  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;openssh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;stateVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our config will make use of the &lt;code&gt;user&lt;/code&gt;, &lt;code&gt;hostname&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt; variables we created in our &lt;code&gt;flake.nix&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we are finally ready to apply our new config, run the below command. (replace &lt;code&gt;homelab&lt;/code&gt; with whatever the &lt;code&gt;hostname&lt;/code&gt; variable is in your &lt;code&gt;flake.nix&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nixos-rebuild boot &lt;span class="nt"&gt;--flake&lt;/span&gt; /home/&lt;span class="nv"&gt;$USER&lt;/span&gt;/.flake#homelab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any errors come up please leave a comment below and I'll be happy to help troubleshoot.&lt;br&gt;
If the command completes and there were no issues then you can just run &lt;code&gt;sudo reboot&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Fail2Ban and Modularization
&lt;/h2&gt;

&lt;p&gt;In this example I am setting up Fail2Ban for a local Vaultwarden server, you will need to adapt this based on the Fail2Ban instructions for your software.&lt;/p&gt;

&lt;p&gt;Let's start and creating a folder at &lt;code&gt;~/.flake/nix/modules&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ~/.flake/nix/modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In there let's open up a new file and you can name it either &lt;code&gt;fail2ban.nix&lt;/code&gt; or &lt;code&gt;vaultwarden.nix&lt;/code&gt; if that is the service you are protecting. (name doesn't matter that much its just semantics).&lt;/p&gt;

&lt;p&gt;In that file start with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;fail2ban&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Throughout this I'll be referring to these pages:&lt;br&gt;
&lt;a href="https://nixos.wiki/wiki/Fail2ban" rel="noopener noreferrer"&gt;https://nixos.wiki/wiki/Fail2ban&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/dani-garcia/vaultwarden/wiki/Fail2Ban-Setup" rel="noopener noreferrer"&gt;https://github.com/dani-garcia/vaultwarden/wiki/Fail2Ban-Setup&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/fail2ban/fail2ban/blob/master/config/action.d/cloudflare.conf" rel="noopener noreferrer"&gt;https://github.com/fail2ban/fail2ban/blob/master/config/action.d/cloudflare.conf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I assume if your setting up Fail2Ban you understand how it works and what it is, so you may be asking, alright so how can I create stuff like Jails and custom actions and filters.&lt;/p&gt;

&lt;p&gt;Well Nix has you covered. Let's take a look at my Jail configuration for Vaultwarden.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;fail2ban&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;jails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;vaultwarden&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vaultwarden"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;          cf&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;          iptables-allports&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;        ''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c"&gt;# This is the path where I have my vaultwarden data&lt;/span&gt;
        &lt;span class="nv"&gt;logpath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/vaultwarden/vw-data/vaultwarden.log"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c"&gt;# User gets banned after 4 incorrect attempts&lt;/span&gt;
        &lt;span class="nv"&gt;maxretry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;bantime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"52w"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;findtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"52w"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"FORWARD"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Ok awesome but what is the &lt;code&gt;cf&lt;/code&gt; action and what about the vaultwarden filter, how do i set that up on NixOS when /etc is read-only?"&lt;/p&gt;

&lt;p&gt;Fear not because here is &lt;code&gt;environment.etc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;etc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"fail2ban/filter.d/vaultwarden.local"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkDefault&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkAfter&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      [INCLUDES]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      before = common.conf&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;      [Definition]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      failregex = ^.*Username or password is incorrect\. Try again\. IP: &amp;lt;ADDR&amp;gt;\. Username:.*$&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      ignoreregex =&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;    ''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;fail2ban&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# ...&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may recognise that string for the first child of &lt;code&gt;etc&lt;/code&gt; it is the fail2ban path for custom filters!&lt;/p&gt;

&lt;p&gt;Now let's add the &lt;code&gt;cf&lt;/code&gt; action which is for banning through Cloudflare. You only need this if you have made your Vaultwarden instance public via Cloudflare/-Tunnels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;  &lt;span class="nv"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;etc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"fail2ban/action.d/cf.conf"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkDefault&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mkAfter&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      [Definition]&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;      actionstart =&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      actionstop =&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      actioncheck =&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;      actionban = /run/current-system/sw/bin/curl -s -o /dev/null -X POST \&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            -H "X-Auth-Email: &amp;lt;cfuser&amp;gt;" \&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            -H "X-Auth-Key: &amp;lt;cftoken&amp;gt;" \&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            -H "Content-Type: application/json" \&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            -d '{"mode":"block","configuration":{"target":"ip","value":"&amp;lt;ip&amp;gt;"},"notes":"Fail2Ban &amp;lt;name&amp;gt;"}' \&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules"&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;      actionunban = /run/current-system/sw/bin/curl -s -o /dev/null -X DELETE -H 'X-Auth-Email: &amp;lt;cfuser&amp;gt;' -H 'X-Auth-Key: &amp;lt;cftoken&amp;gt;' \&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$(/run/current-system/sw/bin/curl -s -X GET -H 'X-Auth-Email: &amp;lt;cfuser&amp;gt;' -H 'X-Auth-Key: &amp;lt;cftoken&amp;gt;' \&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;            'https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&amp;amp;configuration_target=ip&amp;amp;configuration_value=&amp;amp;page=1&amp;amp;per_page=1' | tr -d '\n' | cut -d'"' -f6)&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;      [Init]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;      cftoken = your-token&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;      cfuser = jasper-at-windswept@example.com&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s2"&gt;    ''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again you can see that the initial string just references the path as a child of &lt;code&gt;/etc&lt;/code&gt;. It should be pretty conclusive from there how to add your own  actions and filters.&lt;br&gt;
And if ever in doubt, check the NixOS Wiki and search.nixos.org for options relating to fail2ban.&lt;/p&gt;

&lt;p&gt;As a side note, getting this to work took me literal days so yeah, haha.&lt;/p&gt;

&lt;p&gt;Now to get this to work in our config add the following to your &lt;code&gt;configuration.nix&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ config, lib, pkgs, user, hostname, version, ... }:

{
  imports = [
    ./hardware-configuration.nix
    ./modules/vaultwarden.nix
  ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now since we moved to a flake and I snuck &lt;code&gt;nh&lt;/code&gt; into your configuration you can run the super simple command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nh os switch&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will rebuild your system and switch over to it automatically based on the flake path we provided earlier, &lt;code&gt;~/.flake&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Securing your Server
&lt;/h2&gt;

&lt;p&gt;Well this is a pretty big post now isn't it.&lt;br&gt;
The best way I secure my server is by disabling SSH via password and only allowing my personal private key.&lt;/p&gt;

&lt;p&gt;This can be done as follows:&lt;/p&gt;

&lt;p&gt;On your personal computer (the one with your private key)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssh-copy-id -i ~/.ssh/private_key.pub admin@your.homelab.ip.address&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should also change your &lt;code&gt;~/.ssh/config&lt;/code&gt; on your  PC to use that private key when connecting to your homeserver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host your.homelab.ip.address
  IdentityFile ~/.ssh/private
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;KEEP A LOGGED IN TERMINAL TO YOUR SERVER OPEN BEFORE REBUILDING WITH PASSWORDS DISABLED AS IF ANYTHING GOES WRONG YOU WILL BE LOCKED OUT!!!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On your homeserver open up &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; and copy the newly created string.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;configuration.nix&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# ...&lt;/span&gt;
    &lt;span class="nv"&gt;openssh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;authorizedKeys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="c"&gt;# Paste your key into double quotes here&lt;/span&gt;
      &lt;span class="c"&gt;# Example:&lt;/span&gt;
      &lt;span class="s2"&gt;"ssh-ed25519 AAAA------------ jasper@nixos"&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;services&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;openssh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;PasswordAuthentication&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then rebuild, this time though we will use the &lt;code&gt;boot&lt;/code&gt; option and restart the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nh os boot
reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now on your personal computer, open a new terminal and try to connect to the server via SSH. If you connect with the password being requested then hurray, you have just secured your server!&lt;/p&gt;

&lt;p&gt;If you have any troubles please leave a comment or contact me on Discord (&lt;code&gt;jasper-at-windswept&lt;/code&gt;) and I will try to help out!&lt;/p&gt;

&lt;p&gt;That is all for this post, make sure to follow and like the post if you found it helpful and I will see you all in the next one.&lt;/p&gt;

</description>
      <category>nixos</category>
      <category>linux</category>
      <category>homeserver</category>
    </item>
    <item>
      <title>The Ultimate NixOS Homelab Guide - The Install</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Fri, 03 May 2024 07:19:01 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/the-ultimate-nixos-homelab-guide-the-install-53k7</link>
      <guid>https://dev.to/jasper-clarke/the-ultimate-nixos-homelab-guide-the-install-53k7</guid>
      <description>&lt;p&gt;Finally after 2 weeks here we are. A full, in-depth, step-by-step, ultimate guide to NixOS for homeservers!&lt;/p&gt;

&lt;p&gt;This first post wont be too long but will cover the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installing NixOS&lt;/li&gt;
&lt;li&gt;Starting a Basic Config&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Well without further a due, lets get this series rolling!&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Just about all of the following is straight from the &lt;a href="https://nixos.org/manual/nixos/unstable/#sec-installation" rel="noopener noreferrer"&gt;NixOS Manual&lt;/a&gt; so if you need any extra help you can check there or ask a comment below this post and I'll try to help out!&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting a NixOS flash drive
&lt;/h3&gt;

&lt;p&gt;Ok so let's download the ISO and flash it to a spare 8-16GB USB.&lt;br&gt;
First download the nixos-unstable ISO from &lt;a href="https://channels.nixos.org/nixos-unstable/latest-nixos-minimal-x86_64-linux.iso" rel="noopener noreferrer"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next for Linux users just do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check &lt;code&gt;lsblk&lt;/code&gt; for your USB flash drive, for example mine will be &lt;code&gt;/dev/sdb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Still in the terminal navigate to the folder where the ISO is and run:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo dd &lt;/span&gt;&lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nixos-unstable.iso &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdb &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress &lt;span class="nv"&gt;oflag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;sync&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Make sure to change &lt;code&gt;nixos-unstable.iso&lt;/code&gt; to the file name of the ISO you just downloaded and change &lt;code&gt;/dev/sdb&lt;/code&gt; to your flash drives identifier.&lt;/p&gt;

&lt;p&gt;For Windows user:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get &lt;a href="https://github.com/pbatard/rufus/releases/latest" rel="noopener noreferrer"&gt;Rufus&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install Rufus, select the ISO and your flash drive and click Start, then run in ISO mode. You don't need to change any other settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ok so now that we have our boot-able flash drive let's plug it into our server and turn it on.&lt;br&gt;
I'm sure for anyone reading this you do know how to do stuff like entering BIOS and booting a flash drive but for those who are not familiar just hold DEL or F12 on your keyboard whilst your server is turning on to bring up the boot menu, this key can be different depending on your motherboard so if your having trouble lookup its brand to find the key to open the "Boot Menu".&lt;/p&gt;

&lt;p&gt;From there select your flash drive, then when the NixOS installer boots just press enter on the first option. &lt;/p&gt;
&lt;h3&gt;
  
  
  Setup and Partitioning
&lt;/h3&gt;

&lt;p&gt;Since we are not using the graphical installer we will have to do this all in the terminal. As a quick note you need to have a monitor and keyboard connected to your server for the first part of the installation, afterwords you can simply connect via SSH.&lt;/p&gt;

&lt;p&gt;I won't be explaining the next few steps in detail as otherwise this post's retention rate will cease to exist but if your interested what everything is doing check the &lt;a href="https://nixos.org/manual/nixos/unstable/#sec-installation-manual" rel="noopener noreferrer"&gt;NixOS Manual&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First thing do &lt;code&gt;sudo -i&lt;/code&gt; to enter root, this way you won't have to prefix every command with sudo.&lt;/p&gt;

&lt;p&gt;If you have a Ethernet cable for your server make sure it is plugged in otherwise lets setup the Wifi as you will need internet in the installer.&lt;/p&gt;
&lt;h4&gt;
  
  
  Networking
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;systemctl start wpa_supplicant&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;add_network&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set_network 0 ssid "myhomenetwork"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set_network 0 psk "mypassword"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set_network 0 key_mgmt WPA-PSK&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;enable_network 0&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all went well you should see something along the lines of below showing that the connection was successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;3&amp;gt;CTRL-EVENT-CONNECTED - Connection to 32:85:ab:ef:24:5c completed &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;id_str&lt;/span&gt;&lt;span class="o"&gt;=]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Partitioning
&lt;/h4&gt;

&lt;p&gt;For the following commands if you have a M.2 SSD for your main drive you will use &lt;code&gt;/dev/nvme0n1&lt;/code&gt; instead of &lt;code&gt;/dev/sda&lt;/code&gt;, if you have multiple M.2 SSDs you should check &lt;code&gt;lsblk&lt;/code&gt; to find the one you want to use.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;parted /dev/sda -- mklabel gpt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parted /dev/sda -- mkpart root ext4 512MB -8GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parted /dev/sda -- mkpart swap linux-swap -8GB 100%&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parted /dev/sda -- mkpart ESP fat32 1MB 512MB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parted /dev/sda -- set 3 esp on&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let's format these partitions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;mkfs.ext4 -L nixos /dev/sda1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkswap -L swap /dev/sda2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkfs.fat -F 32 -n boot /dev/sda3&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And now finish it off by mounting the correct volumes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;mount /dev/disk/by-label/nixos /mnt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkdir -p /mnt/boot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mount /dev/disk/by-label/boot /mnt/boot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swapon /dev/sda2&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;Now that all our partitions are setup let's do our initial base configuration.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;nixos-generate-config --root /mnt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nano /mnt/etc/nixos/configuration.nix&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Want to use Vim? Just do the following to install vim on the live installer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nix-env -f '&amp;lt;nixpkgs&amp;gt;' -iA vim&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we have our base canvas of our configuration ready to be painted upon let's start with some basics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;imports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="c"&gt;# Include the results of the hardware scan.&lt;/span&gt;
      &lt;span class="sx"&gt;./hardware-configuration.nix&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="nv"&gt;boot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# Use the latest linux kernel&lt;/span&gt;
    &lt;span class="nv"&gt;kernelPackages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;linuxPackages_latest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;# Grub bootloader stuff, no need to change this.&lt;/span&gt;
    &lt;span class="nv"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;efi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;canTouchEfiVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;grub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;efiSupport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nodev"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c"&gt;# Allows us to use closed source packages.&lt;/span&gt;
  &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;allowUnfree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;networking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# What should your server be on the network?&lt;/span&gt;
    &lt;span class="nv"&gt;hostName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"homelab"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;# Use network manager, makes life easier&lt;/span&gt;
    &lt;span class="nv"&gt;networkmanager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c"&gt;# Your timezone here&lt;/span&gt;
  &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;timeZone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Australia/Sydney"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;# Change `admin` to whatever username you want.&lt;/span&gt;
  &lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# This makes sure the user isn't root.&lt;/span&gt;
    &lt;span class="nv"&gt;isNormalUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;extraGroups&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"wheel"&lt;/span&gt; &lt;span class="s2"&gt;"docker"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c"&gt;# Enable ‘sudo’ and the use of docker for the user.&lt;/span&gt;
    &lt;span class="c"&gt;# Set the home directory, also change this to `/home/your-username`&lt;/span&gt;
    &lt;span class="nv"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/admin"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;# Use Zsh&lt;/span&gt;
    &lt;span class="nv"&gt;shell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;zsh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c"&gt;# Enable Zsh, this is just personal preference&lt;/span&gt;
  &lt;span class="nv"&gt;programs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;zsh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;systemPackages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nv"&gt;vim&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c"&gt;# Enable the OpenSSH daemon, for SSH...&lt;/span&gt;
  &lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;openssh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;# Backup the system configuration when changed&lt;/span&gt;
  &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;copySystemConfiguration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;# The current unstable version of NixOS&lt;/span&gt;
  &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;stateVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"24.05"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the minimum of what you need to get started on NixOS. We won't add anything more to this now as it would just take ages longer to install and we want to get in ASAP!&lt;/p&gt;

&lt;p&gt;So once your happy with the configuration just run the following commmand.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nixos-install&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a while it will prompt you to set the root password and then voila, you just installed NixOS!&lt;/p&gt;

&lt;p&gt;Now just &lt;code&gt;reboot&lt;/code&gt; and hop into your new system, don't unplug your keyboard and monitor just yet though, we have a couple more things to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Post-Install
&lt;/h3&gt;

&lt;p&gt;Now launched into NixOS login to the root user account since the user you created doesn't have a password yet.&lt;br&gt;
Once logged into root type &lt;code&gt;passwd your-username&lt;/code&gt; to set the user password.&lt;br&gt;
Then &lt;code&gt;exit&lt;/code&gt; and login to the user account.&lt;/p&gt;

&lt;p&gt;For Wifi users you are not done quite yet, follow these steps to login to your network in nmtui.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;sudo nmtui&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Activate a connection&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select your network name and enter the password.&lt;/li&gt;
&lt;li&gt;Once connected hit escape a few times and your done!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Congratulations! You have just setup NixOS for your homeserver, in the next post I'll be setting up Nextcloud and organizing our configuration to use modules so stay tuned for the next installment coming next week (hopefully)!&lt;/p&gt;

&lt;p&gt;And if you have any suggestions for popular self hosted software you want to see setup on NixOS leave a comment and it might just make it into the series.&lt;/p&gt;

&lt;p&gt;Thanks everyone and I'll see you all again soon!&lt;/p&gt;

</description>
      <category>nixos</category>
      <category>linux</category>
      <category>homeserver</category>
    </item>
    <item>
      <title>I use NixOS for my home-server, and you should too!</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Mon, 22 Apr 2024 00:37:36 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/i-use-nixos-for-my-home-server-and-you-should-too-1n7p</link>
      <guid>https://dev.to/jasper-clarke/i-use-nixos-for-my-home-server-and-you-should-too-1n7p</guid>
      <description>&lt;p&gt;As we covered in my &lt;a href="https://dev.to/jasper-at-windswept/this-distro-finally-fixes-linux-1ac9"&gt;last post&lt;/a&gt;, &lt;a href="https://nixos.org" rel="noopener noreferrer"&gt;NixOS&lt;/a&gt; is a amazing Linux distribution for creating stable and declared environments. Now while this is amazing for a desktop setup, it is also perfect for a home-server or home-lab. &lt;/p&gt;

&lt;p&gt;Let's take a look at a few ways NixOS makes setting up a home-server so much smoother!&lt;/p&gt;

&lt;h2&gt;
  
  
  Self Hosting Services
&lt;/h2&gt;

&lt;p&gt;NixOS has gained many integrations from a wide variety of services over the years but here are a few you will probably be interested in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Jellyfin
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zjorb1sehsa47va842q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zjorb1sehsa47va842q.png" alt="Jellyfin Banner" width="512" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Out of the box NixOS provides options to easily setup a Jellyfin instance on your computer, just add the following to your &lt;code&gt;configuration.nix&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;jellyfin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;dataDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/your-user/jellyfin/data"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"your-user"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is that easy to spin up a fresh instance of Jellyfin and there are even more options all found on &lt;a href="https://search.nixos.org/options?channel=unstable&amp;amp;from=0&amp;amp;size=50&amp;amp;sort=relevance&amp;amp;type=packages&amp;amp;query=jellyfin" rel="noopener noreferrer"&gt;search.nixos.org&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vaultwarden
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi63vwc98qlennztsa2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi63vwc98qlennztsa2i.png" alt="Vaulwarden banner" width="568" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Never before has it been this easy to setup Vaultwarden, a fork of the Bitwarden server with all the features of a paid Bitwarden account!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;vaultwarden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;dbBackend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"postgresql"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;# Store your variables like admin password here&lt;/span&gt;
  &lt;span class="nv"&gt;environmentFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/your-user/vaultwarden/.env"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;SIGNUPS_ALLOWED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;DOMAIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://vaultwarden.example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are even more options than these though so again make sure to checkout &lt;a href="https://search.nixos.org/options?channel=unstable&amp;amp;from=0&amp;amp;size=50&amp;amp;sort=relevance&amp;amp;type=packages&amp;amp;query=vaultwarden" rel="noopener noreferrer"&gt;search.nixos.org&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Nextcloud
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnn0n2x9p7hka3g9mimfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnn0n2x9p7hka3g9mimfz.png" alt="Nextcloud Banner" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we are the big boy himself, Nextcloud.&lt;br&gt;
Of course like all the other popular self hosted services Nextcloud has a large variety of options to get your services up and running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;services&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nextcloud&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/your-user/nextcloud"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;https&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nextcloud.example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;trusted_domains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s2"&gt;"talk.nextcloud.example.com"&lt;/span&gt;
      &lt;span class="s2"&gt;"files.nextcloud.example.com"&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for the final time those are just a fraction of the available options to configure Nextcloud through NixOS, so if you need to configure anything else make sure to check out &lt;a href="https://search.nixos.org/options?channel=unstable&amp;amp;from=0&amp;amp;size=50&amp;amp;sort=relevance&amp;amp;type=packages&amp;amp;query=services.nextcloud" rel="noopener noreferrer"&gt;search.nixos.org/nextcloud&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So have I convinced you yet? NixOS really is the easiest way to manage all of your software on your desktop and home-server!&lt;/p&gt;

&lt;p&gt;But what about Docker, there are some things that NixOS hasn't packaged yet so how do I use those or any of my other docker services?&lt;br&gt;
Well do not worry, NixOS again makes it super simple to setup docker and even setup Nvidia Toolkit support for containers that want GPU utilization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;virtualisation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;docker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;# This option is deprecated and will be replaced &lt;/span&gt;
  &lt;span class="c"&gt;# soon but the new option doesn't seem to work &lt;/span&gt;
  &lt;span class="c"&gt;# properly yet so you can just use this.&lt;/span&gt;
  &lt;span class="nv"&gt;enableNvidia&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;your-user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;# ...&lt;/span&gt;
  &lt;span class="nv"&gt;extraGroups&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"docker"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="c"&gt;# ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like that your ready for anything docker to come, and for those who need to configure docker a bit more, maybe put it in rootless mode, can check out the options on &lt;a href="https://search.nixos.org/options?channel=unstable&amp;amp;from=0&amp;amp;size=50&amp;amp;sort=relevance&amp;amp;type=packages&amp;amp;query=virtualisation.docker" rel="noopener noreferrer"&gt;search.nixos.org&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Well that was easy wasn't it, just a few lines of code and a rebuild later and you could have all of these services up and at it! &lt;br&gt;
This is all well but how do you actually get NixOS and set everything up in the first place?&lt;/p&gt;

&lt;p&gt;That is exactly what I'm going to help you do, two weeks from now I'll be getting a new home-server and in a new post, or maybe series of posts, I'll go over everything I do to setup NixOS on my system, so make sure to follow me to stay tuned for those!&lt;/p&gt;

&lt;p&gt;Another little promotion but if you are interested in NixOS, your just getting started or even if you are more experienced user, I have a documentation site where I publicly write about tons of issues I come across on my journey through NixOS and exactly how I fixed them.&lt;/p&gt;

&lt;p&gt;As well I have a ton of resources linked for learning how to get started with NixOS so make sure to check it out at &lt;a href="https://jasperclarke.com/blog" rel="noopener noreferrer"&gt;jasperclarke.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nixos</category>
      <category>linux</category>
      <category>homeserver</category>
      <category>homelab</category>
    </item>
    <item>
      <title>This distro finally fixes Linux</title>
      <dc:creator>Jasper</dc:creator>
      <pubDate>Thu, 18 Apr 2024 00:18:03 +0000</pubDate>
      <link>https://dev.to/jasper-clarke/this-distro-finally-fixes-linux-1ac9</link>
      <guid>https://dev.to/jasper-clarke/this-distro-finally-fixes-linux-1ac9</guid>
      <description>&lt;p&gt;Probably one of the biggest roadblocks for people who want to use Linux is its complexity. And those people are not wrong Linux is quite complex compared to your typical macOS or Windows(eww). &lt;/p&gt;

&lt;p&gt;Unless your using Ubuntu then you will most likely find Linux can be quite unstable, just one system update and whoops my Arch setup isn't booting the graphical environment anymore!&lt;/p&gt;

&lt;p&gt;That was me during my first two years of Linux, constant issues, every update was like poking a sleeping bear to see if it would wake up, sometimes it did..&lt;/p&gt;

&lt;p&gt;But now that the preamble is covered let's talk about what you really came here for. A Linux distro that fixes everything we have covered so far. No more worrying about your system breaking when you update, no more needing to write massive bash scripts to recreate your system if you ever need to install again, no need to write documentation for your own system just so you can remember how you fixed all those issues!&lt;/p&gt;

&lt;p&gt;I present to you all, NixOS. A fully declarative distribution, where all packages can be individually controlled and version locked to get exactly what your system needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo3fziiry1yppawewrn0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo3fziiry1yppawewrn0.png" alt="NixOS Banner" width="545" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is NixOS?
&lt;/h2&gt;

&lt;p&gt;Ok well lets break that down, "what do you mean it's declarative?". Well most Linux systems are 'imperative', you have to do many things in succession to accomplish your system which results in those long bash setup scripts we all have seen at least once. &lt;/p&gt;

&lt;p&gt;Whereas a 'declarative' system means just about everything in the system is controlled by a few configuration files, "Oh but Jasper that is literally every system, its called dot-files", well yes and no. &lt;/p&gt;

&lt;p&gt;Dot-files on most system are your window manager, terminal and other configs but on NixOS you actually combine every single modification to your system in a small set of files or even all of them in one single file!&lt;/p&gt;

&lt;h2&gt;
  
  
  How NixOS works
&lt;/h2&gt;

&lt;p&gt;Here is a quick example, on most systems to setup your timezone you would have to either run a command or change a system file, just take a look at the &lt;a href="https://wiki.archlinux.org/title/System_time#Time_zone" rel="noopener noreferrer"&gt;Arch Wiki&lt;/a&gt; on changing the time. But as you can see below on NixOS its controlled by a single line in your sole system configuration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;timeZone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Australia/Sydney"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is just one example, with NixOS all you need is a single &lt;code&gt;.nix&lt;/code&gt; file and your can do just about anything you could do with a few hundred commands on another distro.&lt;/p&gt;

&lt;p&gt;And let's say you have made this massive config, well now you can run that config on ANY other system and it will be created the exact same it was on the original system thanks to NixOS's version locking, which we will look at soon.&lt;/p&gt;

&lt;p&gt;So once you make a change to your config you just run the &lt;code&gt;nixos-rebuild&lt;/code&gt; command and then pass in &lt;code&gt;switch&lt;/code&gt; if you want to apply the changes to your system immediately, &lt;code&gt;boot&lt;/code&gt; if you want to apply them at the next boot, &lt;code&gt;build&lt;/code&gt; if you just want to build without applying any changes and EVEN &lt;code&gt;build-vm&lt;/code&gt; which lets you build a virtual machine of your system to test if the changes work without actually testing it on your system.&lt;/p&gt;

&lt;p&gt;The last thing I'll mention is that on NixOS whenever you install a package, (which is done by simply adding the package name to your config) that package is version locked and can never change unless you update your system or specify another specific version of the package, no more needing to worry about a package updating and breaking without your knowledge!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;After using NixOS myself for a few years now I have never had a single problem with my system that couldn't be easily solved by making a quick change to my config.&lt;/p&gt;

&lt;p&gt;While NixOS has a steep learning curve it is well worth it. But don't fear there are alot of great resources on how to start with NixOS.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>nixos</category>
    </item>
  </channel>
</rss>
