Documento 7 di 13
Installazione
Modalità di erogazione, installazione passo per passo, database esterno, configurazione.
Per chi: IT
Questo documento spiega come Orafila viene messo in funzione: le modalità di erogazione, l'installazione su un server con il pacchetto Docker, il database esterno facoltativo, l'avvio di prova su un computer e i riferimenti di configurazione.
Le guide passo per passo con le schermate dei fornitori cloud, pensate anche per chi non fa il sistemista, sono nel pacchetto:
- Rilascio su Oracle Cloud (VM gratuita Always Free, adatta a demo e pilota);
- Rilascio su DigitalOcean (Droplet a pagamento, adatto anche ai clienti in produzione);
- Database esterno.
1. Modalità di erogazione
| Servizio gestito | Installazione dedicata | |
|---|---|---|
| Chi gestisce il server | Il fornitore di Orafila | Il fornitore o l'IT dell'azienda, sul server scelto dall'azienda |
| Cosa riceve l'azienda | Indirizzo dell'applicazione, codice azienda e link di invito per il primo amministratore | Un'installazione completa, con eventuali più aziende (per esempio società di un gruppo) |
| Installazione | Nessuna per l'azienda | Server Ubuntu con Docker, circa 2-3 ore la prima volta (quasi tutte di attesa) |
| Aggiornamenti e backup | A cura del fornitore | Un comando per l'aggiornamento; backup notturni automatici una volta configurati |
| Chiavi AI | Del fornitore o dell'azienda, secondo il contratto | Dell'azienda, con il suo contratto diretto con il fornitore AI |
In entrambi i casi l'applicazione è la stessa e ogni azienda ha i suoi dati separati dal database. Nel servizio gestito l'azienda parte dal passo 8 di questo documento e poi da Avvio e configurazione.
2. Prima di iniziare
- Un server Ubuntu 24.04 (o 22.04) con i requisiti di Requisiti e architettura, raggiungibile via SSH con una chiave.
- Un nome a dominio di cui potete modificare il DNS (per esempio
psa.vostraazienda.it) e un'email per la registrazione dei certificati HTTPS. - L'accesso in sola lettura al repository di Orafila: una deploy key generata sul server e abilitata in sola lettura dal fornitore di Orafila (passo 4).
- Un gestore di password dove salvare le chiavi generate dall'installazione. È indispensabile.
- Facoltativi: una chiave API di Anthropic, OpenAI o Google per l'AI; un bucket compatibile S3 per la copia dei backup; un account su un servizio di controllo esterno (per esempio Healthchecks.io e un servizio di uptime).
Da qui in poi i comandi che iniziano con deploy/ si scrivono sul server, dalla cartella nova-psa.
3. Creare il server e il DNS
- Create il server presso il fornitore scelto, preferibilmente in una regione dell'Unione Europea. Le guide Oracle e DigitalOcean descrivono ogni schermata.
- Nel firewall del fornitore aprite in ingresso TCP 80, TCP 443 e UDP 443 da tutti, e TCP 22 (SSH) possibilmente solo dal vostro indirizzo IP.
- Nel DNS del dominio create un record A con il nome scelto (per esempio
psa) verso l'IP pubblico del server. Prima di andare avanti il nome deve rispondere con l'IP giusto (nslookup psa.vostraazienda.it).
4. Scaricare il pacchetto
- Sul server create la chiave e mandate al fornitore di Orafila la riga pubblica (inizia con
ssh-ed25519), che la abilita in sola lettura sul repository:ssh-keygen -t ed25519 -N "" -C "nova-server" -f ~/.ssh/id_ed25519 cat ~/.ssh/id_ed25519.pub - Quando è abilitata, scaricate il pacchetto:
sudo apt-get update && sudo apt-get install -y git
cd ~
git clone --filter=blob:none --sparse --branch master <INDIRIZZO_DEL_REPOSITORY> intra
cd intra
git sparse-checkout set --no-cone /nova-psa/
cd nova-psa
Si scarica solo la cartella nova-psa della versione attuale. La copia deve restare un repository Git: gli aggiornamenti la usano.
5. Preparare il server
sudo deploy/setup-host.sh
Lo script (da 5 a 15 minuti, si può rilanciare senza danni):
- riconosce il fornitore (Oracle Cloud, DigitalOcean o altro Ubuntu);
- crea 2 GB di swap sui server con meno di 3,5 GB di RAM;
- aggiorna Ubuntu e attiva gli aggiornamenti di sicurezza automatici;
- installa Docker (dal repository ufficiale di Docker), git, age e rclone;
- apre le porte 80 e 443 nel firewall interno del server, se lo blocca;
- controlla se le porte SMTP in uscita sono bloccate (465, 587) e propone la porta 2525.
Su un utente diverso da root (per esempio ubuntu su Oracle) uscite e rientrate con SSH perché il gruppo docker valga anche per voi; docker ps deve rispondere senza errori.
6. Configurare e salvare le chiavi
deploy/nova.sh init --domain psa.vostraazienda.it --email [email protected]
Lo script crea deploy/.env (leggibile solo dal vostro utente), genera tutte le password e i segreti e crea la chiave per cifrare i backup in deploy/secrets/backup.agekey. Rilanciato, non cambia mai i valori già presenti.
Subito dopo, salvate nel gestore di password:
cat deploy/secrets/backup.agekey # tutto il contenuto, righe con # comprese
grep '^APP_ENCRYPTION_KEY=' deploy/.env
cat deploy/.env # consigliato: tutta la configurazione
- Senza la chiave privata dei backup i backup non si possono aprire.
- Senza
APP_ENCRYPTION_KEY, dopo un ripristino la verifica in due passaggi e le password delle caselle di posta non si possono più leggere. - Aggiornate la copia ogni volta che modificate
deploy/.env. Non mandate mai queste chiavi per email o in chat.
AI (facoltativa): per attivarla scrivete in deploy/.env la chiave di almeno un fornitore (ANTHROPIC_API_KEY=, OPENAI_API_KEY= o GEMINI_API_KEY=, senza spazi dopo =). Conviene impostare anche un limite di spesa nella console del fornitore. Si può fare anche dopo: ogni modifica a deploy/.env si applica con deploy/nova.sh up.
7. Avviare
deploy/nova.sh up
Lo script controlla la memoria, costruisce l'immagine (la prima volta 10-15 minuti), avvia il database, applica le migrazioni dello schema, poi avvia l'app, il processo della posta e Caddy, e aspetta che l'app risponda.
Verifiche:
deploy/nova.sh status:app,workeredbhealthy,caddyrunning,migrateexited (normale: ha finito).https://psa.vostraazienda.itmostra il lucchetto e la pagina di accesso (Codice azienda, Email, Password).https://psa.vostraazienda.it/api/healthrisponde{"status":"ok"}.
Se il certificato HTTPS non arriva: aspettate 2-3 minuti; controllate il DNS e le porte 80/443 (anche con sudo deploy/setup-host.sh --firewall-only); leggete deploy/nova.sh logs caddy (certificate obtained successfully vuol dire che è a posto). Dopo la correzione deploy/nova.sh up fa ripartire subito la richiesta. Troppi tentativi falliti di fila fanno bloccare Let's Encrypt per circa un'ora.
8. Attivare la prima azienda
Ogni azienda ha un codice azienda da 3 a 40 caratteri tra lettere minuscole, cifre e trattini:
deploy/nova.sh tenant-create --name "Rossi Software Srl" --slug rossi \
--admin-email [email protected] --admin-name "Anna Rossi"
Il comando crea l'azienda, i sette ruoli predefiniti, la coda Assistenza (prefisso dei ticket TCK) e l'invito per il primo amministratore, e stampa il link di invito (https://psa.vostraazienda.it/invite/...), valido 7 giorni e una sola volta. Mandatelo all'amministratore con un canale sicuro: Orafila non lo invia per email.
Opzioni utili:
| Opzione | Effetto |
|---|---|
--lingua en |
Azienda in inglese: ruoli e coda con i nomi inglesi, documenti ed email ai clienti in inglese, interfaccia in inglese per l'amministratore |
--queue-address [email protected] |
Indirizzo della coda per il gateway di inoltro delle email (vedi Integrazioni) |
--reinvite --slug rossi |
Nuovo link per il primo amministratore, se il precedente è scaduto o perso (il vecchio smette di funzionare); con --admin-email corregge anche l'indirizzo |
L'amministratore apre il link, sceglie la password (almeno 12 caratteri), accede con codice azienda, email e password e attiva la verifica in due passaggi. Da lì prosegue con Avvio e configurazione.
Dati di esempio (facoltativi, per una demo o per la formazione): deploy/nova.sh sample-data --slug rossi riempie tutte le schermate con dati inventati e riconoscibili (codici ESEMPIO-..., indirizzi @esempio.example, due anni di storia); deploy/nova.sh sample-data --slug rossi --remove li toglie senza toccare i dati reali. Toglieteli prima di lavorare con i clienti veri.
9. Configurare i backup
- Create un bucket privato compatibile S3 (Oracle Object Storage, DigitalOcean Spaces o altro) e una chiave di accesso limitata a quel bucket. Su Oracle aggiungete una regola di conservazione che impedisce di cancellare i file per 29 giorni.
- Compilate in
deploy/.envBACKUP_RCLONE_REMOTEe le righeRCLONE_CONFIG_...del vostro archivio (il modellodeploy/env.exampleha i blocchi già pronti per Oracle e DigitalOcean). - Primo backup di prova:
deploy/nova.sh backup(crea il backup, lo verifica decifrandolo, lo copia nel bucket).deploy/nova.sh backupselenca i backup locali e remoti. - Backup automatico ogni notte alle 02:30:
deploy/nova.sh install-timer(controllo consystemctl list-timers nova-backup.timer). - Consigliato: un controllo su Healthchecks.io (periodo 1 giorno, tolleranza 2 ore) con l'indirizzo in
BACKUP_PING_URL: se il backup di una notte non arriva o fallisce, arriva un'email.
| Variabile | Predefinito | Significato |
|---|---|---|
BACKUP_KEEP_LOCAL |
7 | Backup tenuti sul server |
BACKUP_KEEP_REMOTE_DAYS |
30 | Giorni nel bucket (maggiore della regola di conservazione) |
BACKUP_PING_URL |
vuoto | Indirizzo di controllo chiamato dopo ogni backup |
10. Controllo esterno e prova di ripristino
- Create un controllo di disponibilità (uptime) HTTPS su
https://psa.vostraazienda.it/api/healthogni 5 minuti, con avviso via email: il server non può avvisarvi se è spento. - Provate subito il ripristino, non il giorno del bisogno:
deploy/nova.sh restore nova-AAAAMMGGTHHMMSSZ.dump.age --yes(fa prima un backup di sicurezza). La ricostruzione completa su un server nuovo (pacchetto,deploy/.enve chiavi dal gestore di password, ripristino dal bucket) è descritta nelle guide dei fornitori. Vedi anche Gestione e manutenzione.
11. Database esterno (facoltativo)
Di solito PostgreSQL gira in un contenitore sullo stesso server. Per un database gestito (alta disponibilità, backup e ripristino a un momento preciso del fornitore) o un server PostgreSQL dell'azienda:
- Dopo
deploy/nova.sh init, copiate il certificato CA del fornitore indeploy/db-ca.crt. - Compilate in
deploy/.env:NOVA_DB_HOST=nome-del-server-del-database NOVA_DB_PORT=5432 # 25060 su DigitalOcean NOVA_DB_NAME=nova NOVA_DB_SSLMODE=verify-full # oppure verify-ca; altri valori sono rifiutati NOVA_DB_CA_FILE=./db-ca.crt # vuoto = autorità pubbliche, solo con verify-full deploy/nova.sh db-setup: chiede le credenziali di un amministratore del database (non le salva) e crea i ruolinova_owner,nova_app,nova_app_user, il database e, se il fornitore lo permette,nova_backupper i backup. Le password arrivano al database come verificatori SCRAM, mai in chiaro.deploy/nova.sh up: controlla il collegamento, ferma il database interno (il suo volume resta) e applica le migrazioni sul database esterno.
Da quel momento backup, ripristino, aggiornamenti e strumenti lavorano sul database esterno. Per spostare i dati di un'installazione già avviata si fa un backup prima di compilare NOVA_DB_HOST, poi db-setup, restore e up. Tutti i dettagli, i problemi frequenti e la lista di sicurezza sono nella guida Database esterno.
12. Avvio di prova su un computer (senza Docker)
Per una valutazione tecnica o per lo sviluppo, su Linux o macOS con Node.js 22.18 o successivo e PostgreSQL 15 o successivo:
cd nova-psa
npm install
cp .env.example .env.local # poi compilate le variabili (vedi sotto)
sudo -u postgres scripts/setup-dev-db.sh # ruoli nova_owner, nova_app, nova_app_user e database nova_dev
npm run db:migrate
npm run db:seed # dati dimostrativi: aziende "demo" e "altra"
npm run build && npm start # in un altro terminale: npm run mail:worker
Accesso dimostrativo su http://localhost:3000: azienda demo, email [email protected] (amministratore), password Demo-Orafila-2026!; altri ruoli con commerciale@, amministrazione@, magazzino@, marco.galli@ (tecnico), tutti @demo.example. Queste credenziali sono pubbliche e valgono solo per la prova in locale: non usate mai db:seed su un'installazione reale.
13. Riferimento: configurazione del server (deploy/.env)
| Variabile | Obbligatoria | Significato |
|---|---|---|
NOVA_DOMAIN |
sì | Nome a dominio, senza https:// |
ACME_EMAIL |
sì | Email per i certificati Let's Encrypt |
POSTGRES_PASSWORD, NOVA_OWNER_PASSWORD, NOVA_APP_PASSWORD |
sì (generate) | Password dei ruoli del database; up le applica al database |
APP_ENCRYPTION_KEY |
sì (generata) | 32 byte in base64 che cifrano i segreti; su un server già avviato non va mai rigenerata |
INBOUND_EMAIL_SECRET |
sì (generato) | Segreto del gateway di inoltro delle email |
ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY |
no | Chiavi dei fornitori AI; ne basta una |
NOVA_AI_MODEL |
no | Agente predefinito per le aziende che non ne scelgono uno (per esempio claude-sonnet-5-5; vuoto = Claude Opus 5.5) |
MAIL_POLL_SECONDS |
no (60) | Ogni quanti secondi si leggono le caselle (da 10 in su) |
BACKUP_AGE_RECIPIENT |
sì (generata) | Chiave pubblica di cifratura dei backup |
BACKUP_KEEP_LOCAL, BACKUP_KEEP_REMOTE_DAYS, BACKUP_RCLONE_REMOTE, BACKUP_PING_URL, RCLONE_CONFIG_* |
no | Conservazione e copia dei backup |
NOVA_DB_HOST, NOVA_DB_PORT, NOVA_DB_NAME, NOVA_DB_SSLMODE, NOVA_DB_CA_FILE, NOVA_BACKUP_PASSWORD, NOVA_DB_CLIENT_IMAGE |
no | Database esterno |
Formato: una riga CHIAVE=valore, senza spazi intorno a =, commenti su righe proprie; un valore con $ va tra apici singoli.
Per un'installazione senza il pacchetto (avvio in locale o altra piattaforma) l'app legge: DATABASE_URL (ruolo applicativo, soggetto all'isolamento), ADMIN_DATABASE_URL (proprietario, solo per migrazioni e strumenti), APP_ENCRYPTION_KEY, INBOUND_EMAIL_SECRET, APP_BASE_URL (indirizzo pubblico per i link di invito), TRUST_PROXY=1 solo dietro un proxy che imposta X-Forwarded-For, le chiavi AI e, con un database con TLS, ?sslmode=verify-full&sslrootcert=/percorso/ca.crt nell'indirizzo più NOVA_DB_REQUIRE_VERIFIED_TLS=1.
14. Riferimento: comandi di deploy/nova.sh
| Comando | Cosa fa |
|---|---|
init [--domain D] [--email E] |
Crea .env con segreti nuovi e la chiave dei backup (non cambia i valori presenti) |
db-setup |
Solo con un database esterno: crea ruoli e database con le credenziali di un amministratore, non salvate |
up |
Costruisce l'immagine e avvia o riavvia tutto |
install-timer |
Attiva il backup automatico ogni notte alle 02:30 |
status |
Servizi, database esterno, disco, memoria, ultimo backup, email in uscita |
logs [-f] [servizio...] |
Log di app, worker, db, caddy, migrate |
update [--no-backup] |
Scarica la nuova versione con git, fa un backup e riavvia |
tenant-create ... |
Attiva un'azienda e stampa il link di invito |
queue-address ... |
Assegna o toglie l'indirizzo di una coda per il gateway di inoltro |
sample-data --slug CODICE [--remove] |
Aggiunge o toglie i dati di esempio di un'azienda |
backup |
Backup cifrato adesso, più la copia remota se configurata |
backups |
Elenca i backup locali e remoti |
restore FILE --yes [--key K] [--no-safety-backup] |
Ripristina un backup, dopo un backup di sicurezza (--no-safety-backup solo con un database esterno di cui nova.sh non può fare backup, dopo una copia dal fornitore) |
help |
Elenco dei comandi |
Mai usare
docker compose down -v,docker volume rmodocker system prune --volumes: cancellano il database.