Files
gitea/README.md
2026-07-18 20:57:01 +02:00

77 lines
2.6 KiB
Markdown

# Gitea
Self-hosted Gitea behind nginx, backed by MySQL.
```text
internet -> (TLS terminated upstream) -> nginx :80 -> gitea :3000 -> mysql :3306
```
Three services on two networks: `frontend` (nginx + gitea) and `backend`
(gitea + db, `internal`, so the database has no route out).
## Setup
```bash
cp .env.example .env
openssl rand -base64 32 # put the result in MYSQL_PASSWORD
./setup.sh
```
`setup.sh` creates the bind mounts, fixes their ownership, and brings the stack
up. It refuses to start if `MYSQL_PASSWORD` is still the placeholder.
The web installer is disabled (`GITEA_INSTALL_LOCK=true`) because everything it
would ask is already set in `.env`. Create the first admin from the CLI:
```bash
docker compose exec -u git gitea gitea admin user create \
--username admin --email you@example.com --random-password --admin
```
Registration is closed by default (`GITEA_DISABLE_REGISTRATION=true`); flip it
in `.env` if you want open signups.
## TLS
The stack terminates nothing: nginx listens on plain `:80` and expects TLS to be
handled by whatever sits in front (Cloudflare, a host-level proxy, a load
balancer). That upstream must send `X-Forwarded-Proto: https`, otherwise Gitea
builds redirects with the wrong scheme. `GITEA_PROTOCOL=http` with an `https://`
`GITEA_ROOT_URL` is correct for this layout.
If you also want the real client IP in Gitea's logs, uncomment the
`set_real_ip_from` block in [nginx/gitea.conf](nginx/gitea.conf) and point it at
the upstream proxy's network.
## SSH
Git over SSH runs on the host port in `GITEA_SSH_PORT` (2222), mapped to port 22
in the container, where the image's own OpenSSH daemon serves it.
`GITEA_SSH_PORT` only tells Gitea which port to advertise in clone URLs.
Leave `GITEA_START_SSH_SERVER=false`. Setting it to `true` makes Gitea's
built-in SSH server try to bind port 22, which sshd already holds, and the
container exits with `bind: address already in use`.
## Backup
```bash
# Database
docker compose exec db mysqldump \
-u"$MYSQL_USER" -p"$MYSQL_PASSWORD" --single-transaction "$MYSQL_DATABASE" \
| gzip > gitea-db-$(date +%F).sql.gz
# Repositories, avatars, LFS
tar czf gitea-data-$(date +%F).tar.gz data/
```
Restore the database with `docker compose exec -T db mysql -u... -p... gitea <
dump.sql`, then restore `data/` and start the stack.
## Upgrading
`GITEA_IMAGE` is pinned to a minor series (`gitea/gitea:1.26`) so `docker
compose pull` picks up patch releases but never jumps a major version, which
would migrate the database irreversibly. Back up before changing the series,
and read the release notes for that jump.