Forgejo è una piattaforma Git self-hosted leggera, scritta in Go e nata come fork community-driven di Gitea. Il progetto è nato alla fine del 2022, dopo che i domini e il marchio di Gitea sono stati trasferiti a una società a scopo di lucro (Gitea Limited) senza il consenso della comunità. In risposta, Codeberg e.V. ha promosso la creazione di Forgejo con l’obiettivo di mantenere il software libero e governato dalla comunità. Dal 2024 Forgejo è diventato un hard fork, prendendo una direzione di sviluppo autonoma rispetto a Gitea.
Rispetto a soluzioni più pesanti come GitLab, Forgejo si distingue per il consumo minimo di risorse e la semplicità di configurazione, offrendo allo stesso tempo tutto il necessario per ospitare i propri repository: gestione del codice, issue tracking, pull request, wiki integrata e un sistema di CI/CD opzionale tramite Forgejo Actions.
Configurazione Porte e Flussi di Rete
Prima di passare all’installazione, è necessario capire come Forgejo utilizza le porte in un ambiente dove andremo ad utilizzare Docker. Infatti, oltre alla Web UI, Forgejo permette di gestire la connessione con i repository tramite SSH, utilizzando di norma la porta 22, che di default è dedicata a OpenSSH. Con Docker la gestione delle porte è più semplice rispetto a una configurazione nativa (o quella in NixOS ), in quanto il port mapping del container si occupa di instradare il traffico senza bisogno di regole NAT sul sistema.
(Caddy)"] Caddy -->|HTTP :3000| Forgejo["Forgejo
Web UI"] Client -->|SSH :22| ForgejoSSH["Forgejo
SSH Server"] Client -->|SSH :5555| OpenSSH["OpenSSH
(Sistema)"]
Configurazione del Reverse Proxy
Per la Web Interface è necessario configurare un reverse proxy che veicoli il traffico HTTPS verso la porta 3000 di Forgejo. In questa guida utilizziamo Caddy
, ma è possibile usare qualsiasi reverse proxy. Nel blocco seguente è riportata la configurazione di base, disponibile anche nella documentazione ufficiale
. Il dominio, l’IP del server e la porta vanno adattati alla propria configurazione:
git.nome-dominio.com {
reverse_proxy 80.81.82.83:3000
}Configurazione del Protocollo SSH
Il protocollo SSH viene utilizzato per le operazioni Git quotidiane: git clone, git push e git pull. A differenza della Web Interface, il traffico SSH non passa dal reverse proxy, in quanto SSH è un protocollo a sé stante che opera direttamente su TCP, mentre Caddy gestisce solo traffico HTTP/HTTPS.
Nel docker-compose di questa guida la porta SSH è mappata come 22:22, così che Docker possa esporre il server SSH di Forgejo direttamente sulla porta 22 dell’host, permettendo di clonare i repository con il formato standard senza dover specificare porte personalizzate:
git clone git@git.nome-dominio.com:utente/repo.gitPrima di poter utilizzare la porta 22 per Forgejo è però necessario spostare OpenSSH di sistema, che di default occupa quella stessa porta per l’accesso remoto alla macchina. In questa guida lo sposteremo sulla porta 5555, ma è possibile scegliere qualsiasi porta libera. Se non si esegue questa modifica, Docker non riuscirà a fare il bind sulla porta 22 trovandola già occupata.
Modifica della porta SSH
Per farlo è sufficiente modificare il file sshd_config e sostituire la porta 22 con quella scelta:
sudo nvim /etc/ssh/sshd_configConfigurazione SELinux e Firewall
Su distribuzioni come Fedora o RHEL, SELinux blocca l’utilizzo di porte non standard per SSH. È necessario autorizzare la nuova porta e aprirla nel firewall:
sudo semanage port -a -t ssh_port_t -p tcp 5555
sudo firewall-cmd --permanent --add-port=5555/tcp
sudo firewall-cmd --reloadRiavvio del servizio SSH
Una volta fatto, riavviare il servizio SSH per applicare la modifica:
sudo systemctl restart sshdNel video sotto è possibile vedere il processo, testato su Fedora 43, in cui viene cambiata la porta SSH e configurato il firewall per consentire l’accesso al server sulla nuova porta.
Attenzione
Prima di chiudere la sessione corrente, aprire un nuovo terminale e verificare di riuscire ad accedere al server sulla nuova porta:ssh -p 5555 utente@indirizzo-server. Se la connessione funziona è possibile proseguire. In caso contrario, la sessione ancora aperta permetterà di correggere la configurazione senza restare chiusi fuori.
Docker Compose
Dopo aver installato Docker Engine
, Docker Compose e modificato la porta SSH, è possibile procedere con l’installazione di Forgejo. La configurazione proposta sotto è composta da un file docker-compose.yml, che definisce in modo dichiarativo i due servizi necessari (il server Forgejo e il database PostgreSQL), e da un file .env per le variabili d’ambiente.
Creiamo il File Docker Compose
Il file docker-compose.yml qui sotto configura l’intero stack di Forgejo. Una volta completata l’installazione, il server sarà raggiungibile sulla porta 3000 per la Web UI e sulla porta 22 per le operazioni Git via SSH. I due servizi comunicano attraverso una rete Docker dedicata e il server si avvia solo dopo che il database è pronto, grazie all’healthcheck configurato su PostgreSQL.
services:
forgejo_server:
image: codeberg.org/forgejo/forgejo:14
container_name: Forgejo_Server
environment:
USER_UID: 1000
USER_GID: 1000
FORGEJO__database__DB_TYPE: postgres
FORGEJO__database__HOST: forgejo_db:5432
FORGEJO__database__NAME: ${FORGEJO_DB_NAME}
FORGEJO__database__USER: ${FORGEJO_DB_USER}
FORGEJO__database__PASSWD: ${FORGEJO_DB_PASSWORD}
restart: unless-stopped
networks:
- forgejo
volumes:
- ./forgejo:/data
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "22:22"
depends_on:
forgejo_db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
forgejo_db:
image: postgres:14
container_name: Forgejo_DB
restart: unless-stopped
environment:
POSTGRES_USER: ${FORGEJO_DB_USER}
POSTGRES_PASSWORD: ${FORGEJO_DB_PASSWORD}
POSTGRES_DB: ${FORGEJO_DB_NAME}
networks:
- forgejo
volumes:
- ./postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${FORGEJO_DB_USER} -d ${FORGEJO_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
forgejo:
external: falseDefiniamo i Container della Configurazione
- Il container
forgejo_serverè il cuore dell’applicazione e si occupa di gestire l’interfaccia web, le API, i repository Git e il server SSH integrato. Il volume montato in./forgejocontiene tutti i dati dell’istanza: repository, configurazione, avatar e file LFS. Le variabiliFORGEJO__database__*configurano la connessione al database tramite la convenzione di Forgejo con doppio underscore, che permette di impostare qualsiasi parametro diapp.inidirettamente via environment. Il servizio si avvia solo dopo che il database ha superato l’healthcheck, evitando errori di connessione al primo avvio. - Il container
forgejo_dbfornisce lo storage persistente tramite PostgreSQL (al momento della scrittura della guida, la documentazione ufficiale di Forgejo utilizza la versione 14 di PostgreSQL). I dati del database vengono salvati in./postgresper garantire la persistenza tra i riavvii del container. L’healthcheck utilizzapg_isreadyper verificare che PostgreSQL sia pronto ad accettare connessioni prima di far partire il server Forgejo. La reteforgejoconexternal: falseisola i due servizi in una rete Docker dedicata, non raggiungibile dall’esterno se non attraverso le porte esplicitamente mappate.
Creiamo il File .env
Il file .env contiene le credenziali del database condivise tra i due servizi. È importante personalizzare la password con una stringa sicura
e non lasciare mai i valori di esempio in produzione.
FORGEJO_DB_NAME=forgejo
FORGEJO_DB_USER=forgejo
FORGEJO_DB_PASSWORD=cambiami_con_una_password_sicuraQuale Database Scegliere
Forgejo supporta tre motori di database, ognuno adatto a scenari diversi. In questa guida abbiamo utilizzato PostgreSQL, ma nella documentazione ufficiale sono presenti le configurazioni Docker dedicate ad ogni database.
| Database | Risorse | Quando usarlo |
|---|---|---|
| SQLite | Minime (nessun processo separato, pochi MB) | Ideale per un uso personale o per piccoli team con pochi utenti. Non richiede alcun servizio esterno: i dati vengono salvati in un singolo file, il che rende semplicissimi backup e migrazione. È la scelta più leggera se si prevede un utilizzo contenuto. |
| MySQL | Medie (150-400 MB per il servizio) | Adatto se si ha già un’istanza MySQL in uso per altri servizi e si vuole centralizzare la gestione dei database. Non offre vantaggi particolari rispetto a PostgreSQL per Forgejo, ma può avere senso in ambienti dove MySQL è già lo standard. |
| PostgreSQL | Medie (100-300 MB per il servizio) | La scelta consigliata per istanze in produzione o con più utenti attivi. Gestisce senza problemi letture e scritture simultanee, offre strumenti avanzati di backup e manutenzione, ed è il database meglio supportato dall’ecosistema Forgejo. |
In questa guida abbiamo scelto PostgreSQL perché gestisce le connessioni concorrenti in modo nativo, senza i limiti di locking che caratterizzano SQLite. Questo è particolarmente rilevante in uno scenario Docker dove più processi possono accedere al database contemporaneamente: la Web UI, il server SSH, eventuali webhook e, se abilitati, i runner delle Forgejo Actions.
Nella scelta del database è importante valutare anche quanti strumenti accedono contemporaneamente a Forgejo, anche nel caso di un singolo sviluppatore. Se si utilizzano agenti di coding (Claude Code, Cursor, Copilot, Gemini…) o pipeline CI/CD che interagiscono con i repository in parallelo, le scritture concorrenti sul database aumentano sensibilmente.
Primo Avvio
Una volta installato il tutto, il servizio sarà disponibile alla porta 3000 del server e apparirà una schermata che invita a finalizzare l’installazione, andando a specificare il database, l’utente admin e le coordinate SMTP per la posta. Le opzioni disponibili sono molte, quindi non andremo a documentare tutte le varie specifiche.
Le informazioni relative al database sono già inserite in quanto Forgejo ha preso tutto dalla configurazione Docker. Una volta finalizzata l’installazione, il sistema sarà disponibile e attivo.
Autenticazione SSH per Git
Per lavorare con i repository tramite git clone, git push e git pull senza dover inserire la password ogni volta, è necessario configurare l’autenticazione via chiave SSH. La procedura è la stessa usata per qualsiasi server SSH: si genera una coppia di chiavi sul proprio computer e si carica la chiave pubblica nel proprio profilo Forgejo. La guida Chiavi SSH
spiega nel dettaglio come generare e gestire le chiavi.
Una volta generata la chiave, basta accedere a Forgejo, andare in Impostazioni utente → Chiavi SSH/GPG e incollare il contenuto della chiave pubblica (il file .pub). Da quel momento in poi tutte le operazioni Git via SSH saranno autenticate automaticamente:
git clone git@git.nome-dominio.com:utente/repo.gitAvendo spostato OpenSSH sulla porta 5555, è utile aggiungere un blocco nel file ~/.ssh/config della propria macchina locale per evitare di specificare la porta ogni volta che ci si collega al server per amministrazione:
Host mioserver
HostName 80.81.82.83
Port 5555
User <utente>In questo modo ssh mioserver userà automaticamente la porta 5555 per la connessione di amministrazione, mentre le operazioni Git verso git@git.nome-dominio.com continueranno a passare dalla porta 22 gestita da Forgejo.
Troubleshooting
Se Forgejo non si avvia o si comporta in modo inaspettato, il primo strumento da consultare sono i log del container:
docker logs -f Forgejo_ServerSe l’interfaccia web non è raggiungibile sulla porta 3000, verificare che entrambi i container siano in esecuzione e che gli healthcheck siano passati:
docker psUn problema frequente riguarda la connessione SSH. Se git clone sulla porta 22 non funziona, verificare che Docker abbia effettivamente il bind sulla porta e che OpenSSH di sistema non la stia occupando:
ss -tlnp | grep :22Se il risultato mostra sshd invece di docker-proxy, significa che OpenSSH non è stato spostato correttamente sulla porta 5555. In tal caso, rivedere la sezione Configurazione del Protocollo SSH
.
Se l’interfaccia web restituisce errori relativi al database, conviene verificare i log di PostgreSQL e che il container sia attivo:
docker logs Forgejo_DBPer verificare che il database sia raggiungibile dall’interno del container Forgejo:
docker exec Forgejo_Server pg_isready -h forgejo_db -U forgejoNel caso in cui i cookie di sessione non vengano mantenuti e il login non funzioni, il problema è quasi sempre legato all’assenza di HTTPS. Se nel file di configurazione app.ini l’opzione COOKIE_SECURE è impostata a true, i cookie vengono inviati solo su connessioni cifrate e senza un reverse proxy con certificato valido il browser li scarta silenziosamente.