Salta ai contenuti

Installazione su Linux (nativa)

XIQUIL su Linux si installa come servizio systemd, senza Docker. Lo script bash install.sh configura PostgreSQL via package manager, certificato TLS, servizio systemd con hardening, CLI wrapper xiquil e launcher per il menu applicazioni delle distro desktop.

Funziona su server headless (tipico deploy con accesso solo via browser dalla LAN) e su desktop (con apertura automatica del browser e voce nel menu app).

Questa guida copre la versione 0.21.0-beta.1-nativetest.11+. Versioni precedenti hanno meno controlli e mancano del CLI wrapper.

  • Distro supportate: Ubuntu 22.04+, Debian 12+, Fedora 39+, Arch Linux (lo script rileva automaticamente apt/dnf/pacman)
  • Python 3.11+ (python3 --version)
  • 2 GB RAM minimo (4 GB raccomandati)
  • 800 MB di spazio disco
  • Privilegi root (sudo)
  • Connessione internet per scaricare PostgreSQL dal repository PGDG (~70 MB)

Vai su Releases di GitHub e scarica il tarball:

Terminal window
# Sostituisci X.Y.Z con la versione desiderata
VERSION=X.Y.Z
wget "https://github.com/JustVitLab/xiquil/releases/download/v${VERSION}/xiquil-${VERSION}-linux-x64.tar.gz"
tar xzf "xiquil-${VERSION}-linux-x64.tar.gz"
cd "xiquil-${VERSION}"

Avvia lo script come root:

Terminal window
sudo bash desktop/linux/install.sh

Il wizard chiede i parametri in sequenza. Tutti hanno default sensati (basta premere Invio).

1. PostgreSQL

Lo script rileva se PostgreSQL è già installato:

  • Già presente → procede senza reinstallare. Marker scritto come POSTGRES_INSTALLATION=existing (l’uninstaller non lo toccherà).
  • Non presente → chiede se installarlo automaticamente. Prima di farlo, sonda la porta 5432 con ss -tlnH. Se occupata (Docker, vecchio PG, pgBouncer), aborta con messaggio chiaro:
    La porta 5432 è già in uso su questo sistema.
    Cause tipiche:
    - Docker container PostgreSQL con port-forwarding sull'host
    - Installazione PostgreSQL precedente non rimossa
    - pgBouncer / pgAdmin desktop
    Soluzioni:
    1. Ferma il processo che usa la porta 5432 (es. 'docker stop ...')
    2. Oppure scegli una porta PostgreSQL diversa quando richiesto
    Se installa, il marker sarà POSTGRES_INSTALLATION=system.

Repository sorgente:

  • apt: PGDG apt.postgresql.org (postgresql-18)
  • dnf: PGDG download.postgresql.org (postgresql18-server, postgresql18)
  • pacman: package nativo Arch (postgresql)

2. Database

CampoDefaultNote
HostlocalhostCambia per DB remoto. Marker → remote se non locale
Porta5432
Nome databasexiquil
Utente proprietarioxiquil_admin
Password applicativoautogenerata24 caratteri base64. Scritta in xiquil.env

Se il DB è locale, lo script:

  • Crea il role con CREATE ROLE xiquil_admin WITH LOGIN PASSWORD '...' (idempotente: usa ALTER ROLE se esiste)
  • Crea il database con createdb -O xiquil_admin --locale-provider=icu --icu-locale=en-US xiquil
  • Aggiunge la regola in pg_hba.conf per host xiquil xiquil_admin 127.0.0.1/32 scram-sha-256
  • Ricarica PostgreSQL
  • Testa la connessione con psql -c "SELECT 1" — se fallisce, aborta prima di andare avanti con step irreversibili

3. Rete

CampoDefaultNote
Indirizzo di ascolto127.0.0.10.0.0.0 per LAN. Cambia anche ALLOWED_HOSTS
Porta HTTPS443Porte < 1024 richiedono CAP_NET_BIND_SERVICE (gestita da systemd unit)
Hostname consentitilocalhost,$(hostname)Aggiungi IP LAN se accedi da altri PC
Fuso orarioEurope/RomeFormato IANA

