I just had a very pleasant experience installing and setting up Gogs.io on my server, so that I can self-host my private repositories.
When evaluating a system that I plan to use for the foreseeable future, there are a number of factors I take into account. I want:
- a relatively simple installation process
- to know what the dependencies are and how to install them
- to have a clear path for how updates will be installed
- to know where all the pieces live so that I can back everything up
- to be able to switch to another solution in the future if the current system no longer suits my needs or if the project changes direction
After installing the Gogs binary, it was very clear to me how everything related, and it turns out it passes all these tests.
Installing
First check that you have the prerequisites installed. It's pretty simple, you need a recent version of MySQL or Postgres, Git, and SSH. Create the database (they even include the SQL to create the database in the scripts folder) and create a user that has full access to the database.
Create a "git" Linux user which will be used for the incoming SSH connections as well as will run the binary.
Download the zipped binary, extract it into a folder, make sure the git user owns the whole folder, and run ./gogs web
as the instructions say. It said it was listening on port 3000, so I then went to my nginx config and set up a reverse proxy, so that I can use my existing wildcard SSL certificate.
My nginx config looks like the below:
server {
listen 443 ssl;
server_name code.pin13.net;
ssl_certificate /web/conf/ssl/wildcard.pin13.net.crt;
ssl_certificate_key /web/conf/ssl/server.key;
location / {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect default;
proxy_set_header Host $http_host;
}
}
You can also configure an init script so that the system starts the binary on boot. Save this as /etc/init/gogs.conf
description "gogs"
start on runlevel [2345]
stop on runlevel [016]
respawn
exec sudo -u git /web/sites/gogs/gogs web >> /web/sites/gogs/log.txt 2>&1
Now you can stop the binary in your terminal and run sudo service gogs start
instead.
Then I visited the site with its friendly URL, https://code.pin13.net and was presented with a configuration screen. This screen was straightforward, it lets you enter the paths to use to store the git repos, and asks what web address you want to publish, in case you've done what I've done and installed it behind a reverse proxy. After hitting "save", it creates a config.ini and then launches you into the app!
Upgrading
Obviously I haven't had to do this yet, but upgrades look pretty straightforward. Essentially you download the new binary, and copy the data and config folders into the new version's folder. I assume the database migrations will happen automatically or I will be presented with a simple walkthrough.
Backing Things Up
There's no point in self-hosting your code unless you also have a backup plan. If you don't have a plan, you might as well be using Bitbucket and let them handle that for you.
There are essentially three things to back up. You'll need to back up your MySQL or Postgres database, but since you had to install it, you probably already have a way to do that. I run a nightly mysqldump command that creates a sql file.
mysqldump --skip-extended-insert -u backup gogs > /web/backups/gogs.sql
You'll also need to back up the configuration, so you might as well back up the whole folder that was extracted from the download.
Lastly you need to back up the actual git repositories. The great part is that Gogs just creates .git folders (which is also how SSH accesses them) so you can just back up the entire git repo directory.
Migrating Away
If for some reason in the future I decide to stop using Gogs, I have a relatively simple path forward. All the git repos are already regular git repos on disk, so worst case I can simply move those to another server and continue pushing to them as normal.
Migrating the issues and other non-git data is of course not as straightforward. However, the database schema is relatively simple, so I can definitely envision writing an export or conversion script that pulls the data out of the database as a last resort.
Background
I've always used GitHub for my public repos, and will continue to do so. GitHub has done an amazing job at creating ways for people to collaborate, and I don't want to lose that by leaving GitHub completely. However, I am not willing to pay what would be quite a high monthly cost for my own personal private repos.
Previously, I had installed Gitlab back when it still required gitolite. A year or so later I checked back and there had been some significant changes, enough that doing an in-place upgrade was going to be prohibitively complicated. So I installed another instance next to the existing one, intending to move things over. By the time I thought about moving things to it, there had been another round of fundamental changes so I put the whole thought on hold. Later, I started using Bitbucket for my private repos, which was simple enough.
I've been trying to move everything off this old VPS that I've had which is now way out of date and should really be shut down. Two of the more complicated things on it were the two Gitlab instances. This meant that I kept putting off the whole project. Finally today, I was inspired to actually do something about it, and started looking into Gitlab again.
Gitlab fails almost all of the above tests. The Docker image abstracts things away too much, but installing the components manually is ridiculously cumbersome. The package version assumes it will be the only thing running on the server, so I can't really run another Nginx or Ruby alongside it.
I was pleasantly surprised by the simple installation procedure of Gogs, and was glad that it made me install a database myself, so that it was less of a black box to me. It's also a bonus that the interface is simple and similar to GitHub. I'm looking forward to hosting my repos myself!