1 12/05/2026 11 min

Su AlmaLinux 9 Focalboard si installa bene, ma non conviene trattarlo come un binario qualsiasi da lanciare e basta. Se l’obiettivo è usarlo davvero in produzione o in una LAN di lavoro, la strada più pulita è: servizio dedicato, database separato, reverse proxy davanti e TLS terminato sul web server. Così riduci l’esposizione, tieni sotto controllo i permessi e puoi spostare il servizio senza riscrivere tutto.

Qui sotto trovi una procedura completa, pensata per AlmaLinux 9 con systemd, PostgreSQL e Nginx. Se preferisci SQLite per un test rapido, lo puoi fare, ma non è la scelta giusta appena il sito deve reggere più utenti, backup seri o accesso via rete. L’idea è partire con una base prevedibile, poi verificare ogni blocco prima di passare al successivo.

Scelta architetturale: binario, database e proxy

Focalboard gira come applicazione Go e ascolta su una porta locale. Il pattern più pulito su AlmaLinux 9 è questo:

  • Focalboard gira come utente di servizio non privilegiato.
  • PostgreSQL conserva i dati applicativi.
  • Nginx espone il sito in HTTPS e inoltra le richieste al backend locale.
  • systemd gestisce avvio, restart e logging.

Il vantaggio pratico è semplice: se cambia il dominio, il certificato o la porta interna, tocchi il proxy; se cambia il backend, non devi riconfigurare i client. Inoltre limiti la superficie d’attacco: niente porta applicativa aperta su Internet, niente database esposto fuori host, niente processo lanciato a mano in una shell dimenticata.

Prerequisiti minimi su AlmaLinux 9

Prima di scaricare nulla, verifica che il sistema sia aggiornato e che tu abbia accesso root o sudo. Per questa guida assumo un host pulito o quasi pulito, con rete funzionante e un nome DNS già deciso per il servizio.

Controlli rapidi:

cat /etc/almalinux-release
uname -r
sudo dnf -y update

Se il sistema è in produzione, esegui prima un backup o almeno uno snapshot del volume. Non è un passaggio cosmetico: quando tocchi database, proxy e servizio, il rollback vero è quello che ti fa tornare indietro in pochi minuti.

Pacchetti necessari e account di servizio

Installa i pacchetti base: Nginx, PostgreSQL client e server, strumenti per il download e utility per SELinux e firewall. Su AlmaLinux 9 la combinazione tipica è questa:

sudo dnf install -y nginx postgresql-server postgresql-contrib curl tar policycoreutils-python-utils firewalld

Se il repository di Focalboard non è disponibile nel tuo ambiente, userai il tarball ufficiale del progetto o il pacchetto binario che hai validato internamente. Evito di assumere un canale di distribuzione unico perché gli ambienti reali cambiano, e qui il punto è non inventare una procedura che poi non combacia con il feed che hai davvero a disposizione.

Crea l’utente di servizio dedicato:

sudo useradd --system --home-dir /opt/focalboard --shell /sbin/nologin focalboard
sudo mkdir -p /opt/focalboard /var/lib/focalboard /var/log/focalboard
sudo chown -R focalboard:focalboard /opt/focalboard /var/lib/focalboard /var/log/focalboard

Il punto non è solo “ordine”. È evitare che il processo scriva dove non deve. Se il servizio ha bisogno di leggere la configurazione e salvare dati, deve farlo in directory precise, con permessi espliciti.

PostgreSQL su AlmaLinux 9: init, utente e database

Per un’installazione solida usa PostgreSQL locale. Inizia con l’inizializzazione del cluster e l’avvio del servizio:

sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql
sudo systemctl status postgresql --no-pager

Atteso: il servizio deve risultare active (running). Se non parte, il primo controllo è il log di systemd:

sudo journalctl -u postgresql -n 50 --no-pager

Crea database e utente dedicati. Usa una password lunga, salvata in un vault o in un file protetto; non inserirla in chiaro in documenti operativi condivisi.

sudo -u postgres psql
CREATE USER focalboard WITH PASSWORD 'PASSWORD_FORTE_E_ROTATA';
CREATE DATABASE focalboard OWNER focalboard;
\q

Se vuoi evitare password in chiaro anche nei file applicativi, valuta un file di configurazione con permessi stretti o una gestione tramite secret del sistema di provisioning. In questa guida mostro il metodo classico, ma il principio resta: il segreto non va disperso nei log né nei backup non protetti.

Download e posizionamento dei file di Focalboard

Scarica la release che hai validato. Il nome del file cambia nel tempo, quindi qui il comando va adattato al pacchetto reale. L’importante è mantenere una struttura ordinata sotto `/opt/focalboard`.

