Files
termanager2/README.md

28 KiB

TerManager2

Applicazione web per la gestione dell'assegnazione e rientro di territori (cartoline), statistiche di percorrenza e campagne speciali per congregazioni.


Indice


Panoramica

TerManager2 gestisce:

  • Territori (cartoline) con PDF allegato, stato dinamico (in reparto / assegnato / da rientrare / prioritario / inattivo), zona e tipologia.
  • Proclamatori (assegnatari) con dati personali cifrati a livello di colonna nel database (AES-256-CBC tramite APP_KEY).
  • Assegnazioni con data assegnazione/rientro, anno teocratico, conteggio opzionale in campagna.
  • Campagne (periodi speciali) con percentuali di percorrenza in tempo reale.
  • Dashboard con media mensile di percorrenza, campagna attiva, e tre liste rapide (da assegnare, prioritari, da rientrare).
  • Registro delle assegnazioni filtrabile per anno teocratico, zona, stato.
  • Audit Log completo di tutte le azioni utente con diff before/after.

Stack tecnologico

Componente Tecnologia
Framework Laravel 11.x
PHP 8.3-FPM
UI Livewire 3.5 + TailwindCSS 4.0 + Alpine.js
Database MariaDB 11
Cache/Session Redis 7 (Alpine)
Web Server Nginx 1.25 (Alpine)
Auth Laravel Breeze 2.0
RBAC spatie/laravel-permission 6.4
Audit Trail spatie/laravel-activitylog 4.8
Asset Build Vite 6.0 + @tailwindcss/vite
Node.js 20 LTS (nel container PHP)
Mail (dev) Mailpit
Container Docker Compose (6 servizi)

Requisiti di sistema

  • Docker >= 24.0 e Docker Compose >= 2.20
  • Git per clonare il repository
  • Porte libere (configurabili nel .env):
Porta Servizio Variabile .env
8080 Applicazione web (Nginx) APP_PORT
1025 SMTP Mailpit MAIL_PORT
8025 UI Mailpit MAILPIT_UI_PORT

MariaDB (3306) e Redis (6379) non espongono porte sull'host: sono accessibili solo dalla rete interna Docker.


Installazione da zero

Passo 1 — Clona il repository

git clone <repository-url> termanager2
cd termanager2

Passo 2 — Crea il file .env

cp .env.example .env

Passo 3 — Configura le variabili obbligatorie

Apri .env con un editor e imposta almeno queste variabili:

nano .env
# --- Credenziali admin iniziale (OBBLIGATORIE al primo avvio) ---
INITIAL_ADMIN_NAME="Mario Rossi"
INITIAL_ADMIN_EMAIL=admin@esempio.it
INITIAL_ADMIN_PASSWORD=UnaPasswordSicura123

# --- URL dell'applicazione (adatta al tuo dominio/IP) ---
APP_URL=http://localhost:8080
ASSET_URL=http://localhost:8080

# --- Password database (cambia i default in produzione!) ---
DB_PASSWORD=una_password_sicura
DB_ROOT_PASSWORD=una_root_password_sicura
REDIS_PASSWORD=una_redis_password_sicura

Importante: INITIAL_ADMIN_NAME, INITIAL_ADMIN_EMAIL e INITIAL_ADMIN_PASSWORD sono obbligatorie. Se mancano e il database è vuoto, il container si avvia ma mostra un warning e non potrai accedere.

Passo 4 — Imposta i permessi

Il container PHP gira con UID/GID 1000. I file devono appartenere a questo utente:

# Crea le cartelle necessarie
mkdir -p storage/app/public \
         storage/framework/cache/data \
         storage/framework/sessions \
         storage/framework/views \
         storage/logs \
         bootstrap/cache

# Imposta proprietario e permessi
sudo chown -R 1000:1000 .
chmod -R 775 storage bootstrap/cache

Passo 5 — Avvia i container (primo avvio)

docker compose up -d --build

Questo comando:

  1. Costruisce le immagini Docker (PHP + Nginx)
  2. Avvia 6 servizi: app, nginx, queue-worker, mariadb, redis, mailpit
  3. L'entrypoint del container app esegue automaticamente:
    • Copia .env.example.env (se mancante)
    • Installa le dipendenze Composer (vendor/)
    • Genera APP_KEY (se vuota) e la salva in storage/app/.app_key
    • Installa le dipendenze NPM (node_modules/)
    • Compila gli asset frontend CSS/JS (public/build/)
    • Crea il symlink public/storagestorage/app/public
    • Esegue le migrazioni database
    • Esegue il seed iniziale (ruoli e permessi)
    • Crea l'account admin iniziale
    • Mette in cache config, routes e views

