# 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 # 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.