Skip to content

About

CKAN DCATAPIT HVD PG16

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

173 Commits

Folders and files

Repository files navigation

CKAN Docker per l'Italia

Note

Stack CKAN 2.10.11 + PostgreSQL 16 + Solr 9 + Redis + NGINX, già predisposto per le funzionalità dei cataloghi open data italiani. Pensato per essere provato in locale e poi spostato su un dominio reale cambiando una sola variabile (CKAN_SITE_URL). Leggere il CHANGELOG per i passaggi più delicati legati all'harvesting dei cataloghi federati.

Warning

La serie CKAN 2.10 ha raggiunto la fine del supporto: il progetto CKAN non rilascia più aggiornamenti, nemmeno di sicurezza. Vedi la sezione Sicurezza e aggiornamenti.

Cosa include

  • DCAT-AP_IT — estensione ckanext-dcatapit (Geosolutions) adeguata a CKAN 2.10.10.
  • OAI-PMH — ckanext-oai-pmh-server (con supporto DataCite/OpenAIRE).
  • Harvesting — ckanext-harvest + harvester CKAN, RDF e DCAT-JSON.
  • Linked Open Data / RDF — ckanext-dcat (profili euro_dcat_ap_2, it_dcat_ap) con export catalog.rdf / catalog.ttl e /dataset/{id}.rdf.
  • MQA / data.europa.eu — ckanext-dcat-ap-edp-mqa (disattivabile, vedi sotto).
  • Multilingua (ckanext-multilang) e Xloader per il DataStore.

Prerequisiti


Configurazione (.env)

Tutta la configurazione passa dal file .env. Si parte da .env.example: tutte le variabili hanno default sensati per un test locale, e l'unico blocco realmente da toccare è quello in cima al file (>>> DA MODIFICARE <<<).

Variabili chiave:

