<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>blog.n11n [tag: self-hosted]</title>
  <link>https://blog.n11n.ca</link>
  <description>Nicholas' blog</description>
  <language>en</language>
  <atom:link href="https://blog.n11n.ca/rss.xml" rel="self" type="application/rss+xml" />

  <item>
    <title>Homelab</title>
    <pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate>
    <link>https://blog.n11n.ca/homelab</link>
    <guid>https://blog.n11n.ca/2</guid>
    <description>A general overview of my homelab.</description>
    <content:encoded><![CDATA[<p>It all started with a grocery list.</p> <p>Our paper list was always getting left behind, lost, or thrown away. So I set out to digitize it. But, I didn't want to rely on some external service like dropbox or google docs to do it. Instead, the first spare computer I had sitting around got a fresh copy of <a href="https://www.debian.org/">Debian</a> and away I went.</p> <p>What began as a simple idea eventually grew into multiple servers, dozens of services, and endless projects.</p> <h2>Design</h2> <p>When I started to build my lab, the plan was to create something dependable. I didn't (and still don't) want to spend all my free time making sure everything simply works.</p> <p>The backup plan was to have reliable backups. I drafted a policy and set off to make sure any important data would always be somewhere in case of an emergency. Six-<em>ish</em> years later and I still haven't managed to lose anything important. yet. <em>*knocks on wood*</em></p> <p>Security was and still is a major concern. I don't like people touching my stuff, so I want to make sure only those authorized can get anything in, or out. I'm constantly learning new concepts and finding ways to integrate them and improve the overall design.</p> <h2>Infrastructure</h2> <p>The backbone of my lab is the <a href="https://en.wikipedia.org/wiki/Forge_(software)">forge</a>, which is currently powered by <a href="https://forgejo.org/">Forgejo</a>. After testing and using a few other services, I migrated to Forgejo a few years ago because I really like the community and governance structure - plus it powers <a href="https://codeberg.org/">Codeberg</a> where my public code is.</p> <p>Within my forge, any production infrastructure is defined as code. This includes configuration files, build steps, and playbooks to deploy hosts.</p> <h2>Networking</h2> <p>Part of building something dependable was making it available and easily accessible. What began with open ports and a static IP address, quickly got replaced by a reverse proxy to handle routing and encrypting connections using TLS.</p> <p>Once everything was accessible internally, the next challenge became remote access away from home. Again, open router ports were quickly replaced by VPN access for anyone deemed worthy.</p> <p>The lab has always been an environment for me to learn and explore new networking concepts. Over time this has included IPv6, mTLS, VLANs, and more.</p> <h2>Development</h2> <p>After a reliable system was in place, I could begin developing the tools and services to run on it. There are lots of amazing projects I found that could be easily self-hosted, however I love learning, and writing code, so I often end up building my own stuff.</p> <p>Here are just some of the things I have built or am working on:</p> <ul> <li> asset catalogues: books, hardware, digital assets, etc. </li><li> audio transcription tool </li><li> digital toolbox </li><li> pastebin </li><li> personal finance manager </li><li> text/audio/video chat using WebRTC </li><li> video/image sharing platforms </li> </ul> <p>I made most of these just for me (plus my friends and family), but some might end up being released into the wild one day.</p> <h2>Documentation</h2> <p>Besides backups, good documentation has been the most important part of my lab. I started with handwritten notes and slowly grew them into various tutorials, how-to guides, explanations, and reference materials. More than once I've forgotten how (or why) I did something and only had notes from past me to rely on.</p> <p>Although my documentation is far from perfect, it's constantly evolving to stay useful and relevant going forward.</p> <h2>Now</h2> <p>Everything is in a pretty good state. Over the last couple years I focused on reducing the size and complexity of my lab without sacrificing performance. Turns out I didn't really need much to run everything, plus I sort of enjoy the challenge of doing more with less.</p> <p>Right now that consists of:</p> <ul> <li> <strong>Protectli Vault</strong>: router running OPNSense </li><li> <strong>Intel NUC</strong>: running virtualized dev/prod Debian environments using Proxmox </li><li> <strong>Raspberry Pi</strong>: mainly to control my sit-stand desk and a few other things </li> </ul> <p>I also have a <a href="https://en.wikipedia.org/wiki/Virtual_private_server">VPS</a> running several services outside of my lab.</p> <h2>Next</h2> <p>New hardware is almost always on the radar, however I'm frugal (aka cheap) and a strong advocate of "if it ain't broke don't fix it". I'm looking for a decent <a href="https://en.wikipedia.org/wiki/Uninterruptible_power_supply">UPS</a> though, and some extra storage could always be put to good use.</p> <p>With a stable system, and most of my development needs covered for now, I'm excitedly looking for the next problem to solve.</p> <p>Whatever that might be.</p>         <div class="tags"><a href="https://blog.n11n.ca/tag/forgejo">forgejo</a> <a href="https://blog.n11n.ca/tag/homelab">homelab</a> <a href="https://blog.n11n.ca/tag/self-hosted">self-hosted</a></div> <br>]]></content:encoded>
  </item>

  <item>
    <title>Trigger a remote workflow with Forgejo Actions</title>
    <pubDate>Sat, 31 Jan 2026 00:00:00 +0000</pubDate>
    <link>https://blog.n11n.ca/remote-forgejo-action</link>
    <guid>https://blog.n11n.ca/1</guid>
    <description>How to trigger a workflow in another repository with Forgejo Actions</description>
    <content:encoded><![CDATA[<p>This demonstrates using the <a href="https://codeberg.org/api/swagger">Forgejo API</a> to let a workflow in one repository (<code>from</code>) dispatch a workflow in another (<code>to</code>).</p> <h2>Setup</h2> <p>An <a href="https://forgejo.org/docs/latest/user/token-scope/">access token scoped</a> with <strong>write:repository</strong> permissions must first be created:</p> <p><img src="https://blog.n11n.ca/images/forgejo-access-token.png" alt="User settings > Applications > Access tokens > Generate new token" /></p> <p>Then, add it as a secret named <strong>PAT</strong> in the <code>from</code> repository.</p> <p><em>(make sure Actions are enabled in both repos)</em></p> <h2>"From" workflow</h2> <pre><code># .forgejo/workflows/trigger.yaml</code><br><code>name: Trigger remote</code><br><br><code># trigger for all pushes, adjust accordingly</code><br><code>on:</code><br><code>  push:</code><br><br><code>env:</code><br><code>  SERVER_URL: "git.example.com"</code><br><code>  TARGET_BRANCH: "main"</code><br><code>  TARGET_REPO: "to"</code><br><code>  TARGET_REPO_OWNER: "username"</code><br><code>  WORKFLOW_FILE: "remote.yaml"</code><br><br><code>jobs:</code><br><code>  trigger:</code><br><code>    runs-on: runner-name</code><br><code>    steps:</code><br><code>      - name: Remote trigger</code><br><code>        run: |</code><br><code>          curl -X 'POST' \</code><br><code>            'https://${{ env.SERVER_URL }}/api/v1/repos/${{ env.TARGET_REPO_OWNER }}/${{ env.TARGET_REPO }}/actions/workflows/${{ env.WORKFLOW_FILE }}/dispatches' \</code><br><code>            -H 'Accept: application/json' \</code><br><code>            -H 'Authorization: token ${{ secrets.PAT }}' \</code><br><code>            -H 'Content-Type: application/json' \</code><br><code>            -d '{"ref": "${{ env.TARGET_BRANCH }}"}'</code></pre> <h2>"To" workflow</h2> <pre><code># .forgejo/workflows/remote.yaml</code><br><code>name: Triggered workflow</code><br><br><code># trigger from API dispatch</code><br><code>on:</code><br><code>  repository_dispatch:</code><br><br><code>jobs:</code><br><code>  execute:</code><br><code>    runs-on: runner-name</code><br><code>    steps:</code><br><code>      - name: Remotely triggered</code><br><code>        run: |</code><br><code>          echo "This was triggered remotely"</code></pre> <h3>Also see</h3> <ul> <li> <a href="https://forgejo.org/docs/next/user/actions/reference/">Forgejo Actions | Reference</a> </li> </ul>         <div class="tags"><a href="https://blog.n11n.ca/tag/actions">actions</a> <a href="https://blog.n11n.ca/tag/ci-cd">ci-cd</a> <a href="https://blog.n11n.ca/tag/forgejo">forgejo</a> <a href="https://blog.n11n.ca/tag/git">git</a> <a href="https://blog.n11n.ca/tag/how-to">how-to</a> <a href="https://blog.n11n.ca/tag/self-hosted">self-hosted</a></div> <br>]]></content:encoded>
  </item>
</channel>
</rss>