4. Account amministratore (solo prima installazione)

CampoNote
EmailEmail del primo admin
PasswordMin 8 caratteri, confermata

In ordine, durante “Installazione in corso”:

  1. Rileva package manager (apt/dnf/pacman)
  2. Verifica python3 >= 3.11
  3. Se upgrade: ferma servizio + polla is-active=false 30s + pkill -9 -f /opt/xiquil.*native_startup insurance
  4. Sonda porta 5432 (se PG da installare)
  5. Installa PostgreSQL dal repository ufficiale
  6. Crea utente di sistema xiquil (useradd --system --shell /usr/sbin/nologin)
  7. Crea directory: /opt/xiquil/, /var/lib/xiquil/{uploads,plugins,certs,conf}, /var/log/xiquil/, /var/backups/xiquil/
  8. Copia file applicazione in /opt/xiquil/
  9. Crea venv Python e installa dipendenze (pip install -r requirements.txt)
  10. Installa font DejaVu per export PDF
  11. Imposta ownership xiquil:xiquil + permessi 750 su conf/ e logs/
  12. Crea database, role, regola pg_hba.conf (vedi sezione 1)
  13. Scrive /var/lib/xiquil/conf/xiquil.env con tutti i parametri + marker POSTGRES_INSTALLATION
  14. Esegue migrazioni Alembic — output: “Esecuzione migrazioni Alembic in corso… Può richiedere diversi minuti, non interrompere. Log live: /var/log/xiquil/app-.log”*
  15. Crea l’utente admin via python -m app.cli setup --email ... --password ...
  16. Installa unit systemd in /etc/systemd/system/xiquil.service, daemon-reload, enable
  17. Installa CLI wrapper /usr/local/bin/xiquil (vedi sezione dedicata)
  18. Installa launcher desktop /usr/share/applications/xiquil.desktop + icona in /usr/share/icons/hicolor/256x256/apps/xiquil.png
  19. systemctl start xiquil
  20. Healthcheck post-install (vedi sezione dedicata)

Quando il healthcheck passa tutti e 5 i controlli, lo script stampa un banner verde con 5 bullet:

═══════════════════════════════════════════
XIQUIL è operativo:
- Servizio systemd: attivo
- Backend: raggiungibile
- Database: connesso
- Backup pre-update: /var/backups/xiquil/
- URL: https://localhost:443
═══════════════════════════════════════════

Se sei su un desktop con $DISPLAY o $WAYLAND_DISPLAY settato, lo script apre automaticamente il browser sull’URL via xdg-open (eseguito come $SUDO_USER, non come root). Su server headless questo step viene silenziosamente saltato — vedrai solo il banner.

Se il healthcheck fallisce, lo script stampa un banner giallo con l’exit code e l’azione consigliata, e ritorna l’exit code del healthcheck (utile per CI/Ansible).

desktop/healthcheck.py è lo stesso script usato anche su Windows (cross-platform Python stdlib). Esegue 5 controlli sequenziali con timeout 120s:

#ControlloStrumento LinuxExit code se fallisce
1Servizio registratosystemctl list-unit-files xiquil.service2
2Servizio raggiunge activepoll systemctl is-active --quiet ogni 2s3 (+ tail journalctl per diagnostica)
3Porta TCP bound su 127.0.0.1socket.create_connection4
4HTTPS GET /api/system/version → 200urllib + trust-all SSL1 (soft warn)
5HTTPS GET /health → 200 con database: "connected"come sopra, parse JSON5

Lo script di install mappa ogni exit code a un messaggio italiano colorato che ti dice esattamente dove cercare. Esempio per exit 5:

[ERROR] Backend raggiungibile ma database non connesso
[ERROR] Cause comuni: password DB errata, PostgreSQL non in esecuzione,
porta DB diversa da quella in /var/lib/xiquil/conf/xiquil.env
[ERROR] Diagnostica: tail /var/log/xiquil/app-*.log