cd /tmp
curl -LO https://github.com/mattermost/focalboard/releases/download/vX.Y.Z/focalboard-server-linux-amd64.tar.gz
sudo tar -xzf focalboard-server-linux-amd64.tar.gz -C /opt/focalboard --strip-components=1
sudo chown -R focalboard:focalboard /opt/focalboard

Se il pacchetto che hai ottenuto ha struttura diversa, verifica prima il contenuto con:

tar -tzf focalboard-server-linux-amd64.tar.gz | head

Questa è una delle differenze che fanno perdere tempo: alcuni archivi includono già i file in una directory dedicata, altri no. Il controllo preliminare evita di ritrovarti con binari sparsi nel posto sbagliato.

Configurazione applicativa: file, porta e database

Adatta il file di configurazione al tuo layout. Il nome esatto può variare in base al pacchetto, ma il concetto non cambia: definisci porta locale, URL pubblico, connessione PostgreSQL e directory dati. Un esempio tipico:

sudo tee /opt/focalboard/config.json > /dev/null <<'EOF'
{
  "serverRoot": "https://board.example.com",
  "port": 8000,
  "dbtype": "postgres",
  "dbconfig": "postgres://focalboard:PASSWORD_FORTE_E_ROTATA@127.0.0.1:5432/focalboard?sslmode=disable",
  "useSSL": false,
  "webpath": ""
}
EOF
sudo chown focalboard:focalboard /opt/focalboard/config.json
sudo chmod 640 /opt/focalboard/config.json

Due note pratiche. Primo: se l’app gira dietro Nginx con TLS terminato sul proxy, `useSSL` resta false sul backend. Secondo: la stringa di connessione è un punto sensibile; se la incolli in una shell, evita di lasciarla nel history del terminale. In ambienti più seri, questo dato va gestito con un file separato o con un meccanismo di secret management.

Verifica che la porta scelta non sia già in uso:

sudo ss -lntp | grep ':8000'

Atteso: nessun output, oppure un processo coerente con il tuo backend. Se la porta è occupata, cambia subito il numero e ripeti il controllo prima di andare avanti.

Service systemd per avvio automatico e restart controllato

Il servizio systemd è la parte che trasforma un test in qualcosa di amministrabile. Crea un’unità dedicata:

sudo tee /etc/systemd/system/focalboard.service > /dev/null <<'EOF'
[Unit]
Description=Focalboard Server
After=network.target postgresql.service
Wants=postgresql.service

[Service]
Type=simple
User=focalboard
Group=focalboard
WorkingDirectory=/opt/focalboard
ExecStart=/opt/focalboard/bin/focalboard-server
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/var/lib/focalboard /var/log/focalboard /opt/focalboard
Environment=HOME=/var/lib/focalboard

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now focalboard

Se il binario non si trova in `/opt/focalboard/bin/focalboard-server`, correggi il path guardando la struttura reale del pacchetto con `find /opt/focalboard -maxdepth 2 -type f`. Non assumere mai il nome del binario senza verificarlo: è uno dei classici punti dove si perde mezz’ora per una banale differenza di packaging.

Controlla lo stato subito dopo l’avvio:

sudo systemctl status focalboard --no-pager
sudo journalctl -u focalboard -n 50 --no-pager

Se il servizio fallisce, i primi indizi stanno quasi sempre nel log: porta occupata, config non letta, DB non raggiungibile, permessi errati sulla directory dati o binario mancante.

Nginx come reverse proxy con TLS

Esporre Focalboard direttamente non è una buona idea. Nginx ti permette di gestire HTTPS, redirect, header utili e limiti di connessione senza toccare il backend.

Crea una configurazione dedicata, per esempio in `/etc/nginx/conf.d/focalboard.conf`:

