How to install and configure Gitea a self-hosted Github-like service.

06/07/2018

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:

  1. Add appropriate user that will run service (so it won’t be run as root)
  2. Download binary into shared folder
  3. Prepare directory structure for repos, config and log files with proper permissions
  4. Populate initial app.ini configuration file.
  5. Create linux deamon to run on startup
  6. Configure reverse proxy in apache
  7. Use Letsencrypt SSL cert
  8. Run it!
  9. 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!