Il healthcheck scrive un log persistente in /var/log/xiquil/healthcheck-YYYYMMDD_HHMMSS.log. Su exit 3 (servizio non Running) include automaticamente il tail di journalctl -u xiquil -n 20.

Lanciarlo manualmente in qualsiasi momento:

Terminal window
xiquil health
# Equivalente a:
sudo /opt/xiquil/venv/bin/python /opt/xiquil/desktop/healthcheck.py --port 443 --timeout 30

Lo script bash installato in /usr/local/bin/xiquil espone i comandi più comuni con sintassi semplificata. È un thin layer su systemctl/journalctl/xdg-open/healthcheck.py. Auto-eleva via sudo solo per i comandi privileged (start/stop/restart). I read-only non chiedono mai password.

ComandoAzioneSudo?
xiquil statusBanner stato servizio + URL applicazione + ultimi 5 log systemdNo
xiquil startsystemctl start xiquilSì (auto-prepende)
xiquil stopsystemctl stop xiquilSì
xiquil restartsystemctl restart xiquilSì
xiquil logsjournalctl -u xiquil -f (tail live)No
xiquil logs --since "1 hour ago" --priority warningArgs raw passati a journalctlNo
xiquil openxdg-open https://localhost:<porta> (porta letta da env)No
xiquil healthEsegue healthcheck.py con la porta giustaNo
xiquil versioncat /opt/xiquil/VERSIONNo
xiquil helpElenco comandi (default se nessun arg)No

Esempi pratici:

Terminal window
xiquil status # "● XIQUIL is running (https://hostname:443)"
xiquil restart # auto-sudo
xiquil logs --since "10 min ago" # stato recente senza follow
xiquil logs --priority err # solo errori
xiquil health # diagnostica completa, exit code 0-5
xiquil open # apre il browser (skip se headless)

In sessione headless ($DISPLAY e $WAYLAND_DISPLAY vuoti), xiquil open stampa l’URL in chiaro invece di tentare xdg-open.

Su desktop con DE compatibile (GNOME, KDE Plasma, XFCE, Cinnamon, MATE, ecc.), XIQUIL appare nel menu applicazioni sotto Office o Finance. Cerca “XIQUIL” nello spotlight/launcher della tua DE.

Implementazione: /usr/share/applications/xiquil.desktop con Exec=xdg-open https://localhost:<porta> e icona /usr/share/icons/hicolor/256x256/apps/xiquil.png (copia di frontend/public/logo-512.png ridimensionata dall’icon theme).

Su DE non standard o container minimali senza /usr/share/applications, lo step viene saltato silenziosamente.

Due strade.

Manuale (riesegue install.sh):

Terminal window
VERSION=X.Y.Z
wget "https://github.com/JustVitLab/xiquil/releases/download/v${VERSION}/xiquil-${VERSION}-linux-x64.tar.gz"
tar xzf "xiquil-${VERSION}-linux-x64.tar.gz"
cd "xiquil-${VERSION}"
sudo bash desktop/linux/install.sh

Lo script rileva l’installazione esistente leggendo /var/lib/xiquil/conf/xiquil.env e procede in modalità upgrade: ferma il servizio + kill processi residui, sovrascrive i file, riapplica le migrazioni, riavvia.

Automatica (dal pannello admin web):

XIQUIL include un updater integrato (desktop/updater.py). Quando una nuova versione è disponibile (notification aggiornamento_disponibile agli admin), il pannello “Aggiornamenti” permette di triggerare l’upgrade da browser. Su Linux esegue:

  1. Backup pre-update (best-effort): pg_dump → /var/backups/xiquil/pre_update_YYYYMMDD_HHMMSS.dump
  2. Stop service + polling 30s + pkill -9 insurance sui residual python sotto /opt/xiquil
  3. Estrae il tarball su /opt/xiquil/ (con --strip-components=1 --overwrite)
  4. Aggiorna le dipendenze: pip install -r requirements.txt
  5. Avvia il servizio (la unit systemd ha ExecStartPre=python -m app.init_migrate, le migrazioni partono automaticamente)