server {
    listen 80;
    server_name board.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name board.example.com;

    ssl_certificate /etc/letsencrypt/live/board.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/board.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        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;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

Prima di riavviare Nginx, valida la sintassi:

sudo nginx -t

Atteso: `syntax is ok` e `test is successful`. Se la validazione fallisce, non riavviare a tentativi. Correggi il file, poi ripeti il test. È il modo più semplice per evitare un down inutile del frontend.

Se il certificato non esiste ancora, puoi ottenerlo con Certbot o con il tuo flusso ACME preferito. Il dettaglio cambia in base alla tua infrastruttura, ma il principio è sempre lo stesso: prima il DNS deve puntare correttamente, poi il web server deve rispondere sulla porta 80, poi emetti il certificato.

Firewall e SELinux: il punto che molti saltano

Su AlmaLinux 9 firewall e SELinux non sono optional. Se li ignori, l’installazione può sembrare corretta ma il servizio resta irraggiungibile o si comporta in modo intermittente.

Apri solo le porte necessarie:

sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Per SELinux, se l’app deve collegarsi al database locale e scrivere in directory non standard, potrebbe servire una regola mirata. Prima verifica lo stato e i denial:

sestatus
sudo ausearch -m AVC,USER_AVC -ts recent

Se trovi denial pertinenti, non disabilitare SELinux di riflesso. Meglio capire quale accesso viene bloccato e correggerlo con contesto, porta o label adeguate. Disattivarlo per comodità oggi significa lasciare un problema aperto domani.

Verifica funzionale: dal loopback al browser

La sequenza giusta è questa: prima backend locale, poi proxy, poi DNS pubblico, poi browser. Non partire dal browser e basta, perché lì vedi solo il sintomo finale.

Controlla il backend:

curl -I http://127.0.0.1:8000

Atteso: una risposta HTTP coerente, tipicamente `200`, `302` o comunque una risposta servita dal processo locale. Se ottieni `connection refused`, il servizio non ascolta. Se ottieni timeout, c’è un problema di processo o di binding. Se ottieni errore applicativo, vai nei log del servizio.

Controlla Nginx:

curl -Ik https://board.example.com

Atteso: certificato valido e risposta coerente con il backend. Se il certificato è scaduto o il nome non combacia, il problema non è Focalboard ma il layer TLS.

Se il sito non è raggiungibile dall’esterno ma funziona in locale, verifica DNS e routing:

dig +short board.example.com
traceroute board.example.com

Un record errato o un vecchio IP in cache è più comune di quanto si pensi. Prima di rifare la configurazione applicativa, accertati che il nome pubblico punti davvero all’host giusto.

Hardening essenziale e manutenzione ordinaria

Una volta online, il lavoro non è finito. Un’installazione utile va mantenuta. Le tre abitudini che pagano di più sono: aggiornamenti controllati, backup verificati e log osservati con regolarità.

Per i backup, includi almeno database e configurazione:

pg_dump -U focalboard -h 127.0.0.1 focalboard | gzip > /var/backups/focalboard-$(date +%F).sql.gz
sudo cp /opt/focalboard/config.json /var/backups/focalboard-config.json

Non lasciare i backup in una directory non protetta e non usarli come archivio permanente senza retention. Se il backup contiene credenziali, deve stare in un perimetro coerente con il livello di sensibilità dei dati.

Per gli aggiornamenti, il metodo prudente è semplice: metti in maintenance window, ferma il servizio, salva la release corrente, aggiorna il binario, riavvia e verifica. Se il nuovo pacchetto cambia schema o comportamento, testa prima in staging. Qui il rischio non è teorico: un cambio di versione può introdurre differenze di configurazione o migrazioni non banali.

Problemi tipici e lettura rapida dei sintomi

Quando l’installazione non va, i sintomi più frequenti sono quasi sempre questi:

  • Pagina bianca o 502: backend fermo, porta sbagliata o proxy mal configurato.
  • Errore di login o dati non salvati: database non raggiungibile, credenziali errate o permessi sulla directory dati.
  • Servizio che riparte in loop: config invalida, binario mancante, SELinux o dipendenza non soddisfatta.
  • Funziona in locale ma non da fuori: firewall, DNS o certificato.

Il modo più veloce per non perdere tempo è leggere il layer giusto. Se `curl http://127.0.0.1:8000` fallisce, non serve guardare il DNS. Se il backend risponde ma `curl -Ik https://board.example.com` no, il problema è davanti, non dentro l’app.

Una variante pratica: test rapido senza esporre tutto

Se vuoi provare Focalboard prima di completare TLS e DNS, puoi limitarlo al loopback e accedervi solo localmente o tramite SSH tunnel. È una buona mossa per validare il backend senza aprire subito il servizio a tutta la rete.

ssh -L 8000:127.0.0.1:8000 user@server
curl -I http://127.0.0.1:8000

Così separi il debugging dell’applicazione dal resto dell’infrastruttura. Se il tunnel funziona e il browser mostra l’interfaccia, il backend è sano e puoi concentrarti sul proxy o sul DNS. Se non funziona nemmeno così, il problema è locale e va risolto prima di esporre il servizio.

Chiusura operativa

Installare Focalboard su AlmaLinux 9 non è complicato, ma va fatto con disciplina: utente dedicato, database separato, systemd, reverse proxy, firewall e controllo dei log. Questa sequenza evita gran parte dei guasti banali e ti lascia un’installazione che puoi davvero amministrare. Se devi scegliere dove investire tempo, investilo sullo schema di deployment e sulla verifica dei layer, non sul tentativo di “farlo partire” in fretta. La differenza tra una demo e un servizio usabile sta quasi sempre lì.