docs: add CLAUDE.md and docs/ configuration reference

This commit is contained in:
davide committed 2026-11-10 14:59:21 +01:00
1 parent d4a390388c
commit 74feb21b01
12 files changed
+497

No files matched your search

+85
View File
@@ -0,0 +1,85 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Cos'è questo repo
Non è il codice sorgente di Gitea: è lo **stack Docker di deploy** (Gitea + Caddy) di un server Git self-hosted. Contiene solo `docker-compose.yml`, `Caddyfile`, `README.md` (requisiti, porte, troubleshooting) e `SETUP.md` (wizard iniziale). Non ci sono build, lint o test. Documentazione in italiano; rispondere all'utente in italiano.
Riferimenti dettagliati in [docs/](docs/README.md): config-reference, cli, backup-restore, reverse-proxy-caddy, ssh, actions-runner, email, authentication, security-hardening, troubleshooting. Leggere il file pertinente prima di rispondere a domande di configurazione.
Fonti ufficiali per risolvere dubbi di configurazione (consultarle con WebFetch prima di rispondere a memoria): https://docs.gitea.com (sito prodotto: https://about.gitea.com).
## Comandi
```bash
docker compose up -d # avvio
docker compose pull && docker compose up -d # aggiornamento (image gitea/gitea:latest, non pinned)
docker compose logs -f gitea # log
docker compose restart gitea # necessario dopo modifiche a app.ini
docker exec -u git gitea gitea <cmd> # CLI Gitea nel container (utente git, non root)
ss -tlnp | grep '2222\|3000\|80\|443' # verifica porte occupate
```
## Architettura
```
Internet ─→ Caddy :80/:443 ─→ gitea:3000 (rete interna compose; sull'host solo 127.0.0.1:3000)
─→ host :2222 ─→ gitea:22 (SSH Git, nessun proxy)
```
- **Caddy** (`caddy:2`) fa TLS automatico Let's Encrypt e `reverse_proxy gitea:3000`. Il dominio nel `Caddyfile` è il placeholder `your-domain.com`; va allineato a `ROOT_URL` di Gitea. Lo SSH **non** passa da Caddy.
- **Gitea** salva tutto in `./gitea-data` (→ `/data`): config in `gitea-data/gitea/conf/app.ini`, repo in `gitea-data/git/repositories`, SQLite in `gitea-data/gitea/gitea.db`. DB scelto al wizard: SQLite3.
- `gitea-data/`, `caddy/data/`, `caddy/config/` sono runtime e in `.gitignore`: mai committarli (contengono secrets e chiavi host SSH).
- Il wizard (SETUP.md) scrive `app.ini`; la porta SSH mostrata negli URL (`SSH_PORT`) deve coincidere con la porta **sinistra** del mapping compose (`2222`). Cambiando il mapping, aggiornare anche `SSH_PORT` (e `SSH_LISTEN_PORT` resta 22).
## Schema configurazione Gitea (riferimento rapido)
Qualunque chiave di `app.ini` si può impostare/sovrascrivere nel servizio `gitea` di compose con `environment:` nella forma `GITEA__sezione__CHIAVE=valore` (applicata a ogni avvio; variante `..._FILE` per leggere da file). Per UID/GID: `USER_UID`/`USER_GID` (default 1000) devono combaciare col proprietario di `./gitea-data`.
Sezioni e chiavi principali (default da docs.gitea.com/administration/config-cheat-sheet):
| Sezione | Chiavi chiave (default) |
|---|---|
| (root) | `APP_NAME`, `RUN_USER`, `RUN_MODE` (`prod`) |
| `[server]` | `ROOT_URL` (obbligatorio dietro proxy: `https://dominio/`), `DOMAIN`, `HTTP_PORT` (3000), `SSH_DOMAIN`, `SSH_PORT` (22; porta mostrata), `SSH_LISTEN_PORT`, `DISABLE_SSH`, `START_SSH_SERVER` (false), `LFS_START_SERVER` (false), `OFFLINE_MODE`, `APP_DATA_PATH` |
| `[database]` | `DB_TYPE` (`sqlite3`/`postgres`/`mysql`/`mssql`), `PATH` (sqlite), `HOST`, `NAME`, `USER`, `PASSWD`, `AUTO_MIGRATION` (true) |
| `[security]` | `INSTALL_LOCK` (true dopo wizard), `SECRET_KEY` (**mai cambiare** dopo l'install: rende illeggibili 2FA ecc.), `INTERNAL_TOKEN`, `REVERSE_PROXY_TRUSTED_PROXIES`, `PASSWORD_HASH_ALGO` (pbkdf2), `MIN_PASSWORD_LENGTH` (8), `DISABLE_GIT_HOOKS` (true) |
| `[service]` | `DISABLE_REGISTRATION`, `REQUIRE_SIGNIN_VIEW`, `REGISTER_EMAIL_CONFIRM`, `ENABLE_CAPTCHA`, `DEFAULT_USER_VISIBILITY`, `ENABLE_NOTIFY_MAIL` |
| `[mailer]` | `ENABLED`, `PROTOCOL` (`smtp`/`smtps`/`smtp+starttls`/`sendmail`), `SMTP_ADDR`, `SMTP_PORT`, `FROM`, `USER`, `PASSWD` |
| `[repository]` | `ROOT`, `DEFAULT_BRANCH` (main), `DEFAULT_PRIVATE` (last), `DISABLE_HTTP_GIT`, `DISABLED_REPO_UNITS`, `MAX_CREATION_LIMIT` (-1) |
| `[ssh.minimum_key_sizes]` | `RSA` 3071, `ED25519` 256, `ECDSA` 256, `DSA` -1 |
| `[actions]` | `ENABLED` (true); retention log 365g / artifact 90g; richiede un `act_runner` separato (token: `gitea actions generate-runner-token`) — non presente in questo stack |
| `[session]` | `PROVIDER` (file), `COOKIE_NAME`, `SESSION_LIFE_TIME` (86400) |
| `[log]` | `MODE` (console), `LEVEL` (Info) |
| `[cron]` / `[cron.*]` | task pianificati (mirror `@every 10m`, health check `@midnight`, update checker `@every 168h`) |
| `[attachment]` | `MAX_SIZE` (100 MB), `MAX_FILES` (5) |
| `[lfs]` / `[packages]` | storage `local`; limiti pacchetti `-1` (illimitati) |
| `[oauth2]`, `[cache]`, `[api]`, `[other]` | token lifetime 3600s, adapter `memory`, `MAX_RESPONSE_ITEMS` 50 |
Per chiavi non elencate (indexer, ui, openid, webhook, storage S3/minio, ecc.) consultare il cheat sheet completo.
## CLI utili (dentro il container come utente `git`)
- `gitea admin user create --username U --password P --email E [--admin] [--must-change-password]`
- `gitea admin user list|delete|change-password|generate-access-token`
- `gitea admin regenerate hooks|keys` (obbligatorio dopo restore o spostamenti di directory)
- `gitea admin auth add-oauth|add-ldap|add-smtp|list`
- `gitea doctor check [--all] [--fix]`, `gitea doctor recreate-table`
- `gitea generate secret SECRET_KEY|INTERNAL_TOKEN|JWT_SECRET`
- `gitea manager shutdown|restart|flush-queues|processes`
- `gitea migrate`, `gitea dump`, `gitea actions generate-runner-token`
- Passare `-c /data/gitea/conf/app.ini` se la config non viene trovata.
## Backup / restore
- `gitea dump` richiede Gitea **fermo** per essere consistente. In Docker: `docker exec -u git -w /tmp gitea /usr/local/bin/gitea dump -c /data/gitea/conf/app.ini` (cwd scrivibile per evitare errori di permessi sullo zip; `RUN_USER` in app.ini deve essere `git`). Alternativa pragmatica: fermare lo stack e copiare `./gitea-data`.
- Il dump produce zip con `app.ini`, `custom/`, `data/`, `repos/`, `gitea-db.sql`.
- Restore manuale: estrarre `data/*` in `/data/gitea`, `repos/*` in `/data/git/repositories`, importare il DB, `chown -R git:git /data`, poi `gitea admin regenerate hooks`.
## Note operative
- Immagine `gitea/gitea:latest` non fissata: gli aggiornamenti possono includere migrazioni DB automatiche (`AUTO_MIGRATION`); fare backup prima di `pull`.
- Modifiche a `Caddyfile`: `docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile`.
- Se la 2222 è occupata, cambiare solo la porta host nel compose e aggiornare `SSH_PORT` in Gitea (vedi README).
- Cambiare dominio ⇒ aggiornare insieme `Caddyfile`, `ROOT_URL`, `DOMAIN`, `SSH_DOMAIN` e `~/.ssh/config` dei client.
+16
View File
@@ -0,0 +1,16 @@
# Indice documentazione
Note di riferimento per questo stack (Gitea + Caddy). Fonte: https://docs.gitea.com (verificare lì per versioni recenti).
| File | Contenuto |
|---|---|
| [config-reference.md](config-reference.md) | Sezioni e chiavi di `app.ini`, variabili d'ambiente `GITEA__...` |
| [cli.md](cli.md) | Comandi `gitea` (admin, doctor, dump, manager...) |
| [backup-restore.md](backup-restore.md) | Backup, restore, aggiornamenti |
| [reverse-proxy-caddy.md](reverse-proxy-caddy.md) | Caddy, ROOT_URL, WebSocket, sub-path, IP reali |
| [ssh.md](ssh.md) | Porta SSH, chiavi, client config, problemi comuni |
| [actions-runner.md](actions-runner.md) | Gitea Actions e runner (non presente nello stack) |
| [email.md](email.md) | Configurazione `[mailer]` |
| [authentication.md](authentication.md) | OAuth2, LDAP, SMTP, proxy header, sicurezza account |
| [security-hardening.md](security-hardening.md) | Fail2ban, registrazione, impostazioni sicure |
| [troubleshooting.md](troubleshooting.md) | Problemi tipici e diagnosi |
+34
View File
@@ -0,0 +1,34 @@
# Gitea Actions e runner
Gitea Actions (compatibile con workflow GitHub Actions) è abilitato di default da 1.21 (`[actions] ENABLED=true`). **Lo stack attuale non include un runner**: senza di esso i job restano in coda.
## Passi
1. Abilitare Actions nel repo: Impostazioni → "Abilita Actions del repository" (disattivo per default).
2. Ottenere un token di registrazione:
- istanza: `<url>/-/admin/actions/runners`
- organizzazione: `<url>/<org>/settings/actions/runners`
- repo: `<url>/<owner>/<repo>/settings/actions/runners`
- CLI: `gitea actions generate-runner-token [--scope owner/repo]`
3. Registrare e avviare il runner (binario "Gitea Runner", prima `act_runner`):
```bash
gitea-runner register --no-interactive --instance <URL> --token <TOKEN>
gitea-runner daemon
```
L'istanza deve essere raggiungibile da runner e container dei job: **non** `localhost`/`127.0.0.1`; usare l'URL pubblico o un indirizzo LAN. Il file `.runner` creato non va modificato a mano.
4. Il runner usa Docker per isolare i job (daemon Docker necessario; montare `/var/run/docker.sock` se containerizzato — implica privilegi elevati sull'host).
5. Workflow in `.gitea/workflows/*.yaml` (anche `.github/workflows`):
```yaml
name: demo
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "ciao"
```
`runs-on` deve corrispondere a un'etichetta (label) registrata dal runner.
## Config server
`[actions]`: DEFAULT_ACTIONS_URL (github), log retention 365g, artifact 90g, timeout task zombie 10m / endless 3h / abandoned 24h. Segreti e variabili: Impostazioni repo/org → Actions.
Non verificati qui (consultare docs.gitea.com/usage/actions): compose del runner, variabili d'ambiente, formato label.
+12
View File
@@ -0,0 +1,12 @@
# Autenticazione
Gestione da Amministrazione sito → Origini di autenticazione, o CLI `gitea admin auth ...`.
- **OAuth2 / OpenID Connect** (Keycloak, GitHub, Google...): bottone "Accedi con". Il redirect URI deve combaciare esattamente (`https://your-domain.com/user/oauth2/<nome>/callback`). Auto-registrazione e linking account in `[oauth2_client]`.
- **LDAP** (bind DN o template DN, sync utenti, filtro admin, gruppi) e **FreeIPA**.
- **SMTP**: valida login contro un mail server (PLAIN/LOGIN).
- **PAM**: richiede build custom, non nei binari ufficiali.
- **SPNEGO/SSPI**: SSO Windows/Kerberos.
- **Header del reverse proxy** (`X-WEBAUTH-USER`): Gitea deve essere raggiungibile *solo* dal proxy (qui la 3000 è già su 127.0.0.1, ma attenzione se si espone altrimenti).
- Account locali: 2FA (TOTP/WebAuthn) dalle impostazioni utente; token di accesso con scope; chiavi SSH e GPG. (Dettagli 2FA/token/GPG non verificati: docs.gitea.com/usage/authentication e pagine collegate.)
- `SECRET_KEY` cifra i segreti 2FA: non cambiarla.
+38
View File
@@ -0,0 +1,38 @@
# Backup, restore, aggiornamenti
## Cosa salvare
Tutto lo stato è in `./gitea-data` (repo, SQLite, app.ini con SECRET_KEY, chiavi host SSH) e `./caddy/data` (certificati TLS, riemettibili). Nessuno dei due è versionato.
## Metodo semplice (consigliato per SQLite)
```bash
docker compose stop gitea
tar czf gitea-backup-$(date +%F).tgz gitea-data
docker compose start gitea
```
Conservare il backup fuori dall'host e **insieme** a `app.ini` (senza SECRET_KEY i dati cifrati/2FA sono persi).
## gitea dump
Richiede Gitea fermo per consistenza. In Docker (RUN_USER=git in app.ini):
```bash
docker exec -u git -w /tmp gitea /usr/local/bin/gitea dump -c /data/gitea/conf/app.ini
docker cp gitea:/tmp/gitea-dump-*.zip .
```
Lo zip contiene `app.ini`, `custom/`, `data/`, `repos/`, `gitea-db.sql`, `log/` (non necessario). Opzioni: `--file`, `--tempdir`, `--type`, `--database`, `--skip-repository`, `--skip-log`, ecc. Per MySQL/Postgres preferire `mysqldump`/`pg_dump`.
## Restore (manuale, non esiste comando)
1. Estrarre lo zip.
2. `data/*` → `/data/gitea`, `repos/*` → `/data/git/repositories`, `app.ini` → `/data/gitea/conf/`.
3. Importare `gitea-db.sql` (con SQLite basta ripristinare `gitea.db`).
4. `chown -R git:git /data` (nel container).
5. `gitea admin regenerate hooks`; se problemi `gitea doctor check --all --fix`.
## Aggiornamento
```bash
# 1) backup 2) poi:
docker compose pull
docker compose up -d
```
L'immagine è `gitea/gitea:latest`: per aggiornamenti controllati fissare un tag (es. `gitea/gitea:1.x`) e leggere le note di rilascio. Le migrazioni DB partono in automatico (`AUTO_MIGRATION`) e non sono reversibili: il backup pre-update è l'unico rollback.
## Cambio tipo di database
`gitea dump --database postgres` genera SQL nel formato di destinazione; poco testato, scegliere il DB giusto dall'inizio. Prima: `gitea doctor check --all --fix` e `doctor recreate-table`.
+42
View File
@@ -0,0 +1,42 @@
# CLI di Gitea
Eseguire nel container come utente `git` (mai root):
```bash
docker exec -u git gitea gitea <comando>
# se non trova la config:
docker exec -u git gitea gitea -c /data/gitea/conf/app.ini <comando>
```
Opzioni globali: `--config/-c`, `--custom-path/-C`, `--work-path/-w`.
## Utenti
```bash
gitea admin user create --username U --password P --email E [--admin] [--must-change-password] [--random-password] [--access-token]
gitea admin user list [--admin]
gitea admin user change-password -u U -p NUOVA [--must-change-password]
gitea admin user delete --id N | --username U | --email E
gitea admin user generate-access-token -u U -t NOME --scopes ...
```
## Manutenzione
```bash
gitea admin regenerate hooks # dopo restore/spostamento directory
gitea admin regenerate keys # rigenera authorized_keys
gitea doctor check --list # elenco controlli
gitea doctor check --all [--fix] # diagnosi/riparazione
gitea doctor recreate-table # backup DB prima!
gitea doctor convert # utf8 → utf8mb4 (MySQL)
gitea migrate # migrazioni DB (idempotente)
gitea generate secret SECRET_KEY|INTERNAL_TOKEN|JWT_SECRET
gitea cert --host your-domain.com
```
## Autenticazione esterna
`gitea admin auth list|delete --id|add-oauth|add-smtp|add-ldap|add-ldap-simple|update-*`
## Server in esecuzione
`gitea manager shutdown|restart|flush-queues|logging|processes [--stacktraces --cancel PID]`
## Backup
`gitea dump` (vedi [backup-restore.md](backup-restore.md)), `dump-repo`/`restore-repo` per singoli repo.
## Actions
`gitea actions generate-runner-token [--scope owner[/repo]]`
+112
View File
@@ -0,0 +1,112 @@
# Riferimento configurazione (app.ini)
Percorso nel container: `/data/gitea/conf/app.ini` (host: `./gitea-data/gitea/conf/app.ini`). Riavviare Gitea dopo ogni modifica: `docker compose restart gitea`.
## Override via variabili d'ambiente (compose)
Forma: `GITEA__<sezione>__<CHIAVE>=valore`, applicata a ogni avvio del container.
Per leggere da file: `GITEA__<sezione>__<CHIAVE>__FILE=/percorso`.
```yaml
services:
gitea:
environment:
- GITEA__server__ROOT_URL=https://your-domain.com/
- GITEA__service__DISABLE_REGISTRATION=true
- USER_UID=1000
- USER_GID=1000
```
`USER_UID/USER_GID` devono combaciare col proprietario di `./gitea-data`.
Sezioni con punto: `[ssh.minimum_key_sizes]` → `GITEA__ssh.minimum_key_sizes__RSA`.
## Root
| Chiave | Default | Note |
|---|---|---|
| APP_NAME | "Gitea: Git with a cup of tea" | titolo pagine |
| RUN_USER | utente corrente | nel container `git`; deve combaciare con l'utente OS |
| RUN_MODE | prod | `dev` solo debug |
## [server]
| Chiave | Default | Note |
|---|---|---|
| PROTOCOL | http | anche https, fcgi, http+unix |
| DOMAIN | localhost | host mostrato negli URL |
| HTTP_ADDR / HTTP_PORT | 0.0.0.0 / 3000 | |
| ROOT_URL | http://localhost:3000/ | **deve essere l'URL pubblico** (https://dominio/) |
| LOCAL_ROOT_URL | | da impostare se la porta web interna non è 3000 |
| SSH_DOMAIN | = DOMAIN | host SSH negli URL clone |
| SSH_PORT | 22 | porta **mostrata** negli URL (qui 2222) |
| SSH_LISTEN_PORT | = SSH_PORT | porta su cui ascolta il server SSH built-in (qui 22) |
| DISABLE_SSH | false | |
| START_SSH_SERVER | false | SSH built-in (nell'immagine Docker è già gestito da sshd) |
| LFS_START_SERVER | false | abilita Git LFS |
| OFFLINE_MODE | true | disabilita CDN/Gravatar |
| ENABLE_ACME | false | non serve: TLS lo fa Caddy |
| APP_DATA_PATH | data | |
## [database]
| Chiave | Default | Note |
|---|---|---|
| DB_TYPE | mysql | sqlite3 / postgres / mysql / mssql (qui sqlite3) |
| PATH | data/gitea.db | solo sqlite |
| HOST, NAME, USER, PASSWD | 127.0.0.1:3306, gitea, root, vuoto | |
| SSL_MODE | disable | |
| MAX_OPEN_CONNS / MAX_IDLE_CONNS | 0 / 2 | |
| AUTO_MIGRATION | true | migrazioni all'avvio |
## [security]
| Chiave | Default | Note |
|---|---|---|
| INSTALL_LOCK | false | true dopo il wizard (blocca /install) |
| SECRET_KEY | casuale | **non cambiare mai** dopo l'install (2FA e dati cifrati) |
| INTERNAL_TOKEN | casuale | comunicazione interna |
| LOGIN_REMEMBER_DAYS | 31 | |
| PASSWORD_HASH_ALGO | pbkdf2 | argon2, scrypt, bcrypt |
| MIN_PASSWORD_LENGTH / PASSWORD_COMPLEXITY | 8 / off | |
| REVERSE_PROXY_LIMIT | 1 | |
| REVERSE_PROXY_TRUSTED_PROXIES | 127.0.0.0/8,::1/128 | in Docker aggiungere la subnet compose (es. 172.16.0.0/12) |
| DISABLE_GIT_HOOKS | true | hook custom = esecuzione codice sull'host |
| EGRESS_MODE | lax | `strict` richiede allow-list |
## [service]
| Chiave | Default | Note |
|---|---|---|
| DISABLE_REGISTRATION | false (ma il wizard lo propone) | true = solo admin crea utenti |
| REQUIRE_SIGNIN_VIEW | false | true = server privato |
| REGISTER_EMAIL_CONFIRM | false | richiede mailer |
| ENABLE_BASIC_AUTHENTICATION | true | |
| ENABLE_CAPTCHA | false | |
| DEFAULT_USER_VISIBILITY / DEFAULT_ORG_VISIBILITY | public | |
| ENABLE_NOTIFY_MAIL | false | |
| ENABLE_TIMETRACKING | true | |
## [repository]
ROOT (`{APP_DATA_PATH}/gitea-repositories`; nel Docker `/data/git/repositories`), DEFAULT_BRANCH (main), DEFAULT_PRIVATE (last|private|public), DEFAULT_OBJECT_FORMAT (sha1|sha256), DISABLE_HTTP_GIT, DISABLE_MIGRATIONS, DISABLE_STARS, MAX_CREATION_LIMIT (-1), DEFAULT_REPO_UNITS, DISABLED_REPO_UNITS (disabilita funzioni globalmente, es. `repo.actions,repo.packages`).
## [ssh.minimum_key_sizes]
ED25519 256, ECDSA 256, RSA 3071, DSA -1 (disabilitato).
## [mailer]
Vedi [email.md](email.md).
## [actions]
ENABLED true (da 1.21); default action host `github`; retention log 365g, artifact 90g, run 400g; zombie task timeout 10m; endless task 3h; abandoned job 24h. Vedi [actions-runner.md](actions-runner.md).
## [session]
PROVIDER file, PROVIDER_CONFIG data/sessions, COOKIE_NAME i_like_gitea, SESSION_LIFE_TIME 86400, SAME_SITE lax. Aggiungere `COOKIE_SECURE=true` dietro HTTPS.
## [log]
MODE console, LEVEL Info. Modalità file: `gitea.log`, rotazione 7 giorni. Necessario su file per fail2ban.
## [cron] / [cron.*]
`[cron] ENABLED=false` (globale); task: archive cleanup `@midnight`, update_mirrors `@every 10m`, repo health check `@midnight`, stop_zombie_tasks `@every 5m`, stop_endless_tasks `@every 30m`, cancel_abandoned_jobs `@every 6h`, update_checker `@every 168h`.
## Altre sezioni
- **[attachment]**: ENABLED, MAX_SIZE 100 (MB), MAX_FILES 5, STORAGE_TYPE local, PATH attachments.
- **[lfs]**: PATH ./data/lfs; batch 20, concurrency 8.
- **[packages]**: ENABLED true; limiti per tipo -1; CHUNKED_UPLOAD_PATH tmp/package-upload. Registry container richiede `/v2` alla radice del dominio.
- **[oauth2]**: ENABLED, ACCESS_TOKEN_EXPIRATION_TIME 3600, REFRESH_TOKEN_EXPIRATION_TIME 730h, JWT_SIGNING_ALGORITHM RS256.
- **[cache]**: ADAPTER memory, INTERVAL 60, ITEM_TTL 16h.
- **[api]**: ENABLE_SWAGGER true, MAX_RESPONSE_ITEMS 50, DEFAULT_PAGING_NUM 30.
- **[other]**: SHOW_FOOTER_VERSION, SHOW_FOOTER_POWERED_BY, ENABLE_SITEMAP, ENABLE_FEED.
- **[indexer], [ui], [openid], [webhook], [storage]**: non verificate in questo riferimento; consultare https://docs.gitea.com/administration/config-cheat-sheet.
+21
View File
@@ -0,0 +1,21 @@
# Email
Abilita notifiche, reset password, conferma registrazione. Aggiungere a `app.ini` (o `GITEA__mailer__...`) e riavviare.
```ini
[service]
ENABLE_NOTIFY_MAIL = true
[mailer]
ENABLED = true
FROM = gitea@your-domain.com
PROTOCOL = smtps ; smtps (465) | smtp+starttls (587) | smtp | sendmail
SMTP_ADDR = mail.your-domain.com
SMTP_PORT = 465
USER = gitea@your-domain.com
PASSWD = *** ; meglio GITEA__mailer__PASSWD__FILE
```
- Gmail: `smtp.gmail.com`, 465 smtps (o 587 smtp+starttls), serve una *app password* (richiede 2FA Google); OAuth non supportato.
- L'autenticazione richiede TLS (o HOST=localhost).
- `sendmail` non funziona con l'immagine Docker ufficiale: usare SMTP.
- Test: Amministrazione sito → Configurazione → Riepilogo → Configurazione mailer → invia email di prova.
+41
View File
@@ -0,0 +1,41 @@
# Reverse proxy Caddy
`Caddyfile` attuale:
```
your-domain.com {
reverse_proxy gitea:3000
}
```
Caddy gestisce da solo certificato Let's Encrypt, rinnovi, redirect HTTP→HTTPS e WebSocket (`/-/ws`, aggiornamenti in tempo reale) con `reverse_proxy`. Passa `Host` e `X-Forwarded-Proto` correttamente.
## Requisiti in Gitea
```ini
[server]
ROOT_URL = https://your-domain.com/
DOMAIN = your-domain.com
[security]
REVERSE_PROXY_LIMIT = 1
REVERSE_PROXY_TRUSTED_PROXIES = 172.16.0.0/12 ; subnet rete docker compose (verificare)
```
Senza trusted proxies corretto Gitea (e fail2ban/log) vede l'IP del container Caddy invece del client.
## Sub-path (sconsigliato)
```
git.example.com {
route /git/* {
uri strip_prefix /git
reverse_proxy gitea:3000
}
}
```
`ROOT_URL = https://git.example.com/git/`. Il proxy non deve decodificare `%2F`. Il registry container richiede `/v2` alla radice del dominio.
## Comandi
```bash
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile
docker compose logs caddy
```
Il certificato non viene emesso se 80/443 non sono raggiungibili o il DNS non punta all'IP pubblico. Per test senza rate limit, usare in `Caddyfile` la direttiva globale `{ acme_ca https://acme-staging-v02.api.letsencrypt.org/directory }`.
## Limiti upload
Caddy non limita il body di default; i limiti sono in Gitea (`[attachment] MAX_SIZE`, `[repository.upload]`, `[packages] LIMIT_SIZE_*`).
+44
View File
@@ -0,0 +1,44 @@
# Sicurezza
## Impostazioni consigliate
```ini
[service]
DISABLE_REGISTRATION = true ; server personale
REQUIRE_SIGNIN_VIEW = true ; opzionale: tutto privato
[session]
COOKIE_SECURE = true
[security]
INSTALL_LOCK = true
DISABLE_GIT_HOOKS = true
```
- Esporre fuori solo 80, 443, 2222; 3000 resta su 127.0.0.1.
- Backup di `app.ini` (SECRET_KEY/INTERNAL_TOKEN) separato e protetto.
- Aggiornare regolarmente l'immagine (vedi [backup-restore.md](backup-restore.md)).
- Preferire chiavi ED25519; abilitare 2FA per gli admin.
## Fail2ban (sull'host)
1. Log su file in `app.ini`:
```ini
[log]
MODE = console, file
LEVEL = Info
```
2. `/etc/fail2ban/filter.d/gitea.local`:
```ini
[Definition]
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
ignoreregex =
```
3. `/etc/fail2ban/jail.d/gitea.local` (path del log: `<repo>/gitea-data/gitea/log/gitea.log`):
```ini
[gitea]
enabled = true
filter = gitea
logpath = /home/davide3011/gitea/gitea/gitea-data/gitea/log/gitea.log
maxretry = 10
findtime = 3600
bantime = 900
action = iptables-allports
```
4. Con Docker aggiungere un jail con `action = iptables-allports[chain="FORWARD"]`.
5. Per vedere l'IP reale impostare `REVERSE_PROXY_LIMIT = 1` e `REVERSE_PROXY_TRUSTED_PROXIES` con la subnet docker (172.16.0.0/12 di norma). Verificare i path/permessi del log prima di fidarsi.
+30
View File
@@ -0,0 +1,30 @@
# SSH
Mapping compose: `2222:22` → host 2222 → sshd built-in dell'immagine nel container (porta 22). Lo SSH non passa da Caddy.
## Impostazioni coerenti
```ini
[server]
SSH_DOMAIN = your-domain.com
SSH_PORT = 2222 ; mostrata negli URL
SSH_LISTEN_PORT = 22 ; porta nel container
```
URL clone: `ssh://git@your-domain.com:2222/utente/repo.git`.
## Client (`~/.ssh/config`)
```
Host your-domain.com
Port 2222
User git
```
Poi `git clone git@your-domain.com:utente/repo.git`.
## Chiavi
Aggiungere la chiave pubblica in Impostazioni → Chiavi SSH/GPG. Dimensioni minime: ED25519 256, ECDSA 256, RSA 3071, DSA vietato (`[ssh.minimum_key_sizes]`). Test: `ssh -T -p 2222 git@your-domain.com`.
## Problemi
- Porta occupata: cambiare solo la porta host nel compose e `SSH_PORT`.
- `Permission denied (publickey)`: chiave non registrata o agent sbagliato (`ssh -vT ...`).
- Dopo restore: `gitea admin regenerate keys` e `hooks`.
- Le chiavi host SSH del server sono in `gitea-data/ssh`: conservarle per evitare avvisi "host key changed".
- Dietro NAT: port forwarding anche per 2222.
+22
View File
@@ -0,0 +1,22 @@
# Troubleshooting
| Sintomo | Causa / rimedio |
|---|---|
| Certificato non emesso | DNS non punta all'IP pubblico, 80/443 chiuse o in uso; `docker compose logs caddy` |
| Link/clone con URL sbagliato | `ROOT_URL`, `SSH_DOMAIN`, `SSH_PORT` non coerenti |
| Porta 2222 occupata | `ss -tlnp \| grep 2222`, cambiare porta host e `SSH_PORT` |
| `Permission denied (publickey)` | chiave non registrata; `ssh -vT -p 2222 git@dominio` |
| Push rifiutato dopo restore/spostamento | `gitea admin regenerate hooks` |
| Errori permessi su `/data` | `USER_UID/GID` ≠ proprietario di `./gitea-data`; `chown` |
| Login ok ma IP client = 172.x | `REVERSE_PROXY_TRUSTED_PROXIES` mancante |
| Aggiornamenti live assenti | WebSocket `/-/ws` bloccato dal proxy |
| Job Actions in coda | nessun runner registrato / label non corrisponde |
| Pagina /install riappare | `INSTALL_LOCK` non true o `app.ini` non persistito |
| Schema DB anomalo | `gitea doctor check --all --fix` (backup prima) |
Diagnosi base:
```bash
docker compose ps
docker compose logs --tail=100 gitea caddy
docker exec -u git gitea gitea doctor check --all
```