Il backup pre-update è sempre best-effort: se PG non è raggiungibile o le credenziali non sono valide, viene loggato un warning e l’update procede comunque.

Terminal window
sudo bash /opt/xiquil/desktop/linux/uninstall.sh

Cosa fa sempre:

  1. Backup precauzionale del database in /var/backups/xiquil/pre_uninstall_YYYYMMDD_HHMMSS.dump (best-effort: se PG è giù o credenziali sbagliate, viene loggato e si procede)
  2. Ferma il servizio + polling stop + pkill sui residual python
  3. Disabilita e rimuove la unit systemd
  4. Elimina /opt/xiquil/
  5. Elimina /usr/local/bin/xiquil (CLI wrapper)
  6. Elimina /usr/share/applications/xiquil.desktop (launcher)
  7. Elimina /usr/share/icons/hicolor/256x256/apps/xiquil.png (icona)

Cosa chiede esplicitamente (default NO):

  • Eliminare il database xiquil + ruolo xiquil_admin? Solo se confermi. Locale: usa psql come postgres superuser. Remoto: skip (servirebbe accesso al server remoto).
  • Eliminare l’utente di sistema xiquil? Default NO.

Cosa NON fa mai automaticamente:

  • PostgreSQL non viene rimosso. Potrebbe essere usato da altre applicazioni sul tuo sistema. Lo script stampa i comandi per la rimozione manuale, adattati al tuo package manager:
    - Debian/Ubuntu: sudo apt purge postgresql-18 postgresql-client-18
    - Fedora/RHEL: sudo dnf remove postgresql18-server postgresql18
    - Arch: sudo pacman -Rns postgresql
    Se il marker POSTGRES_INSTALLATION=existing (PG era già lì prima di XIQUIL), il messaggio specifica che non è stato installato da XIQUIL — gestito interamente dall’utente.
  • /var/lib/xiquil/ (dati, log, backup, configurazione) conservato sempre — incluso il dump pre-uninstall appena creato. Per re-install futuro o forensics.

Il summary finale ricorda i path conservati e il comando per la rimozione totale (irreversibile):

Terminal window
sudo rm -rf /var/lib/xiquil /var/log/xiquil /var/backups/xiquil

Il file /etc/systemd/system/xiquil.service:

[Unit]
Description=XIQUIL Financial Intelligence Platform
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service
[Service]
Type=exec
User=xiquil
Group=xiquil
WorkingDirectory=/opt/xiquil/backend
Environment=NATIVE_MODE=1
Environment=PYTHONPATH=/opt/xiquil/backend:/opt/xiquil
EnvironmentFile=/var/lib/xiquil/conf/xiquil.env
ExecStartPre=/opt/xiquil/venv/bin/python -m app.init_migrate
ExecStart=/opt/xiquil/venv/bin/python -m desktop.native_startup
Restart=on-failure
RestartSec=10
StartLimitBurst=5
StartLimitIntervalSec=60
TimeoutStartSec=120
TimeoutStopSec=30
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
NoNewPrivileges=yes
ReadWritePaths=/var/lib/xiquil /var/log/xiquil /var/backups/xiquil
LimitNOFILE=65536
MemoryMax=1G
[Install]
WantedBy=multi-user.target

Hardening systemd applicato:

DirettivaEffetto
ProtectSystem=strictFilesystem read-only tranne ReadWritePaths
ProtectHome=yesNiente accesso a /home, /root
PrivateTmp=yesNamespace /tmp isolato per il processo
NoNewPrivileges=yesImpossibile elevare privilegi (no setuid/sgid)
ReadWritePathsSolo le 3 directory dati di XIQUIL
MemoryMax=1GHard limit memoria, OOM kill se sforato
Restart=on-failureAuto-restart con backoff (5 tentativi/60s)
ExecStartPreMigrazioni eseguite ad ogni avvio (idempotenti — Alembic dice “already at HEAD” se nulla da fare)