Passo 6 — Verifica che tutto funzioni

# Controlla che tutti i container siano "healthy"
docker compose ps

Output atteso — tutti i container devono essere Up (e healthy dove previsto):

NAME                  STATUS                  PORTS
termanager2_app       Up (healthy)            9000/tcp
termanager2_nginx     Up                      0.0.0.0:8080->80/tcp
termanager2_queue     Up                      9000/tcp
termanager2_db        Up (healthy)            3306/tcp
termanager2_redis     Up (healthy)            6379/tcp
termanager2_mail      Up                      0.0.0.0:1025->1025/tcp, 0.0.0.0:8025->8025/tcp

Se un container non è healthy, controlla i log:

# Log del container app (il più importante)
docker compose logs app --tail=100

# Log di tutti i container
docker compose logs --tail=50

Passo 7 — Accedi all'applicazione

Apri il browser su: http://localhost:8080 (o la porta configurata in APP_PORT)

Accedi con le credenziali impostate in INITIAL_ADMIN_EMAIL e INITIAL_ADMIN_PASSWORD.


Configurazione

Variabili d'ambiente principali (.env)

Variabile Default Descrizione
APP_KEY (auto-generata) Chiave AES-256 per cifratura dati. Mai condividere. Viene generata automaticamente al primo avvio
APP_URL da .env.example URL completo dell'applicazione (es. https://miodominio.it)
ASSET_URL da .env.example URL base per gli asset CSS/JS (normalmente uguale a APP_URL)
APP_PORT 8080 Porta host su cui Nginx espone l'app
APP_ENV local Ambiente: local (sviluppo) o production
APP_DEBUG true Mostra errori dettagliati. Impostare false in produzione
SEED_DEV_DATA false Se true, il seed include dati demo di test
RUN_DB_SEED_ON_FIRST_START true Se true, esegue il seed automatico solo al primo avvio
ENSURE_INITIAL_ADMIN_ON_EMPTY_DB true Se true, crea admin iniziale quando non esistono utenti
INITIAL_ADMIN_NAME (vuoto) Nome dell'admin iniziale — obbligatorio al primo avvio
INITIAL_ADMIN_EMAIL (vuoto) Email dell'admin iniziale — obbligatorio al primo avvio
INITIAL_ADMIN_PASSWORD (vuoto) Password dell'admin iniziale (min 8 caratteri) — obbligatorio al primo avvio
DB_DATABASE termanager2 Nome database MariaDB
DB_USERNAME termanager2 Utente database
DB_PASSWORD secret Password database — cambiare in produzione
DB_ROOT_PASSWORD rootsecret Password root MariaDB — cambiare in produzione
REDIS_PASSWORD redissecret Password Redis — cambiare in produzione
MAIL_PORT 1025 Porta SMTP (Mailpit in dev, SMTP reale in prod)
MAILPIT_UI_PORT 8025 Porta UI Mailpit per debug email

Configurazione applicativa

Dopo il primo accesso, la configurazione si gestisce dalla sezione Impostazioni nel menu (solo Amministratore):

  • Nome congregazione
  • Soglia mesi per priorità automatica territori
  • Soglia giorni per "da rientrare"
  • Retention giorni audit log

Credenziali iniziali

Le credenziali admin non sono hardcoded. Al primo avvio devi impostare nel .env:

  • INITIAL_ADMIN_NAME
  • INITIAL_ADMIN_EMAIL
  • INITIAL_ADMIN_PASSWORD

Se il database è vuoto e queste variabili non sono valorizzate, il container app mostra un warning e non verrà creato l'account admin.


Migrazione su nuovo server

Quando sposti TerManager2 su un nuovo server, segui questa procedura:

1. Copia i file sul nuovo server

# Dal vecchio server: crea un archivio (escludi vendor, node_modules e volumi Docker)
tar czf termanager2-backup.tar.gz \
    --exclude='vendor' \
    --exclude='node_modules' \
    --exclude='public/build' \
    --exclude='.git' \
    termanager2/

# Copia sul nuovo server
scp termanager2-backup.tar.gz utente@nuovo-server:/home/utente/Docker/

