PortLAB
PortLAB è la piattaforma con cui, al CNR-IFAC (Istituto di Fisica Applicata «Nello Carrara»), si realizzano e si gestiscono portali scientifici: un unico motore, scritto in PHP con database PostgreSQL, da cui nascono siti diversi — multilingua, adattivi e ricchi di contenuti interattivi — condividendo struttura, stile e strumenti.
Che cos'è
PortLAB è un framework leggero per la costruzione di portali. Ogni pagina è definita da una piccola configurazione dichiarativa (in formato JSON) che ne stabilisce struttura, lingue, librerie e livelli di accesso, mentre i contenuti vivono in file separati per lingua. Questo permette di aggiungere pagine e interi siti in tempi rapidi, mantenendo coerenza grafica e funzionale e senza dover toccare il motore.
Progetti realizzati con PortLAB
- WebNIR (webnir.eu) — portale CNR-IFAC sulle radiazioni non ionizzanti: campi elettromagnetici (CEM), radiazioni ottiche artificiali (ROA) e dispositivi medici impiantabili attivi (DMIA), con strumenti per la valutazione dell'esposizione e della schermatura.
- Purple (purplecodex.eu) — portale sui metodi analitici non invasivi applicati ai beni culturali, per lo studio e la catalogazione dei codici purpurei, i manoscritti su pergamena tinta di porpora.
- UISH — Urban Intelligence Science Hub (uish.ifac.cnr.it) — progetto CNR per il gemello digitale della città: l'attività di CNR-IFAC sulla qualità dell'aria a Catania e la validazione del modello AirPortal.
- Eclipsis (eclipsis.ifac.cnr.it) — portale dedicato all'eclissi di Sole del 12 agosto 2026 osservata a La Coruña: la catena di riduzione delle fotografie RAW, dai metadati degli scatti alle effemeridi, eseguita sul server.
- Console di amministrazione — l'interfaccia di gestione della piattaforma stessa, che ospita anche una sezione didattica con esempi interattivi.
Architettura a progetti e personalizzazione
PortLAB è organizzato attorno a un sito principale che funge da base condivisa per tutti i progetti secondari ospitati sulla piattaforma. Ogni progetto dispone dei propri contenuti e delle proprie personalizzazioni locali, ma eredita automaticamente dal sito principale sia il codice comune sia le librerie di terze parti, condivise una sola volta e mantenute in modo centralizzato: nessuna duplicazione e aggiornamenti immediati per tutti. Al tempo stesso ogni progetto può personalizzare qualunque elemento in qualsiasi punto, sostituendo in modo selettivo e indipendente la versione condivisa con una propria versione locale. Ne risulta un'architettura a livelli — elementi locali, comuni e librerie condivise, liberamente combinabili — che consente di avviare rapidamente nuovi portali mantenendo per ciascuno un'identità e un aspetto su misura.
Oltre al codice comune e alle librerie, anche i servizi e gli strumenti offerti da PortLAB (gestione e visualizzazione del database, diagramma dello schema, gestione utenti, consultazione dei log e altro) possono essere ereditati dai progetti secondari tramite collegamenti simbolici al progetto principale: ogni nuovo portale dispone così dell'intero corredo di strumenti senza duplicazione, potendo comunque sostituirne o estenderne qualunque parte in locale.
Interfaccia grafica (GUI)
L'interfaccia si compone di elementi standard basati su Bootstrap — intestazioni, barre di navigazione, menu, breadcrumb, piè di pagina e finestre modali: mattoni indipendenti e riutilizzabili da combinare fino a ottenere la struttura di pagina desiderata, con coerenza visiva e piena responsività.
Template
Il template è il modello di pagina: stabilisce quali elementi di interfaccia usare e come impaginarli, incluso il tipo di menu (orizzontale in alto oppure laterale) e lo stile complessivo. Ogni template è una combinazione predefinita e riutilizzabile di componenti, richiamata da una pagina con un semplice riferimento; cambiando template cambiano aspetto e layout dell'intera pagina senza toccarne i contenuti.
Descrittore di pagina
Ogni pagina è dichiarata da un piccolo file JSON, e la dichiarazione non è un adempimento: senza quel file la pagina non esiste per la piattaforma e il suo indirizzo risponde «non trovato». È la prima maglia del controllo degli accessi. Il descrittore dice quale template usare, chi può aprire la pagina, che cosa caricare e in che ordine, e come la pagina si presenta nel menu.
{
"template": 18,
"profiles": [1],
"flags": { "menu_order": 3 },
"libs": {
"css": ["/css/common/table.css", "/css/common/diagram.css"],
"js": ["/js/libs/jquery-4.0.0.min.js"],
"js_end": ["/js/common/diagram_ui.js"]
}
}
- template — il modello di pagina descritto qui sopra.
- profiles — i profili autorizzati. L'elenco vuoto significa pagina pubblica, non pagina inaccessibile: è l'unica apertura, e va scritta apposta.
- libs — fogli di stile e script nell'ordine esatto in cui vanno caricati, con js prima del corpo della pagina e js_end dopo.
- flags.hide_in_menu — la pagina resta raggiungibile per indirizzo ma non compare nel menu.
- flags.menu_order — il posto della pagina fra i file della sua cartella: numero crescente e, a parità o in assenza di numero, ordine per nome. Il nome scioglie sempre il pareggio, così un numero sbagliato sposta una voce e non riordina la sezione. Serve a tenere l'ordine fuori dai nomi dei file, che sono anche indirizzi. Le cartelle, che un json non ce l'hanno, prendono il numero dalla mappa menu_order di protect/struct.json del progetto; con un numero si mescolano ai file, e così una pagina può stare anche dopo una cartella.
Tutto il resto non è configurazione ma file riconosciuti dal nome: il corpo della pagina, uno per lingua; un dizionario per le stringhe dell'interfaccia Javascript; e, se serve, un file di logica lato server. Aggiungere una pagina significa quindi creare dei file, non modificare un registro centrale — ed è la ragione per cui menu, breadcrumb e motore di ricerca la trovano da soli.
Utenti, accessi e navigazione
Gestione utenti multi-profilo
A ogni utente possono essere associati più profili di autorizzazione. Una risorsa è accessibile quando almeno uno dei profili dell'utente coincide con uno dei profili richiesti dalla risorsa; le pagine senza profili restano pubbliche. Lo stesso criterio governa in modo uniforme l'accesso a pagine e sezioni, le voci di menu, i file scaricabili e persino la visibilità di singole porzioni di una pagina: la stessa pagina può così mostrare contenuti diversi a utenti con profili diversi.
Area riservata
Le pagine pubbliche sono nettamente separate dal codice applicativo e dai contenuti riservati, custoditi in un'area collocata fuori dalla radice web e quindi non raggiungibile direttamente dal browser. I documenti riservati non vengono mai esposti come URL statici: sono consegnati esclusivamente da procedure lato server che, prima dell'invio, verificano identità e profili dell'utente.
Sicurezza e crittografia
Le difese sono trasversali: sessioni protette con token anti-CSRF, rigenerazione dell'identificativo di sessione e cookie con attributi di sicurezza (HttpOnly, Secure, SameSite); password custodite solo come hash; parametri delle query validati e vincolati. I contenuti riservati e i collegamenti «a capacità» sono protetti con crittografia standard (AES-256 con autenticazione HMAC) e chiavi mantenute fuori dal codice sorgente. Il controllo degli accessi è fail-closed: una pagina è raggiungibile solo se esplicitamente configurata, e anche gli endpoint di calcolo lato server sono soggetti ai profili dell'utente. Le richieste a risorse inesistenti vengono ricondotte a pagine di errore standard che riportano alla home.
Generazione dinamica dei menu di navigazione
Il menu non è scritto a mano: viene costruito automaticamente esplorando l'albero delle cartelle e delle pagine. Ogni nuova pagina compare da sola, organizzata su più livelli secondo l'annidamento; le voci sono filtrate in base al profilo dell'utente e a un apposito flag di esclusione, e i titoli sono ricavati dalla pagina nella lingua scelta. L'ordine mette prima i file e poi le sottocartelle; fra i file vale il numero dichiarato nel descrittore della pagina, e a parità — o in sua assenza — il nome. Una sezione si riordina così cambiando un numero, senza rinominare file né spostare indirizzi.
Contenuti, ricerca e privacy
Supporto multilingua
Le lingue disponibili si dichiarano pagina per pagina. Il corpo di ogni pagina risiede in un file separato per ciascuna lingua, mentre le stringhe dell'interfaccia sono gestite da un sistema di traduzione a dizionari che funziona in modo identico in PHP e in Javascript: la stessa funzione e gli stessi dizionari sono disponibili sia lato server sia nel browser. Così è possibile tradurre al volo qualunque stringa, proveniente da qualsiasi sezione della pagina — comprese quelle prodotte da programmi in Python o C++ eseguiti tramite il gateway (gw2py) e restituite alla pagina.
È inoltre disponibile un'estensione per le stringhe parametriche: il testo
tradotto contiene segnaposto numerati (es. {0}, {1})
sostituiti a runtime con i valori effettivi. È un dettaglio essenziale perché in
lingue diverse il parametro può occupare una posizione diversa nella frase:
il segnaposto viene collocato dove serve in ciascuna traduzione, così il testo
resta naturale (ad esempio «{0} elementi trovati» in italiano diventa
«found {0} items» in inglese, con il valore in punti diversi). Tutta la
pipeline è in UTF-8, quindi può ospitare qualsiasi alfabeto; attualmente i portali
sono in italiano e inglese, con un selettore di lingua a bandiera e sigla.
Ricerca testuale interna
Digitando almeno tre caratteri, il sistema esamina le pagine del sito nella lingua attualmente selezionata e mostra i risultati in una finestra dedicata. Per ogni pagina viene presentato un estratto con titolo, parole chiave, descrizione e testo in cui compare il termine cercato, evidenziato nel suo contesto, con collegamento diretto alla pagina. La ricerca gestisce correttamente alfabeti e caratteri internazionali (UTF-8) e può essere mirata, pagina per pagina, ai soli paragrafi rilevanti.
Gestione GDPR
PortLAB include una gestione GDPR pronta all'uso: un'informativa privacy/cookie dedicata e un avviso di consenso riusabile da tutti i siti. La piattaforma è predisposta per l'uso dei soli cookie tecnici, senza profilazione né terze parti; l'avviso è puramente informativo, non blocca la navigazione e ricorda la presa visione per un periodo prestabilito.
Strumenti per il database (PostgreSQL)
Gestione delle tabelle
Un'unica interfaccia riusabile consente di creare, modificare, eliminare e consultare le righe delle tabelle del database, con strumenti di filtro multi-criterio, ordinamento personalizzabile, paginazione e import/export dei criteri in formato JSON.
Visualizzazione ed esplorazione dei dati
Un completo visualizzatore del database riunisce quattro strumenti: un navigatore che esplora database, schemi, tabelle, viste, viste materializzate e funzioni tramite un albero interattivo e filtri a cascata (mostrando struttura, tipi, chiavi, dimensioni e definizioni); un esecutore di query SQL con editor evoluto, esecuzione diretta ed esportazione dei risultati in CSV; una libreria di query memorizzate richiamabili con un clic; e una ricerca per parole chiave su tutti i campi, con filtri per schema, tabella, campo e tipo di dato.
Diagramma grafico dello schema
Un visualizzatore grafico genera un diagramma interattivo dello schema: ogni tabella o vista è un nodo con l'elenco dei campi e la chiave primaria evidenziata. I nodi si trascinano liberamente sul piano di lavoro e i collegamenti tra i campi correlati si tracciano come linee; disposizione, colori e collegamenti vengono salvati e ripristinati a ogni accesso.
Amministrazione e diagnostica
Consultazione dei log del server
Una console di amministrazione permette di consultare i log di Apache — accessi ed errori — filtrando le righe per inclusione o esclusione di una stringa, con la possibilità di nascondere i messaggi informativi o di svuotare il log; una sezione dedicata mostra la configurazione PHP del server. L'accesso è riservato agli amministratori.
Messaggi d'errore standardizzati
Ogni punto critico del codice — query SQL, operazioni PHP, chiamate al gateway Python, script lato client — è marcato da un codice/indice: quando qualcosa va storto compare un messaggio uniforme che riporta quel codice, permettendo di risalire al punto esatto in cui si è verificato il problema. I messaggi sono differenziati per profilo: l'utente vede un avviso essenziale con il codice, mentre all'amministratore vengono mostrati anche i dettagli tecnici (tipo, file, riga, testo della query) utili al debug. Il meccanismo è uniforme per le pagine e per le chiamate AJAX.
Tecnologie
Cuore del funzionamento lato server è un gateway che consente alle pagine di invocare, in modo uniforme, programmi ed elaborazioni scritti in linguaggi diversi — finora Python e C++ — restituendone i risultati (in genere in formato JSON) direttamente nella pagina. Il gateway è usato in modo pervasivo insieme all'interfaccia AJAX di jQuery: questo ha di fatto standardizzato le chiamate in tutto il portale, con un unico schema richiesta/risposta per qualunque operazione dinamica.
- Motore in PHP su Apache/Linux, database PostgreSQL; front-end su Bootstrap 5 e jQuery.
- Pagine configurate in modo dichiarativo (JSON): template, metadati, librerie e profili di accesso, senza modificare il motore.
- Componenti riutilizzabili e calcolo lato server tramite un gateway Python: le pagine possono avviare simulazioni ed elaborazioni e mostrarne i risultati.
- Contenuti scientifici interattivi: grafici (ECharts), formule in LaTeX (KaTeX), visualizzazioni 3D (three.js), codice con evidenziazione della sintassi.
- Procedura guidata per avviare nuovi portali; layout responsive per desktop e mobile.
PortLAB si installa su un server tuo con uno script. Qui prepari lo zip: la copia di PortLAB e i parametri della tua installazione, in un file solo.
In tre passi
- Compila i parametri qui sotto e premi «Prepara lo zip».
- Copia lo zip sul server e scompattalo.
- Lancia lo script da root. Installa i pacchetti, crea il database, configura Apache e il certificato, e alla fine prova la home.
Istruzioni
Che cosa serve
- Un server con Ubuntu 26.04 LTS e l'accesso da root. Ubuntu 26.04 ha nel suo archivio PHP 8.5 e PostgreSQL 18, quindi non servono repository esterni.
- Un nome di dominio che punta al server serve solo al certificato di Let's Encrypt, che controlla il dominio sulla porta 80: la porta dev'essere raggiungibile da Internet. Senza, lo script mette un certificato autofirmato. Il sito risponde sulla 443, che va aperta a chi lo usa.
- L'uscita verso Internet durante l'installazione: lo script scarica i pacchetti di Ubuntu (apt), le librerie PHP (Composer) e quelle Python (pip).
- Un server di posta per le e-mail del sito, con host, porta e cifratura e, se li chiede, utente e password. Senza, il sito funziona ma la registrazione e il recupero della password non mandano e-mail.
I comandi
Dal tuo computer, copia lo zip sul server ed entra:
scp portlab-<nome>.zip utente@server:
ssh utente@server
Sul server, scompatta e lancia lo script da root:
python3 -m zipfile -e portlab-<nome>.zip .
sudo bash portlab/webadmin/install/install.sh
rm portlab-<nome>.zip
Per scompattare basta Python, che su Ubuntu c'è già. L'ultima riga cancella lo zip, che contiene le password; il file dei parametri lo cancella lo script quando ha finito.
Che cosa fa lo script
- Controlla i parametri. Se uno non va bene si ferma e li elenca, prima di toccare qualunque cosa.
- Installa i pacchetti: Apache con PHP e il gateway Python, PostgreSQL, Composer, WeasyPrint, i caratteri per i PDF, pdftotext e certbot.
- Crea l'utente e copia i file nella cartella scelta, con le librerie PHP e Python.
- Crea il database: i due ruoli, lo schema, i dati di riferimento (lingue, convenzioni locali, espressioni regolari, profili), il sito e l'amministratore.
- Scrive la configurazione: la chiave dei token, le credenziali del database per il server web, il nome del sito, la posta, robots.txt e security.txt.
- Configura Apache con il vhost che la Diagnostica si aspetta, gli apre in scrittura la cartella di PortLAB con una regola di systemd (Ubuntu 26.04 gliela lascerebbe in sola lettura) e chiede il certificato.
- Imposta i permessi delle cartelle in cui scrive il server web e programma i lavori notturni: le pulizie e l'indice della ricerca.
- Prova la home e stampa l'indirizzo del sito. Se la password dell'amministratore l'ha generata lo script, la stampa qui, una volta sola.
Dopo l'installazione
Apri il sito, entra con l'indirizzo e la password dell'amministratore e apri Gestione > Progetti > Diagnostica. Dice che cosa resta da sistemare, e per molti controlli dà il comando che lo sistema.
Se qualcosa non va
- Si può rilanciare. Lo script rifà i passi senza cancellare niente: la chiave dei token resta la stessa, e lo schema del database non si ricarica se c'è già. I parametri però vanno rimessi, perché il file è stato cancellato.
- Il certificato non arriva quando il dominio non punta ancora al server o la porta 80 è chiusa. Resta quello autofirmato; sistemato il DNS, basta rilanciare lo script.
- La home non risponde: il motivo è in
/var/log/apache2/error.log. - Il registro dice «Read-only file system»: Apache non ha la regola di systemd che gli apre la cartella di PortLAB (vedi Configurare a mano).
I pacchetti
Lo script li installa da sé. Chi prepara il server a mano, o vuole sapere che cosa arriva, trova qui l'elenco completo.
Pacchetti del sistema (Ubuntu 26.04)
| Pacchetto | A che cosa serve |
|---|---|
apache2 | il server web |
libapache2-mod-php8.5 | PHP dentro Apache, per le pagine |
libapache2-mod-wsgi-py3 | il gateway Python gw2py dentro Apache |
php8.5-cli | PHP da riga di comando: lo script, l'indice della ricerca, i lavori notturni |
php8.5-pgsql | PHP con PostgreSQL |
php8.5-gd | le immagini: miniature e grafici |
php8.5-mbstring | i testi in UTF-8 |
php8.5-curl | le richieste del server ad altri siti: Diagnostica, accesso con fornitori esterni |
php8.5-xml | XML, per i fogli di calcolo e le importazioni |
php8.5-zip | gli archivi zip dei fogli di calcolo |
php8.5-bcmath | l'aritmetica a precisione arbitraria |
php8.5-intl | date e numeri scritti secondo la lingua |
postgresql | il database, con le estensioni pg_trgm, dblink e postgres_fdw |
python3-venv, python3-pip | l'ambiente Python del gateway e i suoi pacchetti |
composer, unzip | le librerie PHP: PHPMailer per la posta, PhpSpreadsheet per i fogli di calcolo |
rsync | la copia dei file nella cartella scelta |
ssl-cert | il certificato autofirmato, se Let's Encrypt non risponde |
certbot | il certificato di Let's Encrypt e il suo rinnovo |
librsvg2-bin | rsvg-convert, che fa i PDF degli editor di diagrammi e di Gantt |
fonts-ibm-plex, fonts-roboto, fonts-jetbrains-mono, fonts-nunito | i caratteri di quei PDF |
weasyprint | i PDF fatti da pagine HTML, per le esportazioni dei progetti |
poppler-utils | pdftotext, che legge il testo dei PDF del sito per la ricerca |
g++, make | i programmi C++ che il gateway può eseguire |
curl | la prova della home alla fine dell'installazione |
ca-certificates | le autorità che firmano i certificati: posta, Let's Encrypt, CDN |
A mano, tutti insieme:
sudo apt install apache2 libapache2-mod-php8.5 libapache2-mod-wsgi-py3 \
php8.5-cli php8.5-pgsql php8.5-gd php8.5-mbstring php8.5-curl php8.5-xml php8.5-zip \
php8.5-bcmath php8.5-intl postgresql python3-venv python3-pip composer unzip rsync ssl-cert \
certbot librsvg2-bin fonts-ibm-plex fonts-roboto fonts-jetbrains-mono fonts-nunito poppler-utils \
weasyprint g++ make curl ca-certificates
Pacchetti Python del gateway gw2py
Il gateway gira in un ambiente Python suo, <cartella>/venvs/webadmin, con lo
stesso Python di mod_wsgi. I pacchetti stanno in wsgi-scripts/requirements.txt:
| Pacchetto | Versione | A che cosa serve |
|---|---|---|
multipart | 2.0.0 | legge i moduli e i file che le pagine mandano al gateway: è il solo pacchetto che serve a gw2py |
psycopg2-binary | 2.9.12 | PostgreSQL da Python, per il generatore delle console (gen_table_page.py) |
waitress | 3.0.2 | solo per lo sviluppo: il gateway senza Apache (pyapp_server.py) |
Il resto del gateway (l'autorizzazione, i lavori lunghi, il convertitore dei PDF, il controllo delle immagini) usa solo la libreria standard di Python. A mano:
python3 -m venv /home/portlab/venvs/webadmin
/home/portlab/venvs/webadmin/bin/pip install -r /home/portlab/wsgi-scripts/requirements.txt
Configurare a mano Apache, PHP e PostgreSQL
Lo script fa tutto da sé. Per chi preferisce farlo a mano, o vuole vedere che cosa scrive, lo
zip ha nella cartella portlab/conf i file già compilati con i parametri del modulo.
I comandi qui sotto usano i valori predefiniti (la cartella /home/portlab, il
database boot): con altri valori vanno cambiati.
Apache
conf/apache/<nome>.conf: il vhost http, che manda tutto su https tranne le prove con cui Let's Encrypt controlla il dominio;conf/apache/<nome>-ssl.conf: il vhost https, con il gateway Python, le intestazioni di sicurezza e le cartelle protette. È quello che la Diagnostica si aspetta.
Prima il vhost http e il certificato, poi quello https, che nomina già i file del certificato:
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork ssl headers wsgi php8.5
sudo cp portlab/conf/apache/*.conf /etc/apache2/sites-available/
sudo a2dissite 000-default
sudo a2ensite <nome> && sudo systemctl reload apache2
sudo certbot certonly --webroot -w /home/portlab/website -d <dominio> -m <e-mail> --agree-tos
sudo a2ensite <nome>-ssl && sudo apachectl configtest && sudo systemctl reload apache2
Con il certificato autofirmato il passo di certbot non serve: il vhost https usa quello del
pacchetto ssl-cert.
Su Ubuntu 26.04 systemd chiude Apache in una gabbia: fra l'altro /home,
/usr ed /etc sono in sola lettura, e il sito non scrive nelle sue
cartelle anche con i permessi giusti (nel registro: «Read-only file system»). La regola
conf/systemd/portlab-<nome>.conf gli riapre la cartella di PortLAB; dove si
scrive lo decidono ancora i permessi dei file.
sudo mkdir -p /etc/systemd/system/apache2.service.d
sudo cp portlab/conf/systemd/portlab-<nome>.conf /etc/systemd/system/apache2.service.d/
sudo systemctl daemon-reload && sudo systemctl restart apache2
PHP
Le impostazioni stanno in due file, uno per il sito e uno per la riga di comando:
sudo cp portlab/conf/php/apache2/99-portlab.ini /etc/php/8.5/apache2/conf.d/
sudo cp portlab/conf/php/cli/99-portlab.ini /etc/php/8.5/cli/conf.d/
sudo systemctl reload apache2
| Impostazione | Valore | Perché |
|---|---|---|
post_max_size, upload_max_filesize | 200M | i file di misura e le immagini che si caricano |
max_file_uploads | 200 | molti file in un solo caricamento |
memory_limit | 512M | il tetto di una richiesta; le pagine che leggono file grandi lo alzano da sé |
session.gc_maxlifetime | 43200 | la sessione dura 12 ore senza attività, come vuole PortLAB |
expose_php, display_errors | Off | niente versione nelle risposte e niente errori nelle pagine: vanno nel registro di Apache |
date.timezone | il fuso del modulo | le date delle e-mail e dei registri |
pcre.jit | 0 | solo per il sito: la gabbia di systemd di Apache non dà memoria eseguibile, e la compilazione delle espressioni regolari riempirebbe il registro di avvisi |
Le estensioni che servono sono pgsql, gd, mbstring, curl, xml, zip, bcmath e intl (i pacchetti
php8.5-*), più sodium e openssl, che PHP ha già. La Diagnostica le controlla una per
una.
PostgreSQL
PortLAB vuole PostgreSQL 18 sulla stessa macchina, raggiunto in TCP su localhost con una password. Su Ubuntu i valori predefiniti vanno già bene:
listen_addresses = 'localhost'inpostgresql.conf: il database non si apre alla rete;host all all 127.0.0.1/32 scram-sha-256inpg_hba.conf: le pagine entrano con le password del.pgpass.
Il database lo creano i file di webadmin/install/sql, in quest'ordine. Ognuno dice
in testa quali variabili di psql vuole (nomi e password dei ruoli, il sito, l'amministratore):
install/database.sh le passa da sé.
01_database.sql, da postgres: i due ruoli, il database (del ruolo che scrive) e le estensioni pg_trgm, dblink e postgres_fdw;02_schema.sql, con il ruolo che scrive, che diventa il proprietario di tutto;03_permessi.sql, da postgres: la lettura al ruolo che legge, anche per gli oggetti che verranno;04_dati.sql, da postgres: lingue, bandiere, convenzioni locali, fusi orari, espressioni regolari e profili;05_sito.sql, con il ruolo che scrive: il sito, le sue lingue e l'amministratore.
Il server web trova le credenziali in /var/www/.pgpass, di www-data con i permessi
0600. Ogni riga ha sopra un'intestazione: #conn_p per il ruolo che legge,
#conn_a per quello che scrive.
#conn_p
localhost:5432:boot:portlab_ro:<password>
#conn_a
localhost:5432:boot:portlab_rw:<password>
Su una macchina dedicata si può dare a shared_buffers un quarto della memoria; per
il resto bastano i valori di Ubuntu. Le copie del database si fanno con pg_dump, per esempio ogni
notte: sudo -u postgres pg_dump -Fc boot > /var/backups/boot.dump.
Licenze
Il codice di PortLAB è distribuito con la licenza EUPL-1.2, i contenuti con
CC BY 4.0; le librerie di terzi hanno le loro, elencate nella cartella
LICENSES della copia. Le librerie JavaScript arrivano da jsDelivr, con
l'impronta che il browser controlla.
Keywords: PortLAB, CMS, framework PHP, portali scientifici, multilingua, PostgreSQL, CNR-IFAC