<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Server - Services | Derek Armstrong — Software Engineer · AI · Infrastructure</title><link>https://derekarmstrong.dev/tags/server---services/</link><atom:link href="https://derekarmstrong.dev/tags/server---services/index.xml" rel="self" type="application/rss+xml"/><description>Server - Services</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Wed, 23 Apr 2025 00:00:00 +0000</lastBuildDate><image><url>https://derekarmstrong.dev/media/sharing.png</url><title>Server - Services</title><link>https://derekarmstrong.dev/tags/server---services/</link></image><item><title>Gitea: Git on Your Own Terms</title><link>https://derekarmstrong.dev/blog/gitea-git-on-your-own-terms/</link><pubDate>Wed, 23 Apr 2025 00:00:00 +0000</pubDate><guid>https://derekarmstrong.dev/blog/gitea-git-on-your-own-terms/</guid><description>&lt;p&gt;Welcome, fellow home lab enthusiasts! If you&amp;rsquo;re anything like me, you&amp;rsquo;ve probably caught yourself thinking, &amp;ldquo;You know what my server rack needs? More services to tinker with!&amp;rdquo; Well, today we&amp;rsquo;re diving into one of my favorite self-hosted applications: a personal Git server with Gitea. It&amp;rsquo;s like having your own mini GitHub, without the corporate overlords or surprise &amp;ldquo;updates&amp;rdquo; to the terms of service.&lt;/p&gt;
&lt;h2 id="why-gitea-the-little-git-server-that-could"&gt;Why Gitea? The Little Git Server That Could&lt;/h2&gt;
&lt;p&gt;In the world of self-hosted Git solutions, Gitea stands out like a sane person at a cryptocurrency convention. Written in Go, Gitea is ridiculously lightweight, blazing fast, and requires minimal resources - perfect for that dusty Raspberry Pi or the VM you&amp;rsquo;ve allocated just 512MB of RAM to.&lt;/p&gt;
&lt;p&gt;While GitLab offers a more comprehensive DevOps platform with all the bells and whistles (and resource requirements to match), Gitea focuses on doing one thing extremely well: being a Git server that doesn&amp;rsquo;t make your hardware weep. As one user aptly put it: &amp;ldquo;Gitea + SQLite is perfect for home lab. Zero maintenance overhead&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The interface will feel familiar to GitHub users, which makes the transition nearly painless. Plus, the project is actively maintained with regular updates and security patches.&lt;/p&gt;
&lt;h2 id="the-pros-why-youd-want-your-own-git-fortress"&gt;The Pros: Why You&amp;rsquo;d Want Your Own Git Fortress&lt;/h2&gt;
&lt;h3 id="data-sovereignty-your-code-your-rules"&gt;Data Sovereignty: Your Code, Your Rules&lt;/h3&gt;
&lt;p&gt;Having your own Git server means you&amp;rsquo;re not subject to a third party&amp;rsquo;s policies, outages, or sudden pricing changes. No third party has access to your data, ensuring security (which can still be questionable), and you have unlimited repository size.&lt;/p&gt;
&lt;h3 id="mirror-mirror-on-the-wall-who-has-the-most-repos-of-all"&gt;Mirror, Mirror on the Wall, Who Has the Most Repos of All?&lt;/h3&gt;
&lt;p&gt;One of Gitea&amp;rsquo;s killer features is its mirroring capability. You can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Mirror repositories from GitHub, GitLab, or other services to create automatic backups&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Push changes from your private Gitea instance to public repositories&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keep everything in sync with minimal effort&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gitea makes it trivial to mirror a repo. You just choose &amp;rsquo;new migration&amp;rsquo; from under the &amp;lsquo;+&amp;rsquo; menu, and then click on the service you&amp;rsquo;re migrating from.&lt;/p&gt;
&lt;h3 id="unrestricted-runner-minutes-cicd-without-the-meter-running"&gt;Unrestricted Runner Minutes: CI/CD without the Meter Running&lt;/h3&gt;
&lt;p&gt;Unlike GitHub, which meters your CI/CD minutes like a stingy taxi driver, your self-hosted Gitea instance lets you run your CI/CD pipelines as long as your hardware can handle it. Want to set up a 3-hour build process that compiles your personal project on seven different architectures? Go wild!&lt;/p&gt;
&lt;h3 id="offline-access-because-internet-outages-are-a-thing"&gt;Offline Access: Because Internet Outages Are a Thing&lt;/h3&gt;
&lt;p&gt;Another great reason to host your own Gitea instance is that it&amp;rsquo;s available offline. When your internet decides to take an unscheduled vacation, you can still commit changes, browse code, and reference documentation.&lt;/p&gt;
&lt;h3 id="unlimited-private-repositories"&gt;Unlimited Private Repositories&lt;/h3&gt;
&lt;p&gt;You don&amp;rsquo;t need to pay for private repositories or worry about limits from third-party services. With your own server, you have full control and can create unlimited private repositories at no extra cost. This lets you organize projects your way, whether they&amp;rsquo;re small or large, and customize your workflow to fit your needs.&lt;/p&gt;
&lt;h2 id="the-cons-the-price-of-freedom"&gt;The Cons: The Price of Freedom&lt;/h2&gt;
&lt;h3 id="maintenance-you-break-it-you-fix-it"&gt;Maintenance: You Break It, You Fix It&lt;/h3&gt;
&lt;p&gt;Self-hosting means being your own system administrator. When things go sideways, there&amp;rsquo;s no support ticket to file (unless you count yelling at your server rack).&lt;/p&gt;
&lt;h3 id="backups-dont-be-that-person"&gt;Backups: Don&amp;rsquo;t Be That Person&lt;/h3&gt;
&lt;p&gt;You absolutely need a backup strategy. &amp;ldquo;Just wondering what everyone is doing to back up a gitea container?” is a question you should answer before, not after, a disk failure.&lt;/p&gt;
&lt;h3 id="security-with-great-power-comes-great-responsibility"&gt;Security: With Great Power Comes Great Responsibility&lt;/h3&gt;
&lt;p&gt;Security - continuous monitoring just in case someone gets curious&amp;hellip;and lucky. If you&amp;rsquo;re exposing your Gitea instance to the internet, you need to be vigilant about security. Do your homework, understanding how to impliment good security is a high value skill!&lt;/p&gt;
&lt;h2 id="protecting-your-code-castle"&gt;Protecting Your Code Castle&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re keeping your Gitea instance local, behind your firewall, security is relatively simple. But if you&amp;rsquo;re exposing it to the internet, consider:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Using Cloudflare Zero Trust tunnels to avoid opening ports&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enforcing two-factor authentication for all accounts&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keeping your instance updated religiously&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implementing strong password policies&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remember: The first registered user automatically gets admin privileges, so set up your account immediately after installation!&lt;/p&gt;
&lt;h2 id="setting-sail-with-docker-compose"&gt;Setting Sail with Docker Compose&lt;/h2&gt;
&lt;p&gt;Getting started with Gitea is as easy as creating a docker-compose.yml file. Here&amp;rsquo;s a basic example to get you started:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gitea/gitea:latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gitea&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;USER_UID=1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;USER_GID=1000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;always&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./gitea:/data&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/etc/timezone:/etc/timezone:ro&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;/etc/localtime:/etc/localtime:ro&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;3000:3000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;2222:22&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Save this to a file, run &lt;code&gt;docker-compose up -d&lt;/code&gt;, and voilà! Your Gitea instance will be available at
. The first user to register will become the admin.&lt;/p&gt;
&lt;p&gt;For those who prefer a more rootless approach (because who doesn&amp;rsquo;t like added security?), Gitea also offers a rootless Docker image that uses Gitea&amp;rsquo;s internal SSH instead of OpenSSH.&lt;/p&gt;
&lt;h2 id="customization-making-it-your-own"&gt;Customization: Making It Your Own&lt;/h2&gt;
&lt;p&gt;The beauty of self-hosting is customization. Want to change the theme? Go for it. Need to integrate with your existing authentication system? It&amp;rsquo;s possible. Want to add a dancing cat gif to the login page? Weird, but technically doable.&lt;/p&gt;
&lt;p&gt;All configuration is stored in the &lt;code&gt;app.ini&lt;/code&gt; file, which you can find in the &lt;code&gt;custom&lt;/code&gt; directory of your Gitea installation.&lt;/p&gt;
&lt;h2 id="backup-strategies-because-stuff-happens"&gt;Backup Strategies: Because Stuff Happens&lt;/h2&gt;
&lt;p&gt;Gitea provides a built-in &lt;code&gt;dump&lt;/code&gt; command that creates a ZIP file containing everything needed to restore your instance. However, for a more robust solution, consider:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Regular database backups&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Volume snapshots if you&amp;rsquo;re using a filesystem that supports them&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Repository mirroring to another location&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Automated backup scripts that run on a schedule&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remember: a backup you haven&amp;rsquo;t tested restoring from is just a file taking up disk space.&lt;/p&gt;
&lt;h2 id="conclusion-to-git-or-not-to-git"&gt;Conclusion: To Git or Not to Git?&lt;/h2&gt;
&lt;p&gt;Self-hosting Gitea is like brewing your own craft beer. Sure, you could just buy it from the store, but where&amp;rsquo;s the fun in that? Plus, you get to brag about it to your friends who don&amp;rsquo;t care but politely nod anyway.&lt;/p&gt;
&lt;p&gt;The control, flexibility, and ownership you gain makes it worth the effort, especially if you&amp;rsquo;re already maintaining a home lab. So fire up that Docker container and start gitting on your own terms. Your code deserves a home where it&amp;rsquo;s treated like the precious resource it is, not just another tenant in a massive cloud datacenter.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Gitea Documentation. (2023). Repository Mirror.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Gitea Documentation. (2023). Installation with Docker (rootless).
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stack Overflow. (2017). Which are the pros (and cons) of self-hosting your repositories.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;XDA Developers. (2024). 5 reasons you should host your own Git server at home using Gitea.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
. (2022). Mirroring With Gitea.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;phoenixNAP. (2025). How to Install Gitea with Docker on Ubuntu.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reddit. (2019). Pros &amp;amp; Cons: Self Hosted Git.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="key-takeaways"&gt;Key Takeaways&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Gitea is lightweight enough for a Raspberry Pi or a 512MB VM. Written in Go, it does one thing well without the resource drain of GitLab.&lt;/li&gt;
&lt;li&gt;Repository mirroring is a killer feature. One-click mirroring from GitHub or GitLab gives you automatic backups and offline access.&lt;/li&gt;
&lt;li&gt;Self-hosted CI/CD means unlimited runner minutes. Build pipelines run as long as your hardware can handle them.&lt;/li&gt;
&lt;li&gt;Security is your responsibility. Cloudflare Zero Trust tunnels, 2FA, and strong password policies are the bare minimum when exposing Gitea to the internet.&lt;/li&gt;
&lt;li&gt;A backup you have not tested restoring from is just a file taking up disk space. Test restores regularly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="next"&gt;Next&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
— the server infrastructure that makes self-hosting services practical.&lt;/li&gt;
&lt;li&gt;
— VM management tools for the homelab that runs alongside container services.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>