# Sul nuovo server: estrai
cd /home/utente/Docker
tar xzf termanager2-backup.tar.gz
cd termanager2

2. Verifica il file .env

# Controlla che .env esista e contenga i valori corretti
cat .env

# Adatta APP_URL e ASSET_URL al nuovo dominio/IP
nano .env

Critico: se il nuovo server ha un URL/IP diverso, aggiorna APP_URL e ASSET_URL.

3. Imposta i permessi

sudo chown -R 1000:1000 .
chmod -R 775 storage bootstrap/cache

4. Ricostruisci e avvia

docker compose up -d --build

5. Forza la ricompilazione degli asset

Se la pagina appare senza stile (CSS mancante), ricompila gli asset:

# Ricompila CSS e JS dentro il container
docker compose exec -u root app bash -c "npm install --no-audit --no-fund && npm run build"

# Correggi i permessi dei file generati
docker compose exec -u root app chown -R 1000:1000 public/build node_modules

6. (Opzionale) Ripristina il database

Se hai un dump SQL dal vecchio server:

# Copia il dump nel container MariaDB
docker cp backup.sql termanager2_db:/tmp/backup.sql

# Importa il dump
docker compose exec mariadb mysql -u root -p"$(grep DB_ROOT_PASSWORD .env | cut -d= -f2)" termanager2 < /tmp/backup.sql

# Esegui le eventuali migrazioni mancanti
docker compose exec app php artisan migrate --force

# Pulisci la cache
docker compose exec app php artisan optimize:clear

Struttura del progetto

TerManager2/
├── app/
│   ├── Console/Commands/          # AuditCleanup (pulizia log schedulata)
│   ├── Http/Middleware/           # Middleware HTTP applicativi
│   ├── Livewire/
│   │   ├── Assegnazioni/         # Assegna, Rientra
│   │   ├── Auth/                 # Login
│   │   ├── Campagne/             # Index, Create, Edit, Show
│   │   ├── Proclamatori/         # Index, Create, Edit, Show, Cestino
│   │   ├── Settings/             # SettingsEdit, ZoneIndex, TipologieIndex
│   │   ├── Territori/            # Index, Create, Edit, Show, Cestino
│   │   ├── AuditLog.php          # Log attività (filtri, diff)
│   │   ├── Home.php              # Dashboard
│   │   └── Registro.php          # Registro assegnazioni
│   ├── Models/                   # 8 modelli Eloquent
│   └── Providers/                # AppServiceProvider (Gate admin)
├── bootstrap/                    # app.php (middleware), providers.php
├── config/                       # app, auth, database, session
├── database/
│   ├── migrations/               # 10 migrazioni ordinate
│   └── seeders/                  # Roles, Dev, Database seeders
├── docker/
│   ├── nginx/default.conf        # Vhost con security headers
│   └── php/
│       ├── Dockerfile            # PHP 8.3-FPM + estensioni + Composer + Node 20
│       └── php.ini               # 64M upload, opcache, Europe/Rome
├── public/index.php              # Entry point Laravel
├── resources/
│   ├── css/app.css               # TailwindCSS 4 import
│   ├── js/                       # app.js, bootstrap.js (Axios)
│   └── views/
│       ├── components/layouts/   # app.blade.php (sidebar), guest.blade.php
│       └── livewire/             # Tutte le viste dei componenti
├── routes/
│   ├── web.php                   # Tutte le rotte con permessi
│   └── console.php               # Schedule audit:cleanup daily
├── .env.example                  # Template configurazione
├── artisan                       # CLI Laravel
├── composer.json                 # Dipendenze PHP
├── docker-compose.yml            # 5 servizi (app, nginx, mariadb, redis, mailpit)
├── package.json                  # Dipendenze Node (Vite, TailwindCSS)
└── vite.config.js                # Vite + Laravel plugin + TailwindCSS plugin

Funzionalità principali

Dashboard (Home)

  • Anno teocratico corrente (auto-creato se mancante, Set→Ago)
  • Media mensile di percorrenza (territori rientrati / mesi trascorsi)
  • Campagna attiva con barra di progresso percentuale
  • Tre liste rapide con azione diretta:
    • Da assegnare: territori in reparto, ordinati per priorità
    • Prioritari: flag manuale O soglia automatica (la soglia vince sempre)
    • Da rientrare: assegnazioni oltre la soglia giorni configurata

