A community managed fork of gogs. This provides a github-like service for private repository use. Can be exposed and used publicly as well.

See Gitea Docker and Documentation and Gitea cheat sheet.



Docker Creation

If first-run, just launch the docker container to generate the correct configuration directory structure, afterwards you can re-create with a mapped git repository.

Docker Compose
  image: gitea/gitea:1
  restart: unless-stopped
    - USER_UID=1001
    - USER_GID=1001
    - RUN_MODE=prod
    - DISABLE_SSH=true
    - TZ=America/Los_Angeles
    - /data/services/gitea:/data
    - /data/git/gitea:/data/git/repositories
    - /etc/localtime:/etc/localtime:ro
  • Proxy will forward traffic to the container, so no ports need to be exposed.

Reverse Proxy Setup

Allows you to isolate your containers as well as wrap connections in SSL. See NGINX for more details. See Setup Base Proxy Control for basic proxy configuration.

See Gitea reverse proxy reference.


Adjust client_max_body_size to expected max size of data in a git change.

Using Subdomains

This requires a hard IP resolution. Hairpin NAT / NAT reflection will result in the web front working but git pull/push/clones failing. This is due to the way Gitea handles these requests with custom written handlers. Setup DNS resolution or add to hosts file.

0644 root root nginx/conf.d/reverse-proxy.conf
server {
  listen                 443 ssl http2;
  server_name            gitea.{DOMAIN} gitea;

  location / {
    proxy_pass           http://gitea:3000;
    client_max_body_size 1024m;

Using Subpaths

0644 root root nginx/conf.d/reverse-proxy.conf
server {
  location /gitea/ {
    proxy_pass           http://gitea:3000/;
    client_max_body_size 1024m;

Postgres Backend


Though there is some documentation on moving from sqlite3 to postgresql for gitea; all migrations seem to carry over artifacts that express different kinds of failures (like 500’s on issue updates).

Decide on a backend before committing any amount of metadata to Gitea.

0600 gitea gitea gitea/conf/app.ini
DB_TYPE = postgres
NAME = gitea


DB_PATH can be removed if not using sqlite3.

These options should be set during the Initial Setup.

Initial Setup

This will initially setup Gitea with restricted permissions during configuration:

Navigate to: {REVERSE PROXY URI}/install.


Gitea mirrors can automaticallly manage sync’ing with upstream mirrors if setup to do so. This will also allow for local forking of those mirrors for indiviudal use.

Importing Git Repositories

You can import other git repositories, including local and cloned ones:

  • Create an aptly named repository on Gitea, intialize it empty.

  • Push a mirror to this repository. All information will be retained.

  • Disable SSL verification if using self-signed certs.

Push mirror to Gitea.
cd my-repo-to-import
git push --mirror https://{IP}:3000/{USER}/{REPO}.git

As this is a mirror, you want to commit the git metadata and not just the files. The git repository is stored in /data/gitea/git as a standard git repository. Importing this way sets up the Gitea frontend database metadata for the project.

SSL Client Cert Authentication

A reverse proxy requiring SSL client certification authentication requires no change in the Gitea configuration.

See Git Configuration to configure your git client.


Migration Fails with pq: duplicate key value violates unique constraint "{DB TABLE}_pkey"

The initial migration ran past the default timeouts; or a previous migration/mirror of the same name failed during import. The DB sequential ID’s have a new ID but not created, so creating a new key results in a duplicate unique key.

2021/07/15 04:26:59 ...ules/task/migrate.go:67:func1() [E] DeleteRepository: repository does not exist [id: 705, uid: 33, owner_name: , name: ]
2021/07/15 04:26:59 modules/task/task.go:54:handle() [E] Run task failed: pq: duplicate key value violates unique constraint "topic_pkey"

Increase default timeout of mirroring:

0600 gitea gitea gitea/conf/app.ini
DEFAUlT = 360
MIGRATE = 1200
MIRROR  = 1200
CLONE   = 300
PULL    = 300
GC      = 60
Backup gitea and rebuild database tables.
gitea dump -c /etc/gitea/gitea.ini -t /data/gitea/tmp/ -V
gitea doctor recreate-table -c /etc/gitea/gitea.ini

Mirror Fails with ‘could not read Username’

The source repository is no longer public or has been deleted. Disable sync by setting Migration Interval to 0.

Example log when source repo is deleted/private.
2021/07/15 03:53:42 ...ces/mirror/mirror.go:242:runSync() [E] Failed to update mirror repository &{272 10 {USER} <nil> {REPO} {REPO} Mirror of{USER}/{REPO}.  2{USER}/{REPO} master 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 true false false true <nil> 0 map[] map[] [] <nil> false 0 <nil> false 0 <nil> 35674663 <nil> <nil> false false [] default  1582936274 1573978478}:
Stdout: Fetching origin

Stderr: fatal: could not read Username for '': terminal prompts disabled
error: Could not fetch origin

Err: <nil>