77 lines
2.6 KiB
Markdown
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.
|