Gitea is a self-hosted Git service with a functionality similar to GitHub, GitLab and BitBucket. It’s a fork of Gogs and uses the same MIT licence. As most applications written in Go it’s easy to install.


For this guide you should be familiar with the basic concepts of


You’ll need your MySQL credentials. Get them with my_print_defaults:

[isabell@stardust ~]$ my_print_defaults client
[isabell@stardust ~]$

We need a database:

[isabell@stardust ~]$ mysql -e "CREATE DATABASE ${USER}_gitea"
[isabell@stardust ~]$

We can use the uberspace or your own domain:

[isabell@stardust ~]$ uberspace web domain list
[isabell@stardust ~]$


Download and verify

Check current version of Gitea at releases page.

[isabell@stardust ~]$ VERSION=1.14.4
[isabell@stardust ~]$ mkdir -p ~/gitea
[isabell@stardust ~]$ wget -O ~/gitea/gitea${VERSION}/gitea-${VERSION}-linux-amd64
--2020-06-01 21:00:31--
Resolving (
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: [...]
HTTP request sent, awaiting response... 200 OK
Length: 83243800 (79M) [application/octet-stream]
Saving to: ‘/home/isabell/gitea/gitea’

100%[====================================================================================================================>] 83,243,800  14.9MB/s   in 9.8s

2020-06-01 21:00:42 (8.11 MB/s) - ‘/home/isabell/gitea/gitea’ saved [83243800/83243800]
[isabell@stardust ~]$ wget -O ~/gitea/gitea.asc${VERSION}/gitea-${VERSION}-linux-amd64.asc
Resolving (
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: [...]
HTTP request sent, awaiting response... 200 OK
Length: 833 [application/octet-stream]
Saving to: ‘/home/isabell/gitea/gitea.asc’

100%[====================================================================================================================>] 833         --.-K/s   in 0s

2020-06-01 21:03:17 (9.01 MB/s) - ‘/home/isabell/gitea/gitea.asc’ saved [833/833]
[isabell@stardust ~]$

We use gpg to download the pgp key and verify our download.

[isabell@stardust ~]$ gpg --keyserver --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
gpg: directory `/home/isabell/.gnupg' created
gpg: new configuration file `/home/isabell/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/isabell/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/isabell/.gnupg/secring.gpg' created
gpg: keyring `/home/isabell/.gnupg/pubring.gpg' created
gpg: requesting key EC1592E2 from hkp server
gpg: /home/isabell/.gnupg/trustdb.gpg: trustdb created
gpg: key EC1592E2: public key "Teabot <>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
[isabell@stardust ~]$ gpg --verify ~/gitea/gitea.asc ~/gitea/gitea
gpg: Signature made Sat 09 May 2020 10:19:06 PM CEST using RSA key ID 9753F4B0
gpg: Good signature from "Teabot <>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 7C9E 6815 2594 6888 62D6  2AF6 2D9A E806 EC15 92E2
     Subkey fingerprint: CC64 B1DB 67AB BEEC AB24  B645 5FC3 4632 9753 F4B0
[isabell@stardust ~]$

If the verification is fine, we get a gpg: Good signature from "Teabot <>" line and we make the bin executable.

[isabell@stardust ~]$ chmod u+x ~/gitea/gitea
[isabell@stardust ~]$


Gitea configuration file

Before we write the configuration we need the MySQL database password from earlier as well as some random characters as security key.

[isabell@stardust ~]$ pwgen 32 1
[isabell@stardust ~]$

Create a custom directory.

[isabell@stardust ~]$ mkdir -p ~/gitea/custom/conf/
[isabell@stardust ~]$

The minimum set of ~/gitea/custom/conf/app.ini is:

HTTP_PORT = 9000
ROOT_URL = https://%(DOMAIN)s


When using this, we have to finish the installation via gitea web service This is exposed without any password request. We improve the configuration with some modifications, e.g.:

  • Filling the database access data that we would otherwise enter in the web installation step. ([database] section)
  • As security feature we lock the web installation and change the default password complexity to allow well to remember and secure passwords. (See XKCD No. 936 and Explained XKCD No. 936 for the math behind it. 😉 [security] section)
  • We disallow public registration and set some privacy settings. ([service] section)

For more information about the possibilities and configuration options see the Gitea documentation and the Gitea configuration sample.


Replace isabell with your username, fill the database password PASSWD = with yours and enter the generated random into SECRET_KEY =.

APP_NAME = Gitea
RUN_USER = isabell
RUN_MODE = prod ; Either "dev", "prod" or "test", default is "dev".

HTTP_PORT            = 9000
DOMAIN               =
ROOT_URL             = https://%(DOMAIN)s
OFFLINE_MODE         = true ; privacy option.

DB_TYPE  = mysql
HOST     =
NAME     = isabell_gitea
USER     = isabell
SSL_MODE = disable

INSTALL_LOCK        = true

DISABLE_REGISTRATION       = true ; security option, only admins can create new users.
DEFAULT_ORG_VISIBILITY     = private ; [public, limited, private]
NO_REPLY_ADDRESS           =

ENABLED     = true
MAILER_TYPE = sendmail
FROM        =

Gitea using external renderer (optional)

We can install an extra external rendering extension AsciiDoc.

[isabell@stardust ~]$ gem install asciidoctor
Fetching asciidoctor-2.0.10.gem
WARNING:  You don't have /home/isabell/.gem/ruby/2.7.0/bin in your PATH,
        gem executables will not run.
Successfully installed asciidoctor-2.0.10
1 gem installed
[isabell@stardust ~]$


Don’t be irritated by the warning that the bin folder isn’t in the path. Uberspace is taking care of it. You can check with [isabell@stardust ~]$ which asciidoctor.

Now we have to append the config file ~/gitea/custom/conf/app.ini with:

ENABLED = true
FILE_EXTENSIONS = .adoc,.asciidoc
RENDER_COMMAND = "asciidoctor -e -a leveloffset=-1 --out-file=- -"

Gitea initialization

Above we locked the registration and the web installation feature, so this service will never be exposed in an insecure way to the internet. So we have to do the provided steps to create the database layout and generate security keys manually.

[isabell@stardust ~]$ ~/gitea/gitea migrate
... a lot of console output about the database commands.
[isabell@stardust ~]$ ~/gitea/gitea generate secret INTERNAL_TOKEN
[isabell@stardust ~]$ ~/gitea/gitea generate secret SECRET_KEY
[isabell@stardust ~]$ ~/gitea/gitea generate secret JWT_SECRET
[isabell@stardust ~]$ ~/gitea/gitea generate secret LFS_JWT_SECRET
[isabell@stardust ~]$

Gitea admin user

We generate a safe password for the admin user. We use pwgen to create one set of 16 characters and write them into a variable to use it during the next two steps.

[isabell@stardust ~]$ ADMPWD=$(pwgen 16 1)
[isabell@stardust ~]$

Now we create an admin user via Gitea command line. Gitea isn’t allowing admin as name. We choose adminuser and the generated password from above. To ensure we remember the password beyond this installation session we store the password in a text file.

[isabell@stardust ~]$ ~/gitea/gitea admin user create --username adminuser --password ${ADMPWD} --email ${USER} --admin
[isabell@stardust ~]$
New user 'adminuser' has been successfully created!
[isabell@stardust ~]$ echo "usr: adminuser" > ~/gitea/gitea-admin.txt
[isabell@stardust ~]$ echo "pwd: ${ADMPWD}" >> ~/gitea/gitea-admin.txt
[isabell@stardust ~]$

Gitea ssh setup (optional)

Gitea can manage the ssh keys. To use this feature we have to link the ssh folder into the gitea folder.

[isabell@stardust ~]$ ln -s ~/.ssh ~/gitea/.ssh
[isabell@stardust ~]$

Now our Gitea users can add their ssh keys via the menu in the up right corner: -> settings -> tab: SSH/GPG Keys -> Add Key. Gitea is automatically writing a ssh key command into the /home/isabell/.ssh/authorized_keys file. The key line is something similar like:

command="/home/isabell/gitea/gitea --config='/home/isabell/gitea/custom/conf/app.ini' serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC... youruser@yourhost

If we’re using the same ssh key for auth to uberspace and Gitea, we need to modify the server /home/isabell/.ssh/authorized_keys file.

command="if [ -t 0 ]; then bash; elif [[ ${SSH_ORIGINAL_COMMAND} =~ ^(scp|rsync|mysqldump).* ]]; then eval ${SSH_ORIGINAL_COMMAND}; else /home/isabell/gitea/gitea serv key-1 --config='/home/isabell/gitea/custom/conf/app.ini'; fi",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-...


Be careful to keep the key number key-X, keep your key ssh-... and change the username isabell to yours.


You can still use the Uberspace dashboard to add ssh keys.

To interact with Gitea at our local machine like git clone we configure the /home/localuser/.ssh/config file for our local machine with the git ssh key.

    User isabell
    IdentityFile ~/.ssh/id_your_git_key
    IdentitiesOnly yes

Finishing installation

Uberspace daemon for Gitea

Create a file ~/etc/services.d/gitea.ini for the service …

command=%(ENV_HOME)s/gitea/gitea web

After creating the configuration, tell supervisord to refresh its configuration and start the service:

[isabell@stardust ~]$ supervisorctl reread
SERVICE: available
[isabell@stardust ~]$ supervisorctl update
SERVICE: added process group
[isabell@stardust ~]$ supervisorctl status
SERVICE                            RUNNING   pid 26020, uptime 0:03:14
[isabell@stardust ~]$


The status of gitea must be RUNNING. If not, check the configuration file ~/gitea/custom/conf/app.ini.

Uberspace web backend


gitea is running on port 9000.

To make the application accessible from the outside, configure a web backend:

[isabell@stardust ~]$ uberspace web backend set / --http --port <port>
Set backend for / to port <port>; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".
[isabell@stardust ~]$


If we run the service under a domain subfolder aka prefix, you need to append the above command like uberspace web backend set --http --port 9000 --remove-prefix.

Done. We can point our browser to

Installed files and folders are:

  • ~/gitea
  • ~/etc/services.d/gitea.ini
  • ~/.gem/ruby/2.7.0/*/asciidoctor*, if AsciiDoctor is installed.



Check the update feed or releases page regularly to stay informed about the newest version.

To update do:

  • Stop the application supervisorctl stop gitea
  • Do the download and verify part from above.
  • Check if you have to modify the config file. (See documentation and the file sample.)
  • Do the application migration: ~/gitea/gitea migrate
  • Start the application supervisorctl start gitea
  • Check if the application is running supervisorctl status gitea

Tested with Gitea 1.14.4, Uberspace

Written by: Frank ℤisko <>