From Gitea on Linux to Forgejo on FreeBSD

There is no solid reason why I moved away from Gitea. I actually liked Gitea. Let’s say I saw a window of opportunity and made the jump.

But let’s rewind and tell you a bit about the background. I embraced Gitea about two years ago, when I decided to host a private git. I couldn’t trust any public site (ex: GitHub or Gitlab) to hold my journal (see Hermit project). But also, I was eager to work on common projects with friends. Icing on the cake, Gitea offered a Wiki in a similar way of Gitlab, a functionality I love, and … it’s a single binary!

My Gitea instance was running as a container on one physical server running Debian with MySQL as a backend, following Gitea’s recommended installation, along with a couple of other services. I use the “trick” of leveraging a container and ansible automation playbooks because of disaster recovery. I could restore the data at any time on another server, run the playbooks, and be up and running in a jiffy. That was a lifesaver on the night of October 2023, when I was on another continent, and I had to relocate my services to another system as quickly as possible.

Please forgive me: as usual, I go tangential. Long story short, I was content and never had a glitch.

However, two things went on loop in the background of my brain.

I hoped to share Gitea with friends for some common projects. However, that never happened. I was the only one using the instance and that made me question if I should keep Gitea, because most of my projects could be hosted on a simple directory on an host and accessed via ssh. Gitea was configured with MySQL and caching: it felt too much for just one person.

The other thing is that I was made aware of Forgejo, both through the BSD community and Codeberg. I discovered that Forgejo is a fork of Gitea because Gitea’s developer founded a company and offered support, and some users were afraid of a potential license change. Although I feel these chances are slim for Gitea, I can’t blame the fear due to the current wave of enshittification hitting open source projects.

I also read on Forgejo’s blog that, at the beginning of 2024, Forgejo became a hard fork:

“As of Forgejo v1.21, Forgejo contains all of Gitea, and that has the benefit of allowing Forgejo to be a drop-in replacement. With the decision to become a hard fork, this will no longer be guaranteed. […] If you were considering upgrading to Forgejo, we encourage you to do that sooner rather than later, because as the projects naturally diverge further, doing so will become ever harder.”

That was the main reason that made me jump. If I ever had to move away from Gitea, I had to do it as soon as possible. And even that, the Gitea release I was running past the hard fork. And maybe I could still have a chance, but perhaps I would not have the same luck the more I waited.

So, I thought: if I had to jump, better be a good jump! I decided to downgrade the installation from MySQL to sqlite, as I’m basically the only one using it, and change the from a container on Linux to a jail on FreeBSD on the R710 in my new colocation.

So I made and executed my plan:

  1. I downgraded Gitea from MariaDB to sqlite, keeping Gitea as a container on Linux. The “gitea dump –database” command is amazing as you can decide which flavour of database you can dump to. With that, I could dump the data on MariaDB and restore the database to sqlite with just the sqlite3 command itself. Then I changed the app.ini configuration file to point to the new sqlite database, and ran “gitea doctor check –all –fix” and “gitea doctor recreate-table” to fix the tables and recreate any missing ones.

  2. I prepared a VNET jail on FreeBSD with Bastille. There is no real reason why I used Bastille instead of other jail managers. I think I picked up on popularity. And I installed forgejo from the packages.

  3. From the former Gitea dump, I extracted the app.ini configuration file, and I adapted it for my new environment on FreeBSD. It was mostly changing directory locations and creating a new directory structure.

  4. I stopped the Gitea container on Linux, so I could not have any further updates to the repositories by mistake. I again dumped Gitea with the “gitea dump” command and restored it on the FreeBSD jail by following the Gitea’s backup/restore manual. Having to deal with a single sqlite database was much easier.

  5. I ran the command “gitea doctor check –all –fix” as suggested by the above backup/restore. That brought up a lot of tables fixed by the command. A cold sweat went down my spine and I crossed all my fingers: this is where the migration could happen, or it was too late for the jump.

  6. I started the forgejo service on FreeBSD. I celebrated when I saw no significant error message on the console. But when I tried to log on to the web interface, after username and password, I received a “500 Internal Server Error” on the console. After a few searches on previous issues, I understood that could have been related to my two-factor authentication, as things might have changed in how the SECRET_KEY app.ini variable was handled from that release of Gitea to Forgejo. So, I deleted my two-factor configuration from the “two_factor” table …. and it worked, I was in! (I needed to recreate my 2FA)

  7. Everything was working through the web interface, but my Wikis. The weird thing is that I could check out the wiki files with the git command, but the wiki itself wasn’t displaying on the web. As I had the markdown files, I thought that recreating those few repos could have been a small price to pay for the migration. But I am stubborn, so I searched again for any potential issue and I discovered that the reason for that is because both Gitea and Forgejo are “hard coding” the branch name for the wiki at this stage. But while Gitea used master, Forgejo is now using the newer main branch. So it was sufficient to rename the branch through the git command, push the wiki repository … and magically I had my wikis back.

A couple of notes. I had to use tcp_proxy on FreeBSD to redirect the SSH port from 22 to the unprivileged Forgejo port. This was handled differently with the container on Linux, as you can map the ports. In this journey, I understood that the redirect in pf.conf works only if the packet is in transit and not directed to the host. While it could potentially be a performance issue for a large installation, I’m the only one using it, so … why complicate it?

Also, in both scenarios, I had Caddy as a reverse proxy. While I could have terminated SSL directly with Forgejo in the new installation, I decided to keep Caddy as a frontend to be able to redirect friendly hostnames to the wiki pages.

It took me almost a working day to go cautiously through the above process, but I’m not looking back. Perhaps it’s less automated than before, but I’m confident that with sqlite and a “bastille export”, I can potentially restore my private git anywhere in a reasonable amount of time.

2024-12-09