Territori

  • CRUD completo con upload/sostituzione PDF
  • Filtri per zona, tipologia, stato (in_reparto, assegnato, da_rientrare, inattivo)
  • Badge di stato colorati + indicatore priorità (Manuale/Automatico)
  • Dettaglio con PDF viewer inline e storico assegnazioni per anno teocratico
  • Toggle attivo/inattivo e prioritario
  • Soft delete con cestino (ripristino o eliminazione definitiva)

Proclamatori

  • CRUD con campi nome/cognome cifrati nel DB (AES-256-CBC)
  • Ricerca in-memory (necessaria per campi cifrati, ottimizzata per < 200 record)
  • Conteggio territori attualmente assegnati
  • Toggle attivo/inattivo
  • Anonimizzazione GDPR (sostituzione dati con placeholder irreversibile)
  • Soft delete con cestino

Assegnazione / Rientro

  • Selezione territorio disponibile + proclamatore attivo
  • Data assegnazione con auto-detection anno teocratico
  • Validazione: territorio non già assegnato, entrambi attivi
  • Rientro con calcolo automatico giorni
  • Prompt retroattivo campagna: se l'assegnazione ricade nel range di una campagna, viene chiesto se conteggiare il rientro

Campagne

  • CRUD con date inizio/fine e descrizione
  • Stato automatico (Attiva/Futura/Conclusa)
  • Percentuale percorrenza in tempo reale (conteggiati / totali assegnati nel range)
  • Dettaglio con lista territorio-per-territorio dei conteggiati

Registro Assegnazioni

  • Filtri: anno teocratico, zona, stato (aperte/chiuse), ricerca testo
  • Colonne: territorio, proclamatore, date, giorni, campagna

Audit Log

  • Log automatico su tutti i modelli (spatie/laravel-activitylog)
  • Log manuale per eventi di flusso (assign, return, login, logout)
  • Filtri per utente, tipo evento, ricerca testo
  • Dettaglio con diff before/after (properties JSON espanso)
  • Pulizia automatica schedulata (audit:cleanup — retention configurabile)

Impostazioni

  • Nome congregazione
  • Soglia mesi priorità automatica
  • Soglia giorni per "da rientrare"
  • Retention giorni audit log

XML Exchange

  • Conversione dump SQL legacy in XML compatibile con TerManager2
  • Import XML nell'app (sostituzione dati gestionali: impostazioni, zone, tipologie, proclamatori, territori, anni, campagne, assegnazioni)
  • Export XML dei dati correnti

Zone e Tipologie

  • CRUD inline (aggiungi, rinomina, attiva/disattiva, elimina)
  • Protezione: non eliminabile se ha territori associati

Ruoli e permessi (RBAC)

Tre ruoli con permessi granulari gestiti da spatie/laravel-permission:

Permesso Amministratore Assistente Operatore
settings.manage
territori.manage
proclamatori.manage
campagne.manage
territori.assign
territori.return
registro.view
registro.export
audit.view
audit.export

L'amministratore ha un bypass completo via Gate::before nel AppServiceProvider.

Il menu sidebar mostra solo le voci per cui l'utente ha permesso.


Sicurezza e GDPR

Sicurezza

  • Cifratura a riposo: nome e cognome proclamatori cifrati con encrypted cast (AES-256-CBC via APP_KEY)
  • Password: hash bcrypt (standard Laravel)
  • RBAC: middleware permission: su ogni rotta
  • CSRF: token integrato in tutti i form Livewire
  • Rate limiting: login con throttle configurabile
  • Security headers: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection (via Nginx)
  • Sessioni: Redis con cookie termanager2_session (httpOnly, secure in produzione)

GDPR

  • Minimizzazione: solo nome, cognome e stato attivo per i proclamatori
  • Cifratura a riposo: dati illeggibili con accesso diretto al DB
  • Audit trail: log completo di tutte le operazioni sui dati
  • Diritto all'oblio: metodo anonimizza() sul Proclamatore (sostituisce dati con placeholder)
  • Retention: pulizia automatica dei log audit oltre il periodo configurato
  • Ruoli e autorizzazioni: accesso ai dati solo per chi ha permessi specifici
  • No log di dati sensibili: l'audit log registra proclamatore_id ma non nome/cognome in chiaro nei properties

Modello dati

Tabelle principali (10 migrazioni)

