Host your own Git Server with Gogs

Just like many other developers I host my open source projects on GitHub. It is free, easy to get started, and straight forward to use. Yet, I have some projects that I want to keep private for now. Instead of hosting them on GitHub I thought it might be fun to create my own Git server.

Picking a server

Since I am only hosting some private projects I do not need a high performance server to support several hundreds of users or repositories. To keep the costs as low as possible I have decided to go with an Amazon EC2 t2.nano instance. If you do not want to host your data on AWS any small linux system, e.g., Raspberry Pi will suffice as well.

Costs

At the time of this writing the US Oregon data center had the lowest prices for an EC2 t2.nano instance (see table below).

Item Price
EC2 t2.nano instance $ 0.0065 / h
1 GB EBS gp2 storage $ 0.10 / month

Let’s say we keep this instance running 24/7 then the costs will add up to $ 66.54 per year (($ 0.0065 * 24h * 365 days) + (8GB * $ 0.10 * 12 months)). Yet, it is highly unlikely that I will be pushing and pulling code 24/7. Depending on my current usage I can get away with as little as 1h / day adding up to $ 11.9725 (($ 0.0065 * 365 days) + (8GB * $ 0.10 * 12 months)). Way cheaper than the $ 7 / month price tag for Github Personal that adds up to $ 84 a year.

Here is an overview of the aforementioned configurations compared to Github Personal.

t2.nano 1h/day t2.nano 24/7 Github Personal
$ 11.9725 $ 66.54 $ 84.00

With the AWS Free Tier you can even get away with $ 0 for the first 12 months if you use a t2.micro instance. Just sayin’.

Please note: The first GB of data transfer out (e.g., git pull) of your EC2 per month is free. For every additional GB you pay $ 0.09. That is only a problem if you have a huge repository and you pull very often. Inbound traffic (e.g., git push) is for free.

Git server options

There are several ways to host your own Git server. You either go with a plain Git server without frontend or pick one of the pre-build Git server packages such as Gitlab. A frontend might come in handy if you do not want to interact with a CLI all the time.

Initially, I thought I could use Gitlab, one of the most popular Git server packages. Unfortunately, it uses a lot of resources that made it unfeasible to run on a t2.nano instance. Even a t2.micro instance can barely run Gitlab and requires some additional tweaks, e.g., a 3GB swap file and therefore additional EBS storage to compensate. Fortunately, I have stumbled upon a simple alternative called Gogs.

Gogs is a lightweight, open source Git server package written in Go that only uses few resources. The installation is straight forward and only requires few steps to get it up and running.

Step 1: Set up and launch the EC2 instance

Please sign in to your AWS Management Console and switch to the EC2 Service. Then create a new t2.nano (or t2.micro instance if you are on the Free Tier) with Ubuntu Server 14.04 LTS (HVM). During the setup of the instance please add port 80 to the inbound rules of your security group for the instance so that you can connect to the Gogs frontend after installation.

Step 2: Install dependencies

Now that your instance is up and running please connect to it via ssh using either the public IP address or DNS using your private key file.

ssh -i "Gogs.pem" ubuntu@<your public dns>

Then update your apt-get repository cache and install the following dependencies:

sudo apt-get update
sudo apt-get install -y wget unzip git

Step 3: Install Gogs

Before we start I suggest you create a new user (e.g., gogs) that will run Gogs and takes ownership of all git related files.

sudo useradd --system --create-home gogs

Now switch to the newly created user and the corresponding home directory.

sudo su gogs
cd ~

Now we need to download the latest build of Gogs (0.9.97 at the time of this writing) and unzip it.

wget https://dl.gogs.io/gogs_latest_linux_amd64.zip 
unzip gogs*.zip
rm -rf gogs*.zip

Then launch Gogs using:

./gogs/gogs web --port=80

Step 4: Configure Gogs

Now that Gogs is up and running we just need to do the inital setup. Therefore, open your browser and go to http://<public ip of your ec2 instance>. You should now see the Gogs configuration interface. If you cannot reach your EC2 instance you might have forgotten to open port 80 for inbound traffic when setting up your instance. In this case, head back to the EC2 Management Console and add port 80 (or whichever port you want) as inbound traffic rule for your security group.

Database Settings

If you do not have any preferred database management system I suggest you select SQLite as it requires no further setup. If you want to use another database management system such as MySQL, make sure you have a server up and running and the credentials at hand.

Application General Settings

Please change your Domain and Application URL to your EC2 instance public IP address or DNS.

Optional Settings

If you want your Gogs server to be able to send emails, e.g., password reset etc. you can enter the credentials etc. here.

I recommend to check Disable Self-registration and Enable Require Sign In to View Pages to prevent any public exposure of your repositories.

Admin Account Settings

Please choose a username and password for your admin account.

Step 5: Set up Gogs daemon

If you want Ubuntu to relaunch Gogs whenever you reboot your EC2 instance you just need to execute the following commands. Be sure to switch back to your ubuntu user before executing them.

# Download daemon script and make it executable

cd /etc/init.d 
sudo wget https://raw.githubusercontent.com/gogits/gogs/master/scripts/init/debian/gogs
sudo chmod +x gogs

# Change port

sudo sed -i -e 's/DAEMON_ARGS="web"/DAEMON_ARGS="web --port 80"/g' gogs

# Start service

sudo service gogs start

# Enable Gogs service on start up

sudo update-rc.d gogs defaults
sudo update-rc.d gogs enable

Final thoughts

Congratulations, your Gogs service is now ready to host your repositories.

There are some details I would like to make you aware of that are beyond the scope of this article.

HTTPS

At the moment all communication with the Gogs frontend is unencrypted. If you want to increase security you should consider enabling HTTPS on your EC2 instance.

Stopping the server

The public DNS and IP address of your EC2 instance are only valid as long as the instance is running. If you stop and restart your instance at a later time you will be assigned a new public DNS and IP address. That means you will be unable to push or pull any changes to or from Gogs unless you change the remote of your local repository to the new IP address. I have written a ruby script that leverages AWS API to change the remote of my repository whenever I want to push changes.

Amazon also offers a solution for this called Elastic IP that provides a static IP for your EC2 instance even if it is not running. The only problem is that Amazon charges you $ 0.005 / h whenever your instance is stopped which is almost as expensive as leaving the instance running.