Frappe ERP & Docker v16: Sizing, Micro-Servizi e Persistenza in Produzione
Data di pubblicazione:
Installare un ERP aziendale moderno "a nudo" sul sistema operativo host, con dipendenze Python globali gestite via virtualenv monolitici, è una delle bombe a orologeria più rischiose che un'infrastruttura IT possa ospitare.
Basta un aggiornamento non presidiato di un pacchetto di sistema (glibc, librerie libssl o versioni minori di Python) per rompere le dipendenze native di Frappe e causare il blocco improvviso dell'intero gestionale.
Se questo accade in una struttura aziendale complessa o ad alta rotazione operativa (come una realtà alberghiera multi-sede con reception aperta 24/7 e centinaia di ospiti in arrivo), un disservizio all'ERP significa paralisi totale: impossibilità di emettere schedine alloggiati, blocchi alla fatturazione e code al front desk.
In questo articolo analizziamo l'architettura di produzione basata su Frappe / ERPNext v16 containerizzato con Docker Compose che abbiamo recentemente progettato e validato presso un cliente nel settore dell'hospitality, illustrando i principi di isolamento, persistenza, integrazione SSO LDAP e la gestione del codice custom.
1. I Limiti dell'Installazione Monolitica Tradizionale (bench bare-metal)
L'utility standard bench nasce per semplificare l'installazione di Frappe, ma nei setup tradizionali single-host presenta criticità intrinseche:
- Accoppiamento Forte: Nginx, Gunicorn, i processi Celery/RQ, Redis e MariaDB condividono lo stesso spazio di memoria e le stesse risorse CPU senza quote rigide.
- Rischio di Degradazione Asincrona: Quando un utente lancia un report contabile o un'elaborazione statistica pesante, i worker saturano le risorse di sistema, rallentando i thread HTTP di Node/Socketio dedicati all'interfaccia interattiva degli operatori.
- Disaster Recovery Lento: Il ripristino di un ambiente monolitico richiede la riconfigurazione dell'intero stack di sistema operativo, con tempi di fermo difficilmente compatibili con SLA enterprise.
2. Architettura a Micro-Servizi Isolati su Frappe Docker
Per garantire continuità di servizio, abbiamo adottato l'approccio containerizzato basato sui template ufficiali di Frappe Docker, scomponendo lo stack in container specializzati:
[ Traffico Web Client / Front Desk ]
|
v
+-----------------------------------+
| Reverse Proxy Nginx |
| (SSL/TLS + Cache Statica) |
+-----------------------------------+
/ \
(Socket.io / Real-Time) (HTTP / API REST)
/ \
v v
+-----------------------+ +-----------------------+
| frappe-socketio | | frappe-backend |
| (Node.js 18) | | (Gunicorn / Python) |
+-----------------------+ +-----------------------+
\ /
v v
+---------------------------+
| Redis Queue & Cache |
+---------------------------+
|
v
+---------------------------------------------------+
| Worker Asincroni |
| [Short Queue] [Default Queue] [Long Queue] |
+---------------------------------------------------+
|
v
+-----------------------+
| MariaDB Enterprise |
| (Storage Persistente)|
+-----------------------+
A. Separazione Rigida dei Worker Asincroni
La separazione dei container worker in tre pool indipendenti è il fattore chiave di resilienza:
worker-short: Riservato a task rapidi (notifiche istantanee, validazioni veloci).worker-default: Esecuzione dei normali flussi documentali (salvataggio fatture, cambi stato).worker-long: Dedicato a report massivi, sync esterni e importazioni notturne.
Se un batch notturno occupa il worker-long al 100%, i container backend e socketio rimangono completamente scarichi: l'operatore alla cassa o al check-in non percepisce il minimo rallentamento.
B. Due Istanze Redis Distinte
Mai utilizzare una sola istanza Redis per tutto. Abbiamo segregato:
redis-cache: Configurato con policyallkeys-lrue memoria volatile (dati effimeri di sessione e cache query).redis-queue: Dedicato esclusivamente alla coda dei task, configurato con persistenza AOF (Append Only File) per garantire che nessun job vada perso anche in caso di reboot improvviso del nodo.
3. Persistenza dei Dati, Hardening e Sizing MariaDB
I container devono rimanere rigorosamente stateless. Tutti i dati persistenti risiedono in volumi esterni dedicati:
sites-data: Contiene il file di configurazionesite_config.jsone la directorypublic/fileseprivate/filescon tutti gli allegati dei documenti.db-data: Volume dedicato ai file InnoDB di MariaDB.
Parametri Chiave di Hardening MariaDB (my.cnf containerizzato)
Per evitare corruzioni durante improvvisi riavvii dell'host e massimizzare il throughput delle transazioni:
[mysqld]
# Integrità e protezione transazioni finanziarie
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
# Ottimizzazione memoria (parametrizzata sul 60% della RAM host)
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4
innodb_log_file_size = 1G
innodb_file_per_table = 1
# Collation e character set nativo Frappe
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
4. Single Sign-On: Integrazione LDAP / Active Directory
In aziende strutturate, costringere gli utenti a memorizzare una password locale per l'ERP è una pessima pratica di sicurezza.
Sfruttando l'integrazione LDAP nativa di Frappe:
- L'ERP effettua il bind sicuro (LDAPS porta 636) verso l'Active Directory aziendale.
- Gli operatori accedono con le proprie credenziali di dominio centralizzate.
- Se un dipendente lascia l'azienda, la disabilitazione dell'utenza in Active Directory revoca istantaneamente l'accesso a ERPNext, azzerando i rischi di accessi non autorizzati post-offboarding.
5. Sviluppo Custom Protetto: Nessun Tocco al Core
Uno dei difetti storici dei gestionali legacy è la modifica diretta dei file sorgente, che rende impossibile qualsiasi aggiornamento futuro.
Con l'architettura Docker:
- Il core di ERPNext e Frappe risiede nell'immagine base ufficiale immutabile.
- Tutte le logiche personalizzate, i form specifici e i report ad hoc vengono pacchettizzati in App Custom separate (
hotel_custom_app). - L'immagine finale di produzione viene costruita tramite pipeline CI/CD automatica che clona l'app custom sopra il core e valida la sintassi con linter (
Ruff) e test automatici.
Gli aggiornamenti minori o le patch di sicurezza di Frappe diventano un banale cambio di tag dell'immagine Docker, completabile in meno di 60 secondi.
Conclusioni
Passare da un'installazione gestionale improvvisata a un'architettura enterprise a container isolati trasforma l'ERP da punto debole a pilastro di affidabilità aziendale. Scalabilità orizzontale, ripristini rapidi e totale segregazione delle risorse sono i requisiti minimi per proteggere la continuità operativa del business.