Tabella Descrizione
users Utenti app con auth standard Laravel
settings Configurazione singleton (congregazione, soglie, retention)
zone Zone territoriali (id, nome, attivo)
tipologie Tipologie territorio (id, nome, attivo)
proclamatori Assegnatari con nome/cognome cifrati, soft delete
territori Cartoline con zona, tipologia, PDF, soft delete
anni_teocratici Periodi Set→Ago con label univoca
campagne Periodi speciali con date e descrizione
assegnazioni Join territorio↔proclamatore con date, anno, campagna
activity_log Audit trail (spatie/laravel-activitylog)

Indici e vincoli

  • territori.numero — UNIQUE
  • anni_teocratici.label — UNIQUE
  • assegnazioni(territorio_id, returned_at) — INDEX composito
  • assegnazioni(proclamatore_id, returned_at) — INDEX composito
  • assegnazioni(anno_teocratico_id) — INDEX
  • FK con RESTRICT su territorio e proclamatore (protezione integrità)

Regole di business

Anno teocratico

  • Settembre → Agosto: se mese ≥ 9 → anno = corrente/corrente+1; se mese ≤ 8 → anno = corrente-1/corrente
  • Creato automaticamente se non esiste (metodo AnnoTeocratico::perData())
  • L'assegnazione conta per l'anno determinato dalla data di assegnazione

Stato territorio (calcolato dinamicamente)

  • in_reparto: attivo, nessuna assegnazione aperta
  • assegnato: ha assegnazione con returned_at = null
  • da_rientrare: assegnato da più giorni della soglia configurata
  • inattivo: attivo = false