Per accedere da altri computer della LAN:

  1. Modifica /var/lib/xiquil/conf/xiquil.env:

    Terminal window
    sudo nano /var/lib/xiquil/conf/xiquil.env

    Imposta:

    Terminal window
    APP_HOST=0.0.0.0
    ALLOWED_HOSTS=localhost,nome-host,192.168.1.50
  2. Apri la porta nel firewall:

    Terminal window
    # UFW (Ubuntu/Debian)
    sudo ufw allow 443/tcp
    # firewalld (Fedora/RHEL/CentOS)
    sudo firewall-cmd --add-port=443/tcp --permanent
    sudo firewall-cmd --reload
    # iptables raw (Arch / sistemi minimal)
    sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
  3. Riavvia il servizio:

    Terminal window
    xiquil restart
    # o equivalente: sudo systemctl restart xiquil

Da un altro device, apri https://192.168.1.50 (o la porta configurata).

ContenutoPercorso
Applicazione/opt/xiquil/
Ambiente Python (venv)/opt/xiquil/venv/
Backend Python/opt/xiquil/backend/
Frontend compilato/opt/xiquil/frontend/dist/
Healthcheck (cross-platform)/opt/xiquil/desktop/healthcheck.py
Configurazione/var/lib/xiquil/conf/xiquil.env
Certificati TLS/var/lib/xiquil/certs/
Upload utente/var/lib/xiquil/uploads/
Log applicazione (rotazione giornaliera)/var/log/xiquil/app-YYYY-MM-DD.log
Log healthcheck/var/log/xiquil/healthcheck-*.log
Log installer/var/log/xiquil-install.log
Log uninstaller/var/log/xiquil-uninstall.log
Backup database/var/backups/xiquil/{pre_upgrade,pre_uninstall,pre_update}_*.dump
Servizio systemd/etc/systemd/system/xiquil.service
CLI wrapper/usr/local/bin/xiquil
Launcher menu/usr/share/applications/xiquil.desktop
Icona menu/usr/share/icons/hicolor/256x256/apps/xiquil.png
Terminal window
# Wrapper xiquil (consigliato)
xiquil status # banner stato + URL
xiquil restart # auto-sudo
xiquil logs --since "10 min ago"
xiquil health # diagnostica completa exit 0-5
xiquil open # browser (skip headless)
xiquil version
# systemd diretto (equivalenti)
sudo systemctl status xiquil
sudo systemctl restart xiquil
sudo journalctl -u xiquil -f
# Quale processo tiene una porta
sudo ss -tlnp 'sport = :443'
sudo ss -tlnp 'sport = :5432'
# Healthcheck manuale dettagliato
sudo /opt/xiquil/venv/bin/python /opt/xiquil/desktop/healthcheck.py --port 443 --timeout 30
# CLI utenti applicativi
sudo -u xiquil NATIVE_MODE=1 PYTHONPATH=/opt/xiquil/backend:/opt/xiquil \
/opt/xiquil/venv/bin/python -m app.cli list-users
sudo -u xiquil NATIVE_MODE=1 PYTHONPATH=/opt/xiquil/backend:/opt/xiquil \
/opt/xiquil/venv/bin/python -m app.cli reset-password --email [email protected]
# Modifica config + restart
sudo nano /var/lib/xiquil/conf/xiquil.env
xiquil restart
# Backup manuale del database (oltre a quelli automatici dell'app)
sudo -u xiquil pg_dump -h 127.0.0.1 -U xiquil_admin -d xiquil \
-Fc -f "/var/backups/xiquil/manual_$(date +%Y%m%d_%H%M%S).dump"

Lo script di installazione si chiude senza traccia

Sezione intitolata “Lo script di installazione si chiude senza traccia”

Lo script ha un trap ERR che logga line number, exit code e path del log persistente prima di uscire. Dopo una chiusura inattesa:

