Edit 2018-07-14

Following Reddit’s comments I made an Ansible role that follows this tutorial. It’s available on my github

In the light of recent Github acquisition and my Gitlab account running slow, I decided to give it a go with a self-hosted web git service named Gitea. It is a more-intense developed fork of gogs. It’s Open Source, cross-platform and very lightweight.

The real challenge is not installing it, but configuring it properly. The official documentation is lacking some key components - in particular regarding configuring reversed proxy in webserver. Below I share my experience and configuration that lead me to having working Gitea installation.

This article is just a stripped-down version of official documentation that you can find here. It’s purpose is not to substitute official documentation, but to provide short how-to example.

As the time of writing this tutorial is valid up to version 1.4.3. YMMV.

Prerequisites

This tutorial assumes you have Debian-based LAMP server running with Letsencrypt SSL certificate installed. Your machine has properly configured DNS pointing to yourdomain.com.

Getting gitea

Various options:

Docker

downloading binary (recommended, easiest)

distribution package (most probably broken)

from source

I used to build Gitea from Github source but there is no real benefit from this approach unless you plan to hack the code and run modified version or you are paranoid that developers might inject code into binaries.

In order to build, you have to first install Go language (which is not an easy task, since distribution version is most probably outdated), configure environmental variables, then fetch git repo, checkout to selected branch and finally build with TAGS="bindata" make generate build . The whole process takes time and the final product is the same binary that you can just download from Gitea page… So if you just want to get it up and running, go with binary option.

Installing Gitea

We will:

Add appropriate user that will run service (so it won’t be run as root) Download binary into shared folder Prepare directory structure for repos, config and log files with proper permissions Populate initial app.ini configuration file. Create linux deamon to run on startup Configure reverse proxy in apache Use Letsencrypt SSL cert Run it! Profit

All commands below are run as root.

Add user

Create user to run Gitea (ex. git)

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

Download binary

Choose the version from downloads page. In this tutorialI will use latest stable version as the time of writing:

wget -O /usr/local/bin/gitea https://dl.gitea.io/gitea/1.4.3/gitea-1.4.3-linux-amd64 chown git:git /usr/local/bin/gitea chmod 755 /usr/local/bin/gitea

Prepare directory structure for repos, config and log files with proper permissions

Official documentation creates folder for metadata in /var/lib and puts config file in /etc, but for the sake of portability and potential backups I put everything in one folder /opt/gitea:

mkdir -p /opt/gitea/ { custom,data,indexers,public,log } touch /opt/gitea/app.ini chown git:git -R /opt/gitea chmod 750 /opt/gitea/ { data,indexers,log } chmod 640 /opt/gitea/app.ini

Populate initial app.ini configuration file.

cat /opt/gitea/app.ini

APP_NAME = Gitea: Git with a cup of tea || by mDfRg RUN_USER = git RUN_MODE = prod [server] PROTOCOL = https ROOT_URL = https://git.yourdomain.com/ CERT_FILE = /opt/gitea/keys/fullchain.pem KEY_FILE = /opt/gitea/keys/privkey.pem SSH_DOMAIN = git.yourdomain.com DOMAIN = git.yourdomain.com HTTP_PORT = 3000 DISABLE_SSH = false SSH_PORT = 22 LFS_START_SERVER = true LFS_CONTENT_PATH = /opt/gitea/LFS

Notice the CERT_FILE and KEY_FILE . I will cover that later.

Create linux deamon to run on startup

cat /etc/systemd/system/gitea.service

[Unit] Description = Gitea (Git with a cup of tea) After = syslog.target After = network.target After = mysqld.service #After=postgresql.service #After=memcached.service #After=redis.service [Service] # Modify these two values and uncomment them if you have # repos with lots of files and get an HTTP error 500 because # of that ### #LimitMEMLOCK=infinity #LimitNOFILE=65535 RestartSec = 2s Type = simple User = git Group = git WorkingDirectory = /opt/gitea/ ExecStart = /usr/local/bin/gitea web -c /opt/gitea/app.ini Restart = always Environment = USER=git HOME=/home/git GITEA_WORK_DIR=/opt/gitea # If you want to bind Gitea to a port below 1024 uncomment # the two values below ### #CapabilityBoundingSet=CAP_NET_BIND_SERVICE #AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy = multi-user.target

Configure reverse proxy in apache

cat /etc/apache2/sites-available/git.conf

< VirtualHost *:443 > SSLProxyEngine on SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off ProxyPassReverseCookieDomain localhost git.yourdomain.com SSLCertificateFile /opt/gitea/keys/fullchain.pem SSLCertificateKeyFile /opt/gitea/keys/privkey.pem ServerAdmin me@mindefrag.net ServerName git.yourdomain.com ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined < Proxy * > Order allow,deny Allow from all </ Proxy > ProxyPass / https://127.0.0.1:3000/ ProxyPassReverse / https://127.0.0.1:3000/ </ VirtualHost >

Use Letsencrypt SSL cert

Unfortunately, linking to privkey and fullchain in letsenrypt directory produces an error, so as a workaround I just did:

cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /opt/gitea/keys cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /opt/gitea/keys

The downside of it is, you have to repeat it every time certbot renews the certificate (or setup a cronjob).

Run it!

Finally, run service gitea start . service gitea status should look like:

● gitea.service - Gitea ( Git with a cup of tea ) Loaded: loaded ( /etc/systemd/system/gitea.service ; disabled ) Active: active ( running ) since 2018-07-06 12:18:18 CEST ; 14min ago Main PID: 24877 ( gitea ) CGroup: /system.slice/gitea.service └─24877 /usr/local/bin/gitea web -c /opt/gitea/app.ini

And if you enter https://git.yourdomain.com you should see the configuration page:

Provided that you added appropriate user and database, just fill the forms and hit install Gitea. I choose to have my repositories under /opt/gitea/repos because of mentioned reasons (backup and portability).

Final words

Gitea is not an super easy service to configure, but if you know what you’re doing, it’s only about setting some configuration files. The selling point is, it’s a set-and-forget kind of setup. If you wish to upgrade, you just redownload newer binary into the /usr/local/bin/ folder and restart the service. Its memory and CPU footprint is tiny tiny and the joy of having own git repository that is always available is extremely satisfying!