Priorità

  • Manuale: flag prioritario = true impostato dall'admin
  • Automatica: nessuna assegnazione negli ultimi N mesi (soglia configurabile)
  • La soglia automatica vince sempre sul flag manuale (l'admin può aggiungere ma non rimuovere se la soglia scatta)

Campagne — percentuale percorrenza

  • Denominatore: tutti i territori assegnati nel range della campagna
  • Numeratore: assegnazioni conteggiate in campagna (counted_in_campaign = true)
  • Il prompt retroattivo appare al rientro se l'assegnazione è nel range di una campagna

Comandi utili

Gestione container

# Avviare i container (dopo il primo build)
docker compose up -d

# Avviare con ricostruzione immagini (dopo modifiche a Dockerfile o dipendenze)
docker compose up -d --build

# Fermare i container (i dati persistono nei volumi)
docker compose down

# Fermare e CANCELLARE tutti i dati (database, redis, uploads)
docker compose down -v --remove-orphans

# Stato dei container
docker compose ps

# Log in tempo reale (tutti i container)
docker compose logs -f

# Log di un singolo container
docker compose logs app --tail=100
docker compose logs nginx --tail=100
docker compose logs mariadb --tail=100

# Riavviare un singolo container
docker compose restart app

Shell interattiva

# Shell nel container app (come utente 1000)
docker compose exec app bash

# Shell nel container app come root (per operazioni di sistema)
docker compose exec -u root app bash

# Shell nel container MariaDB
docker compose exec mariadb mysql -u root -p

Laravel / Artisan

# Eseguire migrazioni
docker compose exec app php artisan migrate --force

# Seed del database
docker compose exec app php artisan db:seed --force

# Pulizia manuale audit log
docker compose exec app php artisan audit:cleanup

# Cache configurazione (produzione)
docker compose exec app php artisan config:cache
docker compose exec app php artisan route:cache
docker compose exec app php artisan view:cache

# Svuotare TUTTA la cache
docker compose exec app php artisan optimize:clear

Asset frontend (CSS/JS)

# Compilare asset per produzione
docker compose exec -u root app bash -c "npm install --no-audit --no-fund && npm run build"
docker compose exec -u root app chown -R 1000:1000 public/build node_modules

# Compilare asset per sviluppo (hot reload, richiede porta 5173 libera)
docker compose exec app npm run dev

Backup e ripristino database

# Backup del database (sostituisci le credenziali)
docker compose exec mariadb mysqldump -u root -prootsecret termanager2 > backup_$(date +%Y%m%d).sql

# Ripristino da backup
docker compose exec -T mariadb mysql -u root -prootsecret termanager2 < backup_20250101.sql
docker compose exec app php artisan migrate --force
docker compose exec app php artisan optimize:clear

Troubleshooting

La pagina appare senza stile (CSS mancante)

Sintomo: la pagina di login appare con testo non formattato, senza colori né layout.

Causa: il file CSS compilato manca da public/build/assets/. Succede tipicamente dopo una migrazione su nuovo server.

Soluzione:

# Ricompila gli asset come root (evita problemi di permessi)
docker compose exec -u root app bash -c "npm install --no-audit --no-fund && npm run build"

# Correggi i permessi
docker compose exec -u root app chown -R 1000:1000 public/build node_modules

Il container app non diventa healthy

Sintomo: docker compose ps mostra app come starting o unhealthy.

Cosa controllare:

# Guarda i log per capire dove si blocca
docker compose logs app --tail=200

Cause comuni:

  • MariaDB non pronto: l'entrypoint ripete il tentativo 10 volte. Attendi qualche secondo.
  • Credenziali admin mancanti: se ENSURE_INITIAL_ADMIN_ON_EMPTY_DB=true e le variabili INITIAL_ADMIN_* sono vuote, il container mostra un warning.
  • Errore di permessi: esegui sudo chown -R 1000:1000 . sulla cartella del progetto.

Errore "Permission denied" su storage o bootstrap/cache

sudo chown -R 1000:1000 storage bootstrap/cache
chmod -R 775 storage bootstrap/cache

La APP_KEY è cambiata e i dati cifrati non sono leggibili

La APP_KEY viene salvata in storage/app/.app_key per persistere tra i riavvii. Se perdi questo file:

  • I nomi e cognomi dei proclamatori (cifrati con AES-256) diventano illeggibili
  • Le sessioni vengono invalidate

Prevenzione: dopo il primo avvio, salva il valore di APP_KEY dal file .env in un luogo sicuro.

Errore npm "EACCES" o "vite: not found"

# Installa le dipendenze npm come root
docker compose exec -u root app npm install --no-audit --no-fund

# Verifica che vite sia installato
docker compose exec app ls node_modules/.bin/vite

# Compila come root
docker compose exec -u root app npm run build

# Poi correggi i permessi
docker compose exec -u root app chown -R 1000:1000 public/build node_modules

Reset completo (ripartire da zero)

Attenzione: questo cancella il database, i file Redis e tutti i dati applicativi.

docker compose down -v --remove-orphans
sudo chown -R 1000:1000 .
rm -rf node_modules public/build vendor storage/app/.app_key storage/framework/.runtime_db_seeded
docker compose up -d --build

Produzione

Checklist deploy in produzione

  1. Variabili d'ambiente — modifica nel .env:

    APP_ENV=production
    APP_DEBUG=false
    APP_URL=https://tuodominio.it
    ASSET_URL=https://tuodominio.it
    
  2. Password sicure — cambia TUTTI i default:

    DB_PASSWORD=<password-sicura-generata>
    DB_ROOT_PASSWORD=<password-root-sicura-generata>
    REDIS_PASSWORD=<password-redis-sicura-generata>
    
  3. HTTPS — configura un reverse proxy (Traefik, Nginx, Caddy) con certificato SSL/TLS davanti alla porta APP_PORT

  4. Cache — al primo avvio viene fatto automaticamente dall'entrypoint, ma dopo modifiche:

    docker compose exec app php artisan config:cache
    docker compose exec app php artisan route:cache
    docker compose exec app php artisan view:cache
    
  5. Backup — programma backup regolari del database:

    # Cron job giornaliero (esempio)
    0 2 * * * cd /path/to/termanager2 && docker compose exec -T mariadb mysqldump -u root -prootsecret termanager2 | gzip > /backups/termanager2_$(date +\%Y\%m\%d).sql.gz
    
  6. APP_KEY — salva il valore di APP_KEY dal .env in un luogo sicuro (password manager, vault). Senza di essa i dati cifrati dei proclamatori sono irrecuperabili.

  7. Mailpit — in produzione rimuovi il servizio mailpit dal docker-compose.yml e configura un server SMTP reale:

    MAIL_MAILER=smtp
    MAIL_HOST=smtp.tuoprovider.it
    MAIL_PORT=587
    MAIL_USERNAME=utente@tuodominio.it
    MAIL_PASSWORD=password-smtp
    MAIL_ENCRYPTION=tls
    MAIL_FROM_ADDRESS=noreply@tuodominio.it
    

Licenza

Progetto privato — tutti i diritti riservati.