Terminal window
# Log persistente (anche se la finestra terminale si è chiusa)
sudo tail -100 /var/log/xiquil-install.log
# Se hai lanciato senza sudo (caso raro)
tail -100 /tmp/xiquil-install-*.log
Terminal window
# Cosa dice systemd
sudo systemctl status xiquil --no-pager
sudo journalctl -u xiquil -n 50 --no-pager
# PG attivo?
systemctl is-active postgresql 2>/dev/null || systemctl is-active postgresql-18
# Porta libera?
sudo ss -tlnp 'sport = :443'

xiquil health esce con exit code 5 (DB non connesso)

Sezione intitolata “xiquil health esce con exit code 5 (DB non connesso)”
Terminal window
# Log app per l'errore SQLAlchemy preciso
sudo tail -50 /var/log/xiquil/app-*.log
# Test diretto della connessione con le credenziali del file env
DB_USER=$(grep -oP 'POSTGRES_USER=\K.*' /var/lib/xiquil/conf/xiquil.env)
DB_PASS=$(grep -oP 'POSTGRES_PASSWORD=\K.*' /var/lib/xiquil/conf/xiquil.env)
DB_NAME=$(grep -oP 'POSTGRES_DB=\K.*' /var/lib/xiquil/conf/xiquil.env)
DB_PORT=$(grep -oP 'POSTGRES_PORT=\K.*' /var/lib/xiquil/conf/xiquil.env)
PGPASSWORD="$DB_PASS" psql -h 127.0.0.1 -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1"

Se il psql funziona ma il backend no: probabile mismatch fra quello che l’app legge e quello che pensi sia in env (es. cache, env corrotto, processo lanciato con env-vars di shell che sovrascrivono il file).

Manca o è errata la regola di autenticazione:

Terminal window
# Trova il file pg_hba.conf in uso
sudo -u postgres psql -c "SHOW hba_file;"
# Aggiungi la regola (sostituisci pg_hba_path)
echo "host xiquil xiquil_admin 127.0.0.1/32 scram-sha-256" \
| sudo tee -a "$pg_hba_path"
# Reload
sudo systemctl reload postgresql 2>/dev/null \
|| sudo systemctl reload postgresql-18

Tipicamente succede dopo un chmod -R accidentale o un restore manuale dei dati:

Terminal window
sudo chown -R xiquil:xiquil /var/lib/xiquil /var/log/xiquil /var/backups/xiquil
sudo chmod 750 /var/lib/xiquil/conf /var/log/xiquil
xiquil restart

Browser mostra solo JSON {"app":"XIQUIL","status":"running",...}

Sezione intitolata “Browser mostra solo JSON {"app":"XIQUIL","status":"running",...}”

Stai visitando la root del backend invece della SPA React. Vai su https://localhost/login (o /setup per la prima configurazione). Versioni nativetest.12+ rimuovono questo problema rendendo / la SPA in native mode.

Terminal window
# Verifica file .desktop installato
cat /usr/share/applications/xiquil.desktop
# Refresh manuale del database desktop
sudo update-desktop-database /usr/share/applications/
# Refresh icone
sudo gtk-update-icon-cache -f /usr/share/icons/hicolor
# Logout/login della sessione utente

Su GNOME potresti dover riavviare l’attività utente (Alt+F2 → r su X11; logout/login su Wayland).

Voglio rimuovere completamente XIQUIL incluso PostgreSQL

Sezione intitolata “Voglio rimuovere completamente XIQUIL incluso PostgreSQL”

In uninstall.sh, conferma il drop del database; poi a mano:

Terminal window
# Rimuovi PostgreSQL (impatta tutto il sistema!)
# Debian/Ubuntu
sudo apt purge postgresql-18 postgresql-client-18
sudo apt autoremove
# Fedora/RHEL
sudo dnf remove postgresql18-server postgresql18
# Arch
sudo pacman -Rns postgresql
# Pulizia totale dei dati XIQUIL
sudo rm -rf /var/lib/xiquil /var/log/xiquil /var/backups/xiquil