Variabile A cosa serve
CKAN_SITE_URL URL pubblico del portale, senza slash finale. Da qui vengono derivati automaticamente ckanext.dcat.base_uri e l'URL base OAI-PMH.
CKAN_SYSADMIN_NAME / CKAN_SYSADMIN_PASSWORD Utente e password del primo amministratore.
CKAN___BEAKER__SESSION__SECRET, CKAN___API_TOKEN__JWT__*__SECRET Segreti di sessione e dei token API. Lasciare le righe commentate: vengono generati casuali al primo avvio e conservati nel volume ckan_storage. Se si valorizzano a mano, mai con valori noti o di esempio.
NGINX_PORT_HOST / NGINX_SSLPORT_HOST Porte host per accesso non-SSL e SSL.
GEONAMES_USERNAME Username GeoNames per il geocoding (default demo).
CKAN_OAIPMH_BASE_URL (opzionale) forza l'URL base OAI; se vuoto usa ${CKAN_SITE_URL}/oai.
CKANEXT__DCATAPIT__ACCESSIBILITY_STATEMENT_URL URL della dichiarazione di accessibilità (per le PA è obbligatoria, Linee guida AgID: quella pubblicata su form.agid.gov.it). Se valorizzato, il footer mostra il link «Dichiarazione di accessibilità»; vuoto (default) = nessun link.
CKANEXT__DCATAPIT__FOOTER_REBUILT_BY Nome mostrato nel footer dopo «rebuilt by» (es. il fornitore che gestisce l'istanza). Vuoto (default) = AgID.
CKAN_CUSTOM_CSS_DEFAULT / CKAN_CUSTOM_CSS_FORCE Tema predefinito accessibile (WCAG 2.1 AA) in ckan/css.example: con true (default) all'avvio viene impostato come «Custom CSS» (Admin → Config) se l'admin non ne ha uno proprio, e aggiornato alle nuove versioni finché l'admin non lo modifica (script docker-entrypoint.d/05_custom_css.sh). false non tocca mai il Custom CSS. CKAN_CUSTOM_CSS_FORCE=true lo sovrascrive col predefinito al prossimo avvio. Per tornare al predefinito basta anche svuotare il Custom CSS dall'admin e riavviare.

Demo locale vs dominio reale

Basta impostare CKAN_SITE_URL

  • HTTP locale: CKAN_SITE_URL=http://localhost:8080
  • HTTPS locale: CKAN_SITE_URL=https://localhost:8443
  • IP privato: CKAN_SITE_URL=http://192.168.1.50:8080
  • Produzione: CKAN_SITE_URL=https://dati.miocomune.it

SSL o non-SSL

NGINX espone entrambi gli accessi contemporaneamente:

  • non-SSL → http://<host>:${NGINX_PORT_HOST} (default 8080)
  • SSL → https://<host>:${NGINX_SSLPORT_HOST} (default 8443, certificato self-signed generato in automatico al primo avvio).

Si usa quello che si preferisce; CKAN_SITE_URL deve coerentemente puntare allo schema/porta scelti. In produzione, terminare il TLS con un certificato valido (es. reverse proxy esterno o sostituendo il cert in nginx/certs).


Primo avvio (passi esatti)

Eseguire i comandi in ordine, aspettando il completamento di ciascuno.

  1. Clonare e preparare il .env:

    git clone https://github.com/piersoft/ckan-docker-ita.git
    cd ckan-docker-ita
    cp .env.example .env
  2. Modificare nel .env almeno CKAN_SITE_URL e CKAN_SYSADMIN_PASSWORD (vedi tabella sopra).

  3. Costruire le immagini:

    docker compose build
  4. Avviare lo stack:

    docker compose up -d
  5. Attendere che CKAN sia healthy (il primo avvio carica i vocabolari DCAT-AP_IT e può richiedere alcuni minuti):

    docker compose ps
  6. Creare i gruppi tematici, una sola volta (i gruppi restano nel database, anche dopo un rebuild; se rilanciato, i gruppi già presenti vengono saltati):

    docker compose exec ckan bash /srv/app/setup_groups.sh

Il portale è ora raggiungibile all'indirizzo impostato in CKAN_SITE_URL.

Note

Dopo un nuovo docker compose build il passo 6 non va ripetuto: i gruppi sono nel database e l'assegnazione dei dataset ai gruppi usa il file patches/theme_to_group.ini incluso nell'immagine.


Comandi utili

  • Build (ricostruire le immagini):

    docker compose build
  • Start / Stop:

    docker compose up -d
    docker compose down          # ferma e rimuove i container (i volumi restano)
  • CKAN in stato unhealthy — riavviare CKAN, attendere 2-3 minuti, poi riavviare NGINX:

    docker compose restart ckan
    sleep 180
    docker compose restart nginx
  • Setup iniziale dei gruppi (vedi passo 6):

    docker compose exec ckan bash /srv/app/setup_groups.sh
  • Log in tempo reale:

    docker compose logs -f ckan
  • Reset totale (cancella anche i dati: DB, indice Solr, storage):

    docker compose down -v

Sicurezza e aggiornamenti

  • Fine del supporto di CKAN 2.10. Le vulnerabilità di CKAN scoperte dopo la 2.10.11 non verranno corrette in questa serie. Tenerne conto nel valutare l'esposizione del portale e pianificare il passaggio a una versione supportata.

  • Aggiornare periodicamente le immagini. Gli aggiornamenti di sicurezza del sistema operativo e delle librerie entrano solo ricostruendo le immagini con le basi aggiornate (consigliato almeno una volta al mese e dopo ogni aggiornamento del repository):

    git pull
    docker compose build --pull
    docker compose up -d

    docker compose up -d ricrea solo i container cambiati; dati, database, indice Solr e file caricati restano nei volumi.

  • Esporre solo NGINX. Solr, Redis e PostgreSQL stanno su reti Docker interne e non vanno pubblicati sull'host (non aggiungere ports: a quei servizi). In produzione usare HTTPS con un certificato valido.

  • Segreti. Non impostare nel .env valori noti o di esempio per i segreti di sessione e dei token API: lasciando le righe commentate vengono generati al primo avvio (vedi la tabella della configurazione). Il file .env contiene password e segreti: renderlo leggibile solo dall'amministratore (chmod 600 .env).

  • Password dell'amministratore. Cambiare CKAN_SYSADMIN_PASSWORD prima del primo avvio; in seguito la password si cambia dal profilo utente.


Verifica delle funzionalità

  • Catalogo RDF: ${CKAN_SITE_URL}/catalog.rdf e .../catalog.ttl
  • RDF del singolo dataset: ${CKAN_SITE_URL}/dataset/{id}.rdf
  • OAI-PMH: ${CKAN_SITE_URL}/oai?verb=Identify, .../oai?verb=ListMetadataFormats, .../oai?verb=ListRecords&metadataPrefix=oai_dc
  • Harvesting: interfaccia in ${CKAN_SITE_URL}/harvest

Validazione SHACL con il profilo di data.europa.eu

tools/validate_edp_shacl.py valida il catalog.ttl con le stesse shape che usa data.europa.eu, cosi' da vedere violazioni e warning prima che compaiano sul portale europeo. Non usa le shape SEMIC "pure": scarica shapes.ttl + deprecateduris.ttl dal progetto piveau-metrics-validating-shacl, cioe' il profilo "DCAT-AP 3.0.1 Level 1" con cui EDP valida i metadati harvestati. Piveau aggiunge regole proprie che nelle shape SEMIC non esistono.

pip install rdflib pyshacl

# un singolo dataset
python3 tools/validate_edp_shacl.py https://dati.gov.it/opendata --name NOME-DATASET

# le prime 3 pagine del catalogo (100 dataset per pagina)
python3 tools/validate_edp_shacl.py https://dati.gov.it/opendata --pages 3

# tutto il catalogo: legge tutte le pagine fino all'hydra:lastPage
python3 tools/validate_edp_shacl.py https://dati.comune.lecce.it --pages tutte

# solo un ente
python3 tools/validate_edp_shacl.py https://dati.gov.it/opendata --fq organization:NOME-ENTE

# un TTL gia' scaricato
python3 tools/validate_edp_shacl.py --file catalog.ttl

# aggiunge anche le shape raccomandate, piu' severe del profilo EDP
python3 tools/validate_edp_shacl.py https://dati.gov.it/opendata --level 2

Altre opzioni: --dcatap per la versione delle shape (default 3.0.0, quella indicata nei report DQV di EDP), --examples per quanti esempi mostrare di ogni segnalazione, --json FILE per salvare il riepilogo. Codice di uscita: 0 se non ci sono Violation, 1 se ce ne sono, 2 in caso di errore — quindi si puo' usare in una pipeline.

Le shape vengono scaricate una volta e messe in cache nella directory temporanea del sistema. Due avvertenze pratiche: serve rete verso gitlab.com, e dati.gov.it va interrogato senza www, perche' il WAF blocca le richieste che non arrivano da un browser.

Ogni pagina viene validata separatamente, come fa EDP: unire le pagine in un unico grafo duplicherebbe i nodi anonimi dei sottocataloghi e produrrebbe falsi errori di cardinalita' sul publisher.

Come leggere l'esito

Violation sono non conformita' da correggere. Warning no: molti vengono dalle shape di deprecazione di piveau, che segnalano cambi di vocabolario fra DCAT-AP 2.1 e 3.0 e in alcuni casi penalizzano proprio il vocabolario nuovo. Prima di inseguire un warning conviene leggere la shape che lo genera nei file in cache, perche' non sempre indica un errore nei metadati.

Profili italiani: DCAT-AP_IT, vocabolari, HVD

Con --profile lo stesso script valida anche secondo le regole italiane. Le shape stanno in tools/shapes/ e non vengono scaricate.

Profilo Cosa controlla Fonte
edp (default) shape di piveau usate da data.europa.eu piveau-metrics-validating-shacl
dcatapit identificativo, titolare (dct:rightsHolder), frequenza, temi, data di modifica; soggetti con dct:identifier e foaf:name non vuoti; punto di contatto con vcard:fn e vcard:hasEmail; formato, URL di accesso e licenza della distribuzione; tipi dcatapit:* Linee guida AgID per i cataloghi dati
vocabolari temi sui 14 valori EU data-theme, frequenza, lingua, formato, diritti di accesso, media type IANA, URI ELI, categorie HVD authority table EU
hvd dcatap:applicableLegislation con l'ELI del Reg. UE 2023/138 e dcatap:hvdCategory su dataset, distribuzioni e servizi Guida operativa AgID sui dati di elevato valore v1.0 (azione #hvd14), DCAT-AP HVD 2.2.0
agid identificativo del dataset codiceIPA:identificativo (dopo i due punti solo lettere, cifre, ., - e _) con il prefisso uguale al codice IPA del titolare; codice IPA del titolare senza caratteri speciali e presente nell'elenco enti di IndicePA (verifica in linea, --no-ipa per saltarla); email dell'editore del catalogo e dei sottocataloghi non PEC; tema o formato OP_DATPRO («dati provvisori», segnaposto) e formato ARC (quasi sempre un errore), contati nel riepilogo Indicazioni operative AgID per l'harvesting su dati.gov.it (non regole DCAT): escono come Info e non cambiano l'esito

Nel profilo dcatapit le proprieta' obbligatorie producono una Violation, le raccomandate un Warning. Il profilo hvd si applica solo alle risorse che dichiarano l'ELI 2023/138 o una categoria HVD, alle loro distribuzioni e ai servizi che le servono: le shape HVD ufficiali di SEMIC assumono invece un catalogo interamente HVD. Per i vocabolari i temi sono controllati sull'elenco chiuso dei 14 valori, gli altri valori sul namespace dell'URI; formati e media type sugli elenchi chiusi di data.europa.eu, gli stessi usati dall'MQA.

Gli elenchi di formati (vocabolario EU file-type) e media type (registro IANA) stanno in tools/shapes/vocabolari-elenchi.ttl, generato da tools/aggiorna_vocabolari.py a partire dalle API https://data.europa.eu/api/hub/search/vocabularies/{file-type,iana-media-types}. Non si aggiorna da solo: si lancia a mano e poi si ricostruisce la pagina web.

python3 tools/aggiorna_vocabolari.py      # riscrive tools/shapes/vocabolari-elenchi.ttl
cd tools/validatore-web && npm run build  # per il validatore web

I media type si confrontano su tipo/sottotipo, senza distinguere http/https, www e maiuscole (EDP accetta anche gli https://iana.org/... di CKAN); i formati sull'URI esatto.

Il profilo agid raccoglie criteri di gestione del catalogo nazionale, non regole DCAT: identificativi univoci e riconducibili all'ente, e un'email ordinaria (PEO) per contattare chi gestisce il catalogo. Non essendo regole, tutte le segnalazioni sono Info ("indicazioni", in viola nella pagina) e non rendono il catalogo non conforme. La PEC si riconosce in modo euristico (pec come parte dell'indirizzo, cert., gestori PEC noti). Non e' incluso in it; lo e' in tutti.

Il codice IPA del titolare (dct:rightsHolder/dct:identifier) deve comparire, scritto esattamente allo stesso modo (maiuscole comprese: UNITO, non unito), nel dataset "enti" di IndicePA (https://indicepa.gov.it/ipa-dati, API datastore_search_sql); il vecchio dataset "amministrazioni" e' nel formato precedente al 2021 e IndicePA stesso rimanda a "enti". A IndicePA si inviano solo i codici, gia' filtrati sul formato. Se il codice non e' di un ente ma di una sua unita' organizzativa, o e' un codice fiscale, la segnalazione indica il codice IPA da usare. Se IndicePA non risponde la verifica viene saltata e lo si dice nel risultato.

Prima dell'harvesting va sempre verificato che l'endpoint del catalogo e, a campione, le risorse rispondano 200 a una richiesta HEAD (curl -I <url>), senza WAF o filtri su IP e User-Agent: i dati aperti devono essere accessibili e interoperabili. Il validatore non lo controlla: il risultato dipende da chi fa la richiesta, e quello che conta e' l'harvester.

# EDP + tutti i profili italiani + regole operative AgID
python3 tools/validate_edp_shacl.py --file catalog.ttl --profile tutti

# solo i profili italiani (it = dcatapit,vocabolari,hvd)
python3 tools/validate_edp_shacl.py https://dati.gov.it/opendata --pages 2 --profile it

--file accetta anche RDF/XML e JSON-LD.

Report settimanale per PA

tools/report_settimanale.py valida ogni settimana i cataloghi di tutte le PA presenti su dati.gov.it, con gli stessi profili del validatore web, e scrive una cartella con un report per PA:

validazione/
├── index.html            pagina generale, ordinata per gravita'
├── riepilogo.csv         una riga per PA
└── <slug>/
    ├── index.html        report della PA
    └── <slug>.csv        elenco puntuale delle segnalazioni
  • Per le PA con una harvest source DCAT-RDF valida il catalogo sorgente: la pagina 1, oppure, oltre 2.000 dataset, un campione di 6 pagine distribuite (prima, seconda, meta', ultima e alcune a caso, con un seme che cambia ogni settimana). Per le PA senza sorgente RDF (dataset inseriti dal front end, sorgenti CKAN o JSON) valida il catalogo esposto da dati.gov.it per l'organizzazione.
  • Controlla anche che l'endpoint del catalogo e tre risorse a caso rispondano 200 (HEAD, oppure GET con Range se HEAD non e' ammesso).
  • I codici IPA dei titolari di tutte le PA vengono verificati su IndicePA con un'unica serie di query.
  • L'avviso noto su adms:status (StatusRestrictionADMS) non entra nei CSV: viene solo contato.
  • Con --telegram FILE (JSON con token e chat_id) invia un riepilogo e il riepilogo.csv a un bot Telegram. run_validazione.sh lo cerca come report-validazione.json nella propria cartella; va tenuto con permessi 600 e fuori dalla web root.

Per un server senza librerie Python installabili, tools/build_report_pyz.sh crea tools/dist/report_settimanale.pyz, un unico file con lo script, le regole e le librerie (rdflib, pyshacl e dipendenze, tutte in puro Python): basta Python 3.9 o successivo.

tools/build_report_pyz.sh
python3 report_settimanale.pyz --out validazione --limit 10      # prova sulle prime 10 PA
python3 report_settimanale.pyz --out validazione --org regione-toscana

tools/script_validazione/run_validazione.sh e' lo script da mettere in cron: scrive in una cartella temporanea e la sostituisce solo a esecuzione riuscita, cosi' durante il lavoro resta visibile il report precedente. La cartella di uscita (OUT, obbligatoria) e l'indirizzo pubblico del report (URL, facoltativo) si scrivono in run_validazione.conf accanto allo script, che resta fuori dalla repo (.gitignore) come il file Telegram.

Validatore nel browser

tools/validatore-web/ contiene la stessa validazione come pagina web: si carica un file (Turtle, RDF/XML, N-Triples, JSON-LD), si scelgono i profili e si ottiene l'elenco delle segnalazioni raggruppate per regola, con esempi ed esportazione in JSON o CSV. Tutto avviene nel browser, il file non viene inviato a nessun server. Nella scheda CKAN l'opzione «Tutte le pagine del catalogo» scarica e valida una dopo l'altra tutte le pagine del catalog.ttl (si puo' interrompere a meta') e restituisce un unico report. Le shape EDP sono incluse nella pagina (licenza Apache 2.0, Fraunhofer FOKUS) invece di essere scaricate.

Il manuale d'uso e di interpretazione dei risultati (bozza, in attesa di approvazione), con l'elenco dei messaggi e il modo di correggerli, e' in tools/docs/Manuale_Validatore_DCAT-AP_IT.pdf.

La pagina e' pubblicata su GitHub Pages dal workflow .github/workflows/validatore-pages.yml, che riparte a ogni modifica della pagina o delle shape. Per costruirla in locale:

cd tools/validatore-web
npm ci
npm run build          # produce dist/index.html, un file unico
node test/run.mjs catalog.ttl   # stessa validazione da riga di comando

La scheda "CKAN" scarica direttamente catalog.ttl da un portale, ma funziona solo se il server permette la lettura da altre pagine (CORS). Con i portali che non lo permettono, dati.gov.it compreso, si scarica il file e lo si carica dalla scheda "File".

Sugli stessi file la pagina e lo script Python danno gli stessi conteggi, per profilo e per gravita'.


Note sulle patch (harvesting cataloghi federati)

Le patch nei file processors.py, rdf.py, profiles.py (dentro ckan/patches e nelle estensioni ckanext-dcat / ckanext-dcatapit incluse) nascono dall'analisi degli harvesting dei cataloghi nazionali, regionali e comunali su dati.gov.it. Servono a "neutralizzare" metadati incompleti o non conformi dei cataloghi remoti, così che l'export finale in Linked Open Data resti corretto. Per un'installazione stand-alone (senza harvesting di cataloghi terzi) la maggior parte di queste patch non incide.

Dettagli ed esempi nel CHANGELOG.

Disattivare l'integrazione OpenAIRE / MQA

Se non serve l'integrazione con OpenAIRE/data.europa.eu:

  1. rimuovere dcat_ap_edp_mqa dalla variabile CKAN__PLUGINS nel .env;
  2. rimuovere dcat_ap_edp_mqa da ckanext.dcat.rdf.profiles in ckan/docker-entrypoint.d/02_ckan-init.sh.

Crediti

About

CKAN DCATAPIT HVD PG16

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages