Installazione

La distribuzione dei servizi della piattaforma avviene mediante immagini docker, non ci sono requisiti particolari in merito all'orchestratore utilizzato (docker swarm, kubernetes, nomad, mesos).

Requisiti

Il core della piattaforma richiede le seguenti versioni minime dei runtime:

  • PHP >= 8.3

  • Node.js >= 22.x

  • PostgreSQL >= 11 con estensione PostGIS >= 3

Installazione ambiente di Test / Sviluppo

Per una installazione di test su singolo nodo si consiglia di usare il service compose presente nei due repository principali:

Installazione ambiente di Produzione

Per un ambiente di produzione è indispensabile predisporre un ambiente con adeguati livelli di ridondanza e dimensionamento dei singoli servizi in base alla propria infrastruttura e ai propri requisiti in termini di affidabilità e livelli di servizio da garantire.

Non c'e' una ricetta valida a priori per dimensionare il sistema, si consiglia di partire da una configurazione con 2 repliche di ogni servizio stateless e un dimensionamento molto largo (es: 1GB di ram, 1 vCPU) e poi monitorare il proprio sistema per stabilire i requisiti di ogni singolo container: si potrà verificare facilmente che molti microservizi richiedono pochi Mb di ram.

Elenco dei servizi necessari

Ogni servizio si basa su una immagine docker specifica e necessita di adeguate configurazioni. Le configurazioni e i valori di default delle stesse sono documentate nei singoli repository dei microservizi.

Al fine di dare una corretta configurazione dei vari servizi vengono indicate inoltre:

  1. la dipendenza dalle persistenze usate dalla piattaforma

  2. la necessità di pubblicare un endpoint per quel servizio pubblicamente raggiungibile

Sito istituzionale

Servizio
Descrizione
Docker Image
Pubblico

cms-core

Servizio principale del CMS, consente l'accesso della radazione per la gestione dei contenuti e fornisce l'interfaccia di navigazione per i cittadini

PostgreSQLRedisFiles storage

solr

Motore di ricerca in cui il cms indicizza i contenuti per rendere performante la ricerca sul sito

Files storage

varnish

Http cache usata davanti al CMS per ridurre il carico sul CMS stesso.

Servizi digitali e Area Personale

Servizio
Descrizione
Docker Image
Pubblico
Persistenza

app-web

Servizio principale della piattaforma, gestisce pratiche, appuntamenti, offre interfacce di configurazione per gli amministratori e di gestione operativa per i funzionari degli enti. E' inoltre l'interfaccia principale anche per l'esperienza utente.

PostgreSQLFile StorageRedis

app-worker

Esecuzione delle operazioni asincrone del Core (creazione PDF, invio di messaggi, webhooks, ...)

PostgreSQLFile Storage

app-manager

Esecuzione delle migrazioni database

PostgreSQL

app-varnish

Http cache per scaricare l'app-web

form-server

Server delle form (Form.IO)

MongoDB

form-varnish

Http cache per scaricare il form-server

form-builder

Applicativo per la gestione dei subform condivisi da tutti i moduli form.io

payment- dispatcher-v1

Genera, se necessario, un evento Versione 1 di pagamento da un evento di una pratica

Kafka

payment- dispatcher-v2

Genera, se necessario, un evento Versione 2 di pagamento da un evento di una pratica

Kafka

payment-updater

Ascolta sul topic di kafka dei pagamenti e aggiorna lo stato delle pratiche di conseguenza

Kafka

gotenberg

API interna per la creazione di file PDF

ksqldb

Ascolta su tutti i topic di kafka ed espone via API dati aggregati sugli eventi della piattaforma

Kafka

kafka-core-api

Espone un endpoint http che il core usa per inviare eventi sui topic di kafka

KafkaFile Storage

payments poller

Legge da Ksql i pagamenti pendenti e per ognuno di essi chiama il proxy che lo gestisce per aggiornare lo stato del pagamento

XXX-payment proxy

Servizio per l'integrazione con l'intermediario di pagamento XXX (vedi Integrazioni per la lista completa)

KafkaFile Storage

YYY-protocol- proxy

Servizio per l'integrazione con il sistema di protocollo YYY (vedi Integrazioni per la lista completa)

File StorageKafka

registry-api

API per l'app Django con cui abbiamo integrato una decina di protocolli

PostgreSQL

registry-scheduler

Scheduler per gli errori registrati durante un tentativo di protocollazione

PostgreSQLKafka

analytics-services-aggregator

Servizio per il calcolo dei KPI sui Servizi

KafkaClickHouse

analytics-first-availability-aggregator

Servizio per il calcolo dei KPI sui Calendari

KafkaClickHouse

analytics-bookings-aggregator

Servizio per il calcolo dei KPI sui Calendari

KafkaClickHouse

analytics-charts-exporter

API per la generazione dei grafici degli Analytics

ClickHouse

satisfy-hasura

API per il servizio di Customer Satisfaction

PostgreSQL

satisfy-api

API per la raccolta di ratings e questionari di Customer Satisfaction

Kafka

satisfy-ratings-aggregator

Servizio per il calcolo dei KPI della Customer Satisfaction

Kafka

pdnd-connector

Servizio che gestisce l'interazione con la pdnd e gli enti erogatori degli e-service utilizzati dalla piattaforma

File Storage

retry-orchestrator

Servizio che gestisce i retry dei messaggi provenienti dai vari topic di kafka

Kafka

Il servizio kafka-core-api può essere reso opzionale attivando il flag FEATURE_KAFKA_DIRECT: 'true' nelle variabili d'ambiente del core. Con questo flag attivo, i messaggi Kafka sono inviati direttamente tramite rdkafka senza passare per HTTP+Vector, eliminando la dipendenza dal servizio vector.

Esempio di un file di deployment per orchestratore Docker Swarm:

File di esempio

Gli header HTTP di sicurezza (CORS, Content-Security-Policy, security headers) sono ora gestiti a livello applicativo. I middleware Traefik sdc-cors, goodheaders e security possono essere rimossi dalla configurazione di Traefik.

Prima di procedere all’avvio dei microservizi si devono compiere alcune operazioni:

Creazione del file delle istanze

Va creato un file instances.yml sull'ambiente che ospiterà la piattaforma, questo file dovrà poi essere condiviso con i servizi che ne hanno bisogno (vedi file di esempio di distribuzione).

Il file è così formato:

Andrà creato un blocco istanza per ogni ente che si vorrà ospitare sulla piattaforma

Creazione dei database

Singole istanze degli enti (Symfony core)

Il tipo di multi-tenancy implementata in OpenCity Area personale è di singolo stack applicativo con database dedicato per tenant.

Per poter effettuare un’installazione dell’infrastruttura abbiamo quindi bisogno di un singolo database per tenant con le seguenti caratteristiche.

Postgres >= 11 con estensione postgis >= 3

Permessi

Per ridurre i rischi dovuti a errori o a compromissione delle credenziali vengono usati due utenti differenti:

  • un utente oc_manager che viene utilizzato per creare i database ed eseguire operazione di struttura (creazione, modifica e cancellazione di tabelle, viste, colonne ecc ecc)

  • un utente oc_user che viene utilizzato dall’applicativo per effettuare operazioni sui dati

Attualmente nella nostra infrastruttura la creazione del database avviene con l'utente oc_manager, a partire da un template preimpostato con i privilegi necessari.

Creazione del template

Come utente postgres si crea il database impostando i privilegi di default che verranno assegnati a tutti gli oggetti creati in seguito.

A postgres verranno dati privilegi ampi, mentre a oc_user verranno dati privilegi minimali:

In seguito la proprietà del database viene assegnata ad oc_manager

Per creare database come utente postgres gli viene dato il ruolo oc_manager

Creazione di un nuovo database

Per creare il database e impostarne subito come owner l'utente corretto, si esegue come utente postgres

Sistema di protocollazione (registry)

Il sistema di protocollazione ha invece bisogno di un singolo database con le seguenti caratteristiche:

Postgres >= 11

Creazione di un nuovo utente

Tuning di alcuni parametri di connessione (questi comandi sono opzionali ma suggeriti da django)

Creo il database e lo assegno all'utente

Configurazione dei proxy di pagamento

Per garantire una corretta comunicazione tra l'area personale e i proxy di pagamento è necessaria configurare appropriatamente gli endpoint sul proxy di riferimento.

Configurazione dei CORS

Il requisito di base affinchè questi endpoint siano correttamente funzionanti è che siano correttamente racchiuse all'interno di un middleware che gestisca i CORS in maniera adeguata. In particolare questo middleware dovrà essere configurato come segue:

Header
Valore

Access-Control-Allow-Credentials

true

Access-Control-Allow-Headers

Authorization,Origin,Content-Type,Accept,access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,access-control-allow-credentials,Referer

Access-Control-Allow-Methods

GET,POST,HEAD,PUT,DELETE,PATCH,OPTIONS

Access-Control-Allow-Origin-List

*

Access-Control-Max-Age

100

Add-Vary-Header

true

Di seguito un esempio di configurazione del middleware:

Endpoint interni (non necessita di CORS)

L'unico endpoint interno in questo caso è quello per richiedere l'aggiornamento dello stato di un pagamento. Per garantire quindi che questo venga chiamato solo ed esclusivamente dal microservizio di polling, è necessario che questo venga configurato come endpoint raggiungibile solo internamente alla rete di docker. Di seguito un esempio:

Endpoint pubblici

Gli endpoint pubblici sono:

  • Pagamento online (/online-payment/{payment_id})

  • Download dell'avviso cartaceo (/offline-payment/{payment_id})

  • Download della ricevuta telematica (/receipt/{payment_id})

  • Ritorno alla area personale (detta anche landing url) (/landing/{payment_id})

  • Form schema per la configurazione del tenant (/tenants/schema)

  • Form schema per la configurazione del servizio (/services/schema)

  • Documentazione Swagger delle API (/docs)

  • Status (/status, facoltativo)

  • Metriche di monitoraggio (/metrics, facoltativo)

Di seguito un esempio di configurazione degli endpoint

Endpoint protetti

Gli endpoint protetti da autenticazione sono:

  • Inserimento, recupero, modifica e cancellazione della configurazione del tenant (/tenants/{id})

  • Inserimento, recupero, modifica e cancellazione della configurazione del servizio (/services/{id})

Di seguito un esempio di configurazione degli endpoint:

Last updated

Was this helpful?