Gitea è una delle migliori soluzioni per ospitare un server Git self-hosted: leggero, veloce e con un’interfaccia moderna simile a GitHub. In questa guida installeremo Gitea su AlmaLinux 9 usando PostgreSQL 18 come database, un certificato SSL self-signed firmato da una CA interna e Nginx come reverse proxy.
Requisiti iniziali
Gli unici requisiti necessari sono
- server con AlmaLinux 9 installato
- utente con privilegi sudo
- accesso ssh al server
Per una migliore gestione dello spazio disco sono stati configurati due mount point dedicati (uno per il database ed uno per i dati di gitea). Per creare questa configurazione, aggiungere due dischi nel virtualizzatore in uso e verificare che vengano rilevati dal sistema
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 80G 0 disk
├─sda1 8:1 0 600M 0 part /boot/efi
├─sda2 8:2 0 1G 0 part /boot
└─sda3 8:3 0 78.4G 0 part
├─almalinux-root 253:0 0 70.5G 0 lvm /
└─almalinux-swap 253:1 0 7.9G 0 lvm [SWAP]
sdb 8:16 0 100G 0 disk
sdc 8:32 0 100G 0 disk
sr0 11:0 1 1024M 0 romIn questo caso abbiamo sbd e sdc. Procediamo ora alla configurazione del Physical Volume, Volume Group, Logical Volume
# Creazione volume per PostgreSQL
pvcreate /dev/sdb
vgcreate vg_pgsql /dev/sdb
lvcreate -L 50G -n lv_pgsql vg_pgsql
mkfs.ext4 /dev/vg_pgsql/lv_pgsql
# Creazione volume per Gitea
pvcreate /dev/sdc
vgcreate vg_gitea /dev/sdc
lvcreate -L 50G -n lv_gitea vg_gitea
mkfs.ext4 /dev/vg_gitea/lv_giteaDobbiamo ora creare dei mount point e la configurazione del file /etc/fstab
# Creazione directory
mkdir -p /var/lib/gitea
mkdir -p /var/lib/pgsql
# Aggiungere configurazione nel file /etc/fstab
/dev/mapper/vg_pgsql-lv_pgsql /var/lib/pgsql ext4 defaults 1 1
/dev/mapper/vg_gitea-lv_gitea /var/lib/gitea ext4 defaults 1 1
# Attivazione volumi
systemctl daemon-reload
mount -aAbbiamo ora i volumi configurati
df -h
[...]
/dev/mapper/vg_gitea-lv_gitea 49G 744K 47G 1% /var/lib/gitea
/dev/mapper/vg_pgsql-lv_pgsql 49G 71M 47G 1% /var/lib/pgsql
[...]Come ultimo passo per completare i requisti inziali installiamo eventuali aggiornamenti disponibili con sudo dnf update -y
Installazione di PostgreSQL 18
AlmaLinux 9 include una versione precedente di PostgreSQL nei suoi repository predefiniti. Per installare PostgreSQL 18 possiamo usare il repository ufficiale
# Disabilita il modulo PostgreSQL predefinito di AlmaLinux (obbligatorio)
sudo dnf -qy module disable postgresql
# Aggiungi il repository ufficiale PostgreSQL
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# Installa PostgreSQL 18
sudo dnf install -y postgresql18-server postgresql18-contribAd installazione completata va inizializzato il database ed impostato l’avvio automatico
sudo /usr/pgsql-18/bin/postgresql-18-setup initdb
sudo systemctl enable --now postgresql-18
# Verifica
sudo systemctl status postgresql-18
psql --versionOra possiamo creare il database per Gitea. Aprire la shell di PostgreSQL ed eseguire i comandi direttamente, in questo modo si evita il problema di escaping con caratteri speciali nella password
sudo -u postgres psql
# Creazione utenza e database
CREATE USER gitea WITH PASSWORD 'password_sicura';
CREATE DATABASE gitea OWNER gitea ENCODING 'UTF8';
\qVerifichiamo il metodo di autenticazione nel file di configurazione di PostgreSQL
sudo vi /var/lib/pgsql/18/data/pg_hba.confed assicurarsi che le connessioni locali usino scram-sha-256, il metodo predefinito e più sicuro di PostgreSQL 18
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
host all all 127.0.0.1/32 scram-sha-256Se necessario modificare il file e riavviare il servizio per applicare le modifiche
sudo systemctl restart postgresql-18Creazione utente di sistema
Gitea richiede un utente di sistema (git) e un gruppo di sistema (gitea)
- git: è l’utente con cui i client SSH si connettono (git@gitea.tuodominio.it). È anche l’utente che esegue il processo Gitea e deve corrispondere a RUN_USER in app.ini
- gitea: gruppo di sistema usato per la gestione dei permessi sui file
Attenzione: Gitea verifica all’avvio che l’utente che esegue il processo corrisponda esattamente a RUN_USER in app.ini. Se i due non coincidono, SSH rifiuterà tutte le connessioni con chiave pubblica.
# Crea il gruppo gitea
sudo groupadd --system gitea
# Crea l'utente git che eseguirà Gitea e gestirà le connessioni SSH
sudo useradd --system --shell /bin/bash \
--comment 'Gitea' \
--create-home \
--home-dir /home/gitea \
--gid gitea \
git
# Verifica la corretta creazione
getent passwd git
# Output atteso: git:x:NNN:NNN:Gitea:/home/gitea:/bin/bash
getent group gitea
# Output atteso: gitea:x:NNN:gitInstallazione di Gitea
Scaricare il binario direttamente dal sito ufficiale. Controllare sempre l’ultima versione disponibile su gitea.io
wget -O /tmp/gitea https://dl.gitea.com/gitea/1.26.1/gitea-1.26.1-linux-amd64
sudo mv /tmp/gitea /usr/local/bin/gitea
sudo chmod +x /usr/local/bin/gitea
# Verifica del corretto funzionamento
gitea --versionDobbiamo ora creare la struttura delle directory necessarie. Gitea usa /var/lib/gitea come root per tutti i dati e /etc/gitea per la configurazione
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo chown -R git:gitea /var/lib/gitea
sudo chmod -R 750 /var/lib/gitea
sudo mkdir -p /etc/gitea
sudo chown root:gitea /etc/gitea
sudo chmod 770 /etc/giteaLa struttura completa delle directory è la seguente
/var/lib/gitea/
├── custom/ # Personalizzazioni: temi, template, file statici
├── data/ # Dati applicativi principali
│ ├── repositories/ # I repository Git
│ ├── attachments/ # Allegati nelle issue/PR
│ ├── avatars/ # Avatar degli utenti
│ ├── lfs/ # File Git LFS
│ ├── packages/ # Package registry (se abilitato)
│ └── sessions/ # Sessioni utente
└── log/ # Log dell'applicazione
/etc/gitea/
└── app.ini # File di configurazione principaleDobbiamo ora creare il servizo systemd
sudo vi /etc/systemd/system/gitea.serviceed incolliamo il seguente contenuto
[Unit]
Description=Gitea (Git with a cup of tea)
After=network.target
After=postgresql-18.service
[Service]
RestartSec=2s
Type=simple
User=git
Group=gitea
WorkingDirectory=/var/lib/gitea/
RuntimeDirectory=gitea
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/gitea GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.targetPossiamo ora attivare il servizio
sudo systemctl daemon-reload
sudo systemctl enable --now giteaCreazione della CA e del certificato SSL self-signed
In questa guida sono riportati i passi per la creazione e l’utilizzo di un certificato self-signed ma è possibile utilizzare certificati generati da una Certification Authority aziendale interna oppure pubbliche come posso essere Let’s Encript o CA commerciali.
Iniziamo con la creazione di una CA (Certificate Authority) interna con cui firmare il certificato del server. Il certificato della CA dovrà essere installato sui client per evitare gli avvisi di sicurezza del browser
# Struttura della directory
sudo mkdir -p /etc/ssl/gitea
cd /etc/ssl/gitea
# Creazione della CA
# Genera la chiave privata della CA (4096 bit)
sudo openssl genrsa -out ca.key 4096
# Genera il certificato della CA (valido 10 anni)
sudo openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
-subj "/C=IT/ST=Italia/L=Citta/O=NomeOrganizzazione/OU=IT/CN=Gitea Internal CA"Possiamo ora creare il certificato del server, facendo attenzione a sostituire gitea.tuodominio.it e 192.168.1.100 con hostname e IP reali
# Genera la chiave privata del server
sudo openssl genrsa -out server.key 4096
# Genera la richiesta di firma (CSR)
sudo openssl req -new -key server.key -out server.csr \
-subj "/C=IT/ST=Italia/L=Citta/O=NomeOrganizzazione/OU=IT/CN=gitea.tuodominio.it"
# Crea il file di estensioni per i SAN (Subject Alternative Names)
sudo tee server_ext.cnf > /dev/null <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req]
subjectAltName = @alt_names
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
[alt_names]
DNS.1 = gitea.tuodominio.it
IP.1 = 192.168.1.100
EOF
# Firma il certificato del server con la CA (valido 2 anni)
sudo openssl x509 -req -days 730 \
-in server.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt \
-extensions v3_req -extfile server_ext.cnfNel caso di CA aziendali interne o commerciali è possibile generare il file CSR seguendo questa guida “Come generare un CSR con SAN tramite OpenSSL” e copiare i file generati nella directory
Vanno ora impostati i permessi corretti sui file
sudo chmod 600 /etc/ssl/gitea/ca.key
sudo chmod 600 /etc/ssl/gitea/server.key
sudo chmod 644 /etc/ssl/gitea/ca.crt
sudo chmod 644 /etc/ssl/gitea/server.crtCome detto in precedenza il certificato deve essere installato su ogni client che dovrà utilizzare Gitea, di seguito alcuni esempi
# Linux (Debian/Ubuntu)
sudo cp ca.crt /usr/local/share/ca-certificates/gitea-ca.crt
sudo update-ca-certificates
# Linux (RHEL/AlmaLinux/Rocky)
sudo cp ca.crt /etc/pki/ca-trust/source/anchors/gitea-ca.crt
sudo update-ca-trust
# macOS
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca.crtSu Windows invece doppio clic sul file ca.crt → Installa certificato → Computer locale → Autorità di certificazione radice attendibili
Reverse proxy con Nginx
Nginx espone Gitea su HTTPS e redirige automaticamente il traffico HTTP. Gitea continua a girare sulla porta 3000 ma solo in ascolto su 127.0.0.1, non esposta all’esterno
Installare nginx
sudo dnf install -y nginxe creare il file di configurazione
sudo vi /etc/nginx/conf.d/gitea.confcon il seguente contenuto cambiando gitea.tuodominio.it con l’hostname reale
server {
listen 80;
server_name gitea.tuodominio.it;
# Redirige tutto il traffico HTTP su HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name gitea.tuodominio.it;
ssl_certificate /etc/ssl/gitea/server.crt;
ssl_certificate_key /etc/ssl/gitea/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}verificare che la configurazione sia corretta e poi avviare il servizio, impostando l’avvio automatico
sudo nginx -t
sudo systemctl enable --now nginxCome ultimo passo dobbiamo configurare il firewall per far si che la porta HTTPS sia raggiungibile. Sul firewall, viene abilitata anche la porta HTTP per permettere il redirect verso HTTPS. La porta 3000 rimane in ascolto esclusivamente su 127.0.0.1 e non deve quindi essere esposta
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reloadSetup iniziale via browser
Possiamo ora aprire un browser e collegarci al link
https://gitea.tuodominio.itViene visualizzato un wizard di installazione dove possiamo impostare i parametri del database

e successivamente creare il primo utente che avrà privilegi amministrativi

L’installazione è completata e possiamo iniziare ad utilizzare Gitea.
Comandi utili
sudo systemctl status gitea # Stato del servizio
sudo systemctl restart gitea # Riavvio
sudo systemctl stop gitea # Stop
sudo journalctl -u gitea -f # Log in tempo reale
sudo journalctl -u postgresql-18 # Log PostgreSQL
sudo journalctl -u sshd -f # Log SSH (utile per debug connessioni)