← Wiki

Gitea

Gitea is a self-hosted git-driven VCS and webapp. It is relatively full-featured and self-hostable.

This details deploying Gitea behind nginx as a reverse proxy, but any webserver, like Caddy, would also do.

Requirements #

Gitea requires curl, git, and also requires a DB store. If you care about high performance, I would use postgresql here, but sqlite3 or mariadb are also fine. Gitea allows you to have it manage an sshd, but it can also use your system's. We use the latter setup here.

Configuration and Setup #

The configuration for git.asperger.pro starts with /etc/gitea/conf/app.ini. /etc/gitea/app.ini is default and is a huge reference of possible options, so I keep it.

; /etc/gitea/conf/app.ini
; minimal for self-hosting 

; whatever works
APP_NAME  = git.asperger.pro - hobbyist code repos
; daemon user
RUN_USER  = git
RUN_MODE  = prod 
WORK_PATH = /var/lib/gitea

[server]
PROTOCOL         = http
HTTP_ADDR        = 127.0.0.1
; or some other port to be used later
HTTP_PORT        = 3333
DOMAIN           = git.asperger.pro
ROOT_URL         = https://git.asperger.pro
SSH_DOMAIN       = asperger.pro
; we use the system sshd
START_SSH_SERVER = false
SSH_PORT         = 22 
DISABLE_SSH      = false 
OFFLINE_MODE     = true
LFS_START_SERVER = true 
LFS_JWT_SECRET   = ;; gitea generate secret LFS_JWT_SECRET 
APP_DATA_PATH    = /var/lib/gitea/data

[database]
DB_TYPE  = postgres
HOST     = /run/postgresql
NAME     = gitea
USER     = git
SCHEMA   = public

[repository]
ROOT                   = /var/lib/gitea/repositories
DEFAULT_BRANCH         = master
DEFAULT_PRIVATE        = public
; default-ish
DEFAULT_REPO_UNITS     = repo.code,repo.releases,repo.issues,repo.wiki

[security]
INSTALL_LOCK                  = true
SECRET_KEY                    = ;; gitea generate secret SECRET_KEY 
INTERNAL_TOKEN                = ;; gitea generate secret INTERNAL_TOKEN
; OWASP 
PASSWORD_HASH_ALGO            = argon2
REVERSE_PROXY_LIMIT           =
 1
; localhost only 
REVERSE_PROXY_TRUSTED_PROXIES = 127.0.0.1/32,::1/128

[service]
; minimal configs here for single-player mode
DISABLE_REGISTRATION              = true
REQUIRE_SIGNIN_VIEW               = false
ENABLE_NOTIFY_MAIL                = false
DEFAULT_KEEP_EMAIL_PRIVATE        = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
ENABLE_CAPTCHA                    = false
SHOW_MILESTONES_DASHBOARD_PAGE    = false

[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[federation]
ENABLED = false

[packages]
ENABLED = false

[actions]
ENABLED = false

[mirror]
ENABLED = false

[migrations]
ALLOWED_DOMAINS = github.com,codeberg.org,gitlab.com

[indexer]
REPO_INDEXER_ENABLED = true
ISSUE_INDEXER_TYPE   = bleve

[cron.update_checker]
; set to false, we let the package manager do this
ENABLED = false

[metrics]
ENABLED = false

[log]
MODE      = console
LEVEL     = info
ROOT_PATH = /var/log/gitea

[ui]
DEFAULT_THEME = gitea-auto

For each of LFS_JWT_TOKEN, SECRET_KEY, and INTERNAL_TOKEN above, you will have to provide generated secrets:

sudo -u git gitea --config /etc/gitea/conf/app.ini generate LFS_JWT_TOKEN
sudo -u git gitea --config /etc/gitea/conf/app.ini generate secret SECRET_KEY
sudo -u git gitea --config /etc/gitea/conf/app.ini generate secret INTERNAL_TOKEN

Database #

Then we create a db user by running psql as the db owner user:

CREATE ROLE git LOGIN;
CREATE DATABASE gitea OWNER git ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0;

SSH #

This is important. If you haven't set up sshd so that is has fail2ban or some other banhammer automater, go and do that FIRST.

Are we good? Okay. Append or modify sshd_config to add the git daemon user and its group to the whitelisted users.

# /etc/ssh/sshd_config
# [...]
# suppose the users we want are here, we append 'git' to these
AllowUsers username git

# [...]

Match User git
    AuthorizedKeysFile /var/lib/gitea/.ssh/authorized_keys
    PasswordAuthentication no
    AllowTcpForwarding no
    AllowAgentForwarding no
    X11Forwarding no
    PermitTTY no

Then, test and restart sshd for your system.

In this case, git has an authorized_keys file generated by the gitea app, which will look something like:

command="/usr/bin/gitea --config=/etc/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,
no-agent-forwarding,no-pty,no-user-rc,restrict ssh-rsa AAAA[...] user-1

We can further lock down the git daemon user by disabling password all together, but shadowed:

passwd -l git
usermod -p '*' git

nginx setup #

The reverse proxy for the site is pretty standard, beside the larger than average expected payload:

server {
    listen 443 ssl;
    server_name git.asperger.pro;

    client_max_body_size 512M;

    location / {
        proxy_pass http://localhost:3333/;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }

server {
    listen 80;
    return 404;
}

Then, test and reload:

nginx -t 
nginx -s reload

You can then use certbot and append this to your cert (--expand command flag helps).

Making An Admin User #

Finally, we can now produce an admin user for this system:

sudo -u git gitea --config /etc/gitea/conf/app.ini admin user create \
--admin --user-type individual \
--username hpcdisrespecter \
--email  hpcdisrespecter@asperger.pro \
--password <Your_secret>

You are now good to go to start the gitea daemon, upload your public key to your account, and begin working.

Happy Hacking :)