Sections

  1. Introduction
  2. Reasons to host your own server
  3. Setting up the server
  4. Installing prerequisites
  5. Installing Gitea
  6. NGINX configuration and SSL/TLS
  7. Finishing Gitea Installation
  8. Resources

Introduction

The most popular repository out there is probably Github. Everyone knows what Github is. It’s famous for a reason. It’s easy to use, has useful features such as web hooks, and is free. However, Github isn’t the only way to use Git. There are many alternatives out there such as BitBucket, GitLab. These solutions are nice because they’re easy to use and all the data is hosted on the cloud, so you don’t have to worry about losing your data. Although there are many readily available solutions out there for version control, there are still times where you might want to have a bit more control and host your own git server.

Reasons to host your own git server

While cloud solutions are easy to use, there are definitely reasons to host your own git server. For starters, maybe your code base is more private, and you or the company you work for doesn’t want it out in the wild. In this case, hosting your own git server lets you keep all the data in house while giving you the convenience and features of a cloud based solution. Another compelling reason is for privacy and control. Personally, I’m a big fan of self hosted solutions because I like being in control of my digital data/life. Nowadays, the big tech companies know so much about you that every little bit of privacy you can control is always nice.

Setting up the server

You can host a git server with many different server configurations, with the most common being a physical server you have access to and cloud VPS services that let you spin up virtual machines. In this example I am going to be using the second type of solution. There are many companies out there providing cloud VPS services, but the two that I like the best are DigitalOcean and Linode. I feel that these two companies both provide quality service for a good price. I detailed how to set up a VPS and domain name on DigitalOcean in my previous post, and the overall process is very similar with Linode too.

Installing prerequisites

For our git server solution, I’m going to be Gitea. There are also many solutions out there for hosting your own git server such as Gitlab or a plain ssh server. I am using Gitea mainly because it is very light weight and has most of the cool functionality that Github provides such as support for CI/CD pipelines via webhooks. Additionally, Gitea provides a Docker image, so you can set it up very easily if you want to. In this post I’m going to be going over the bare metal installation process.

Before we can install Gitea, we’ll have to install a database for Gitea to use. Gitea support both MySQL and PostgreSQL and has pretty good documentation on the whole install process. We will be using MySQL. Let’s start by installing the MySQL server through the terminal:

sudo apt install mysql-server

Next, let us set up the user account and databse for Gitea by first firing up the mysql command line:

sudo mysql

Now we will create a user:

CREATE USER 'gitea' IDENTIFIED BY 'password';

Of course, you should change password to whatever your actual password will be. After the user has been created, we can create the database that Gitea will use:

CREATE DATABASE giteadb CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';

To tie it all together, we’ll give the gitea user we just created the permissions needed to use giteadb:

GRANT ALL PRIVILEGES ON giteadb.* TO 'gitea';
FLUSH PRIVILEGES;

Now that we have the user and database set up, we can exit the mysql command line and test the connection to the database with the user we just created:

exit
mysql -u gitea -p giteadb

This will prompt you for the password you used to create the user. After you put in the password, if everything is successful, you should be back in the mysql command line as the gitea user. You can now exit the mysql command line and move onto the next step:

exit

Installing Gitea

Now that we have everything ready, we can install Gitea! Today, we’re going to be installing the Gitea binary file as that is usually more up to date and less modified than the packages found in your linux distribution’s package source. First we’ll have to get the binary from the Gitea download page. To find the link to the latest download, click on the download page link, and then click on the topmost version (which is currently 1.12 at the time of writing). After you click into the folder, we want to find the file that ends in linux-amd64, which in this case would be gitea-1.12-linux-amd64. This is the version that we want to use, so right click the link and copy the link location. Now we can download the file on our server:

wget -O gitea https://dl.gitea.io/gitea/1.12/gitea-1.12-linux-amd64
chmod +x gitea

The second line sets the binary file we just downloaded as an executable. Just to be safe, let’s verify that the downloaded file hasn’t been tampered with by verifying the signature. The link to the signature will be in the same location as the binary file, usually right under it. It has the same name as the binary file, but end in .asc. In this case the name of the file that you want to get the link from is gitea-1.12-linux-amd64.asc:

wget -O key.asc https://dl.gitea.io/gitea/1.12/gitea-1.12-linux-amd64.asc
gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
gpg --verify key.asc gitea

After you try to verify the signature, the third line of the output should be:

Good signature from "Teabot <teabot@gitea.io>" [unknown]

This means that the file has not been tampered with. Next, we’ll create a user on the linux system called git for Gitea to use:

sudo adduser \
   --system \
   --shell /bin/bash \
   --gecos 'Git Version Control' \
   --group \
   --disabled-password \
   --home /home/git \
   git

After the user has been created, we can manually create the directory structure needed by Gitea:

sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo chown -R git:git /var/lib/gitea/
sudo chmod -R 750 /var/lib/gitea/
sudo mkdir /etc/gitea
sudo chown root:git /etc/gitea
sudo chmod 770 /etc/gitea

Now that the directory is all set up for Gitea, let’s copy the Gitea binary file we just downloaded to the right place to be used:

sudo cp gitea /usr/local/bin/gitea

We’re almost there. After Gitea is installed correctly, we need to install a system service so that the server will automatically start Gitea when it boots up. We can do this by using systemd:

sudo vim /etc/systemd/system/gitea.service

This will be a new file, we can start editing by pressing the i key. Now we can paste the contents below into the new file we’re editing:

[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
Requires=mysql.service
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea

[Install]
WantedBy=multi-user.target

If you can’t paste correctly, use Ctrl + Shift + v. Afterwards, type :wq and hit enter to save and exit the text editor. Now we can reload services and start the Gitea service:

sudo systemctl daemon-reload
sudo systemctl enable gitea.service
sudo systemctl start gitea.service

Gitea is now installed correctly and is listening on port 3000!

NGINX configuration and SSL/TLS

We need to secure the connection to the git server by enabling SSL/TLS. We can do this using certbot and NGINX. Let’s start by getting the certificates using certbot:

sudo apt install certbot
sudo certbot certonly --standalone

Follow the prompts that show up and put in the domain name you’re using. In this case I’m going to be using a subdomain like git.yourdomain.com. Let’s install NGINX and configure out SSL certifications:

sudo apt install nginx

Let’s remove the default configuration file and make a new one:

sudo rm default
sudo vim git.conf

This will open the new file in vim. We can start editing by pressing i. Now we’ll set up the necessary server blocks by pasting the following:

server {
    listen 80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name gittest.fourberries.com;

    ssl_certificate /etc/letsencrypt/live/git.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/git.yourdomain.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/git.yourdomain.com/chain.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header Referrer-Policy no-referrer;
    add_header X-Frame-Options "SAMEORIGIN";

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:3000;
        
    }
}

We can check that this configuration has no syntax errors like this:

sudo nginx -t

If this doesn’t return as successful, double check the server blocks you pasted before continuing. Once the server blocks are configured correctly, let’s enable them:

sudo systemctl restart nginx

Now you should be able to connect to your server by typing in your domain name in the browser!

Gitea Success

Finishing Gitea installation

We have just one step left. We need to set up the Gitea installation through the browser. Navigate to the domain you installed Gitea on and click on Sign In to start the configuration.

Web Config Page

Here are a few of the fields you need to pay attention to and change based on how we set it up:

  1. Username: gitea (Or whatever you put in earlier when we were setting up MySQL)
  2. Password: The password you used when creating the MySQL user
  3. Database Name: giteadb (Or whatever you put for database name)
  4. Charset: utf8mb4
  5. SSH Server Domain: git.yourdomain.com

After the settings are configured and look correct for your setup, go ahead and hit install Gitea. It’s okay if it spits you out to a page that can’t connect, we’re going to fix this problem. To do so we’ll have to edit the configuration file:

sudo vim /etc/gitea/app.ini

This is the file with all the configuration information, if you messed something up earlier, you can correct it here. We’ll be changing the ROOT_URL under [server]. To do this hit i to start editing and change the text after ROOT_URL = to your domain name:

ROOT_URL = https://git.yourdomain.com/

Remember to include the https because we set up SSL/TLS earlier. After you’ve finished this step, you’re personal Git server is set up and ready to go! You can now create an account and set up a repository like you would on Github!

Resources

  1. Database preparation (https://docs.gitea.io/en-us/database-prep/)
  2. Installing Gitea (https://docs.gitea.io/en-us/install-from-binary/)