<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Rob Hofman]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://robhofman.be/</link><image><url>https://robhofman.be/favicon.png</url><title>Rob Hofman</title><link>https://robhofman.be/</link></image><generator>Ghost 5.78</generator><lastBuildDate>Tue, 29 Oct 2024 17:12:48 GMT</lastBuildDate><atom:link href="https://robhofman.be/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea]]></title><description><![CDATA[<p>Today, I took another step in enhancing my homelab. As a huge fan of the self-hosted community, I&apos;ve spent the past year experimenting with my own home servers, running various services and applications. My latest project is aimed at solving a recurring concern: what happens if a drive</p>]]></description><link>https://robhofman.be/selfhosted-git-and-cicd-using-gitea/</link><guid isPermaLink="false">671e3bf5fb8eed12a3613f96</guid><dc:creator><![CDATA[Rob Hofman]]></dc:creator><pubDate>Sun, 27 Oct 2024 15:46:49 GMT</pubDate><media:content url="https://robhofman.be/content/images/2024/10/gitea-cloud-concept.png" medium="image"/><content:encoded><![CDATA[<img src="https://robhofman.be/content/images/2024/10/gitea-cloud-concept.png" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea"><p>Today, I took another step in enhancing my homelab. As a huge fan of the self-hosted community, I&apos;ve spent the past year experimenting with my own home servers, running various services and applications. My latest project is aimed at solving a recurring concern: what happens if a drive fails or, more plausible, if I fuck something up. </p><p>In my professional life, these fears are mitigated by using version control, cloud-based infrastructure, and CI/CD pipelines for deployments. So I thought, why not apply the same principles to my homelab?</p><h3 id="why-not-github">Why Not GitHub?</h3><p>My first instinct was to use what I already knew&#x2014;GitHub and GitHub Actions. While this seemed like a solid option, I had some reservations. For one, my code would be stored on GitHub&apos;s servers, which is a dealbreaker for many in the self-hosted community. While I&apos;m personally okay with that, the self-hosting option was too tempting to ignore. Moreover, using GitHub Actions (in the cloud) to connect to my home server (on my local network) comes with complexities, especially since I don&#x2019;t have a static IP address.</p><h3 id="exploring-gitea">Exploring Gitea</h3><p>After some research, I discovered that GitHub Actions and GitLab CI/CD have self-hosted alternatives. But I also came across Gitea, an open-source alternative that had everything I needed and is compatible with the GitHub Actions syntax. </p><h3 id="installation-and-setup">Installation and Setup</h3><p>My homelab runs on Proxmox, and I often use the <a href="https://github.com/tteck/Proxmox?ref=robhofman.be" rel="noopener">Proxmox Helper Scripts repository</a> to simplify service installations. Thankfully, there was an LXC container script available for Gitea, which made installation very quick and easy.</p><h4 id="setting-up-postgresql">Setting Up PostgreSQL</h4><p>The first hurdle was setting up a database for Gitea (I did not know this was a requirement). It supports both MySQL and PostgreSQL, but from what I read, PostgreSQL is the preferred choice of the Gitea team, offering better, quicker support. Luckily, Proxmox had a helper script for PostgreSQL as well. Here&#x2019;s a quick summary of the setup commands I used:</p><pre><code># Change the PostgreSQL user password
passwd postgres

# Log in as the postgres user
su - postgres

# Change the admin password
psql -c &quot;ALTER USER postgres WITH PASSWORD &apos;your-password&apos;;&quot;

# Create a Gitea user with the appropriate role
CREATE USER gitea WITH PASSWORD &apos;your-password&apos;;
CREATE ROLE gitea WITH LOGIN PASSWORD &apos;gitea&apos;;

# Create the Gitea database and assign the gitea user
CREATE DATABASE giteadb WITH OWNER gitea TEMPLATE template0 ENCODING UTF8 LC_COLLATE &apos;en_US.UTF-8&apos; LC_CTYPE &apos;en_US.UTF-8&apos;;

# Exit PostgreSQL
\\q</code></pre><h3 id="configuring-gitea">Configuring Gitea</h3><p>Once Gitea was installed, I changed the IP address of the LXC to a fixed one so it would never change. However if you want to go quicker you can use the IP address which is showed at the end fo the installation process. </p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">it is always a good idea to setup a static IP for your services</div></div><p>Once you visit your gitea page, you should be greated with a configuration page. Fill in the details of your postgres database and click on &quot;install Gitea&quot;. </p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/10/image.png" class="kg-image" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea" loading="lazy" width="876" height="563" srcset="https://robhofman.be/content/images/size/w600/2024/10/image.png 600w, https://robhofman.be/content/images/2024/10/image.png 876w" sizes="(min-width: 720px) 720px"></figure><p>If all went well you should now have your own self hosted Gitea system. (I already added some repositories in the screenshot below.)</p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/10/image-1.png" class="kg-image" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea" loading="lazy" width="1711" height="869" srcset="https://robhofman.be/content/images/size/w600/2024/10/image-1.png 600w, https://robhofman.be/content/images/size/w1000/2024/10/image-1.png 1000w, https://robhofman.be/content/images/size/w1600/2024/10/image-1.png 1600w, https://robhofman.be/content/images/2024/10/image-1.png 1711w" sizes="(min-width: 720px) 720px"></figure><h3 id="setting-up-gitea-action-runners">Setting up Gitea action runners </h3><p>Next, I wanted to automate some deployment tasks using <a href="https://docs.gitea.com/usage/actions/overview?ref=robhofman.be" rel="noreferrer">Gitea Actions</a>. Both Gitea and PostgreSQL were running in LXC containers on Proxmox, but for the action runner, I used Docker Compose on my local Windows machine. </p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/10/Untitled-2024-10-27-1526.svg" class="kg-image" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea" loading="lazy" width="628" height="370"></figure><p>I used docker compose to setup a compose file for the action runner (which I just took from the <a href="https://docs.gitea.com/usage/actions/act-runner?ref=robhofman.be#start-the-runner-using-docker-compose" rel="noreferrer">Gitea documentation page</a>)</p><pre><code class="language-yaml">version: &quot;3.8&quot;
services:
  runner:
    image: gitea/act_runner:nightly
    environment:
      CONFIG_FILE: /config.yaml
      GITEA_INSTANCE_URL: &quot;http://192.168.1.72:3000&quot;
      GITEA_RUNNER_REGISTRATION_TOKEN: &quot;${REGISTRATION_TOKEN}&quot;
      GITEA_RUNNER_NAME: &quot;testrunner&quot;
      GITEA_RUNNER_LABELS: &quot;ubuntu-latest:docker://node:16-bullseye&quot;
    volumes:
      - ./config.yaml:/config.yaml
      - ./data:/data
      - /var/run/docker.sock:/var/run/docker.sock</code></pre><h3 id="getting-the-registration-token">Getting the registration token</h3><p>To register the runner, I needed a token. This can be generated by going to <strong>Site Administration</strong> from the user dropdown in the top-right corner of Gitea. Under <strong>Actions &gt; Runners</strong>, I clicked &quot;Create New Runner&quot; to get the token, which I then inserted into the Docker Compose file (I still need to find a way to do this more securely but this is how I do it for now locally on my PC).</p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/10/image-2.png" class="kg-image" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea" loading="lazy" width="1713" height="600" srcset="https://robhofman.be/content/images/size/w600/2024/10/image-2.png 600w, https://robhofman.be/content/images/size/w1000/2024/10/image-2.png 1000w, https://robhofman.be/content/images/size/w1600/2024/10/image-2.png 1600w, https://robhofman.be/content/images/2024/10/image-2.png 1713w" sizes="(min-width: 720px) 720px"></figure><h4 id="fixing-runner-issues">Fixing Runner Issues</h4><p>When I tried running the Docker Compose file, I encountered an error: Gitea couldn&#x2019;t find the <code>config.yaml</code> file because Docker had mistakenly created it as a folder. </p><pre><code>2024-10-27 15:43:34 Error: invalid configuration: open config file &quot;/config.yaml&quot;: read /config.yaml: is a directory</code></pre><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/10/Screenshot-2024-10-27-154524.jpg" class="kg-image" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea" loading="lazy" width="244" height="97"></figure><p>After deleting the folder and recreating it as a file, everything worked, and the runner appeared in Gitea.</p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/10/image-5.png" class="kg-image" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea" loading="lazy" width="1703" height="253" srcset="https://robhofman.be/content/images/size/w600/2024/10/image-5.png 600w, https://robhofman.be/content/images/size/w1000/2024/10/image-5.png 1000w, https://robhofman.be/content/images/size/w1600/2024/10/image-5.png 1600w, https://robhofman.be/content/images/2024/10/image-5.png 1703w" sizes="(min-width: 720px) 720px"></figure><h3 id="setting-up-the-labels">Setting up the labels</h3><p>The next issue I encounterd was that I used the wrong label in my docker compose. It is important to use the right labels. Otherwise the Gitea Action might not know certain actions. At first I got an error on the step: &quot;actions/checkout@v4&quot;. After fixing the label to &quot;ubuntu-latest:docker://node:16-bullseye&quot;, my issue was solved. More info on the labels can be found on the <a href="https://docs.gitea.com/usage/actions/act-runner?ref=robhofman.be#labels" rel="noreferrer">Gitea documentation</a>.</p><h3 id="testing-the-action-runner">Testing the action runner</h3><p>To test if everything was working I used <a href="https://github.com/TheHomelabber/self-hosted-git-hello-world?ref=robhofman.be" rel="noreferrer">the example of &quot;The Homelabber&quot;</a>. I cloned his/her example repository, linked it to my Gitea account, and pushed a commit. The action triggered perfectly, showing all green checkmarks!</p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/10/WhatsApp-Image-2024-10-27-at-14.08.29_8d78f4fd.jpg" class="kg-image" alt="Upgrading My Homelab with Self-Hosted Git and CI/CD using Gitea" loading="lazy" width="1600" height="695" srcset="https://robhofman.be/content/images/size/w600/2024/10/WhatsApp-Image-2024-10-27-at-14.08.29_8d78f4fd.jpg 600w, https://robhofman.be/content/images/size/w1000/2024/10/WhatsApp-Image-2024-10-27-at-14.08.29_8d78f4fd.jpg 1000w, https://robhofman.be/content/images/2024/10/WhatsApp-Image-2024-10-27-at-14.08.29_8d78f4fd.jpg 1600w" sizes="(min-width: 720px) 720px"></figure><h1 id="acknowledgments">Acknowledgments</h1><p>This blogpost/guide is completely built with the help of the excelent blogposts of <a href="https://thehomelabber.com/series/self-hosted-git-with-gitea/?ref=robhofman.be" rel="noreferrer">The Homelabber</a>. Although (s)he does not have completely the same setup as me, the blog provided me with a lot of help. Next to that I have to say the <a href="https://docs.gitea.com/?ref=robhofman.be" rel="noreferrer">Gitea documentation</a> is very thoroughly and nicely written. </p><h1 id="next-steps">Next steps</h1><p>I&#x2019;m really happy with how this project turned out. The next steps include moving the action runner to Proxmox and setting up a reliable backup solution for my repositories. I&#x2019;m still debating whether to sync them with GitHub, offload the code to cloud storage (Google One, OneDrive, Dropbox, etc.), or simply store a copy on my local NAS.</p><p>And so another small step has been taken to automate my entire homelab!</p><p><strong>Keep on labbing! ;)</strong></p>]]></content:encoded></item><item><title><![CDATA[Hello World]]></title><description><![CDATA[<p>To create my personal space on the web I needed to find the right technology. I wanted an easy to use CMS which gave me some headroom for the future.</p><p>I decided to dive back into the world of web technologies and create my own blog. Boy, have things changed</p>]]></description><link>https://robhofman.be/my-blog/</link><guid isPermaLink="false">65bbfd7eacaad01ab99a50ae</guid><category><![CDATA[ghost]]></category><category><![CDATA[blog]]></category><category><![CDATA[webdev]]></category><dc:creator><![CDATA[Rob Hofman]]></dc:creator><pubDate>Thu, 01 Feb 2024 20:22:22 GMT</pubDate><media:content url="https://robhofman.be/content/images/2024/02/ghost.png" medium="image"/><content:encoded><![CDATA[<img src="https://robhofman.be/content/images/2024/02/ghost.png" alt="Hello World"><p>To create my personal space on the web I needed to find the right technology. I wanted an easy to use CMS which gave me some headroom for the future.</p><p>I decided to dive back into the world of web technologies and create my own blog. Boy, have things changed since I created my last website 5 years ago.</p><p>In this post, I will take you through the process of me starting from the idea of creating a blog to this first post.</p><h3 id="cms"><strong>CMS</strong></h3><p>It took me maybe 20 minutes to realize I was too long out of the game to create something from scratch. I looked into the latest trends in web dev technologies, and things have clearly changed since the day I created my last website. I was hesitating a bit to create a website using a static site generator, but in the end, I chose the easy way.</p><p>When looking for &quot;self-hosted blog&quot; on Reddit, it quickly became clear there was one favorite across the open-source, self-hosting community: <a href="https://ghost.org/?ref=robhofman.be" rel="noreferrer">Ghost</a>. It is an easy-to-use CMS which is completely open-source. You can choose to let Ghost do the hosting, but they also offer an option to self-host your Ghost instance. I chose the self-hosting option.</p><p>Last but not least, it is ready for the future. Ghost offers a lot of features which I currently don&apos;t need: newsletter, members, payments, tracking,... You never know where this new pet project will bring me, at least I have some head room with ghost &#x1F604;</p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/02/image-1.png" class="kg-image" alt="Hello World" loading="lazy" width="1691" height="562" srcset="https://robhofman.be/content/images/size/w600/2024/02/image-1.png 600w, https://robhofman.be/content/images/size/w1000/2024/02/image-1.png 1000w, https://robhofman.be/content/images/size/w1600/2024/02/image-1.png 1600w, https://robhofman.be/content/images/2024/02/image-1.png 1691w" sizes="(min-width: 720px) 720px"></figure><h3 id="domain-name"><strong>Domain Name</strong></h3><p>Registering a domain name is easy. I purchased mine at <a href="https://www.combell.com/nl/?ref=robhofman.be" rel="noreferrer">Combell </a>since it is a Belgian company. However, I liked the idea of managing my domain name at the same place as my server, so <a href="https://docs.digitalocean.com/products/networking/dns/?ref=robhofman.be" rel="noreferrer">I set up my DNS servers to the name servers of DigitalOcean so I could manage my domain from there</a>.</p><h3 id="hosting"><strong>Hosting</strong></h3><p>For hosting, I went for a classic: <a href="https://digitalocean.com/?ref=robhofman.be" rel="noreferrer">DigitalOcean</a>. You get an easy-to-use interface for a reasonable price. There is even a Ghost app droplet in the DigitalOcean marketplace. Once I created the droplet using <a href="https://ghost.org/docs/install/digitalocean/?ref=robhofman.be" rel="noreferrer">this guide from Ghost</a>, I was faced with the second problem: the Ghost instance would not boot. After running the command &quot;ghost doctor,&quot; I was notified my server had too little memory. After upgrading my VPS to an instance with 2 GB RAM, I was able to see my website.</p><figure class="kg-card kg-image-card"><img src="https://robhofman.be/content/images/2024/02/image-2.png" class="kg-image" alt="Hello World" loading="lazy" width="1695" height="686" srcset="https://robhofman.be/content/images/size/w600/2024/02/image-2.png 600w, https://robhofman.be/content/images/size/w1000/2024/02/image-2.png 1000w, https://robhofman.be/content/images/size/w1600/2024/02/image-2.png 1600w, https://robhofman.be/content/images/2024/02/image-2.png 1695w" sizes="(min-width: 720px) 720px"></figure><h3 id="setup"><strong>Setup</strong></h3><p>Enabling the theme (I went with a free blog theme, which is fine for me) and disabling all subscription stuff, I was ble to create this first post. I am really amazed at how easy writing an article for my own Ghost website is. I don&apos;t need any technical stuff, and I can just write the content in a &quot;Notion-like&quot; interface.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://robhofman.be/content/images/2024/02/image.png" class="kg-image" alt="Hello World" loading="lazy" width="1684" height="662" srcset="https://robhofman.be/content/images/size/w600/2024/02/image.png 600w, https://robhofman.be/content/images/size/w1000/2024/02/image.png 1000w, https://robhofman.be/content/images/size/w1600/2024/02/image.png 1600w, https://robhofman.be/content/images/2024/02/image.png 1684w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">screenshot of the interface of the editor of this blog post</span></figcaption></figure><h3 id="future"><strong>Future</strong></h3><p>Later on, I would really like to implement some kind of version control. Ideally, I write my blog posts locally in markdown, push them to my Git repository, and my CI/CD pipeline makes sure it gets published.<br>Another thing I would like to experiment with is containerization. Ghost does offer a docker image. I would like to experiment with running the entire website via container technology. This way, I would like to improve my knowledge on this topic</p>]]></content:encoded></item></channel></rss>