Files
termanager2/.env.example
Francesco Picone d433c9392d S-13 sul modulo ufficiale e correzioni all'integrità dei dati
Modulo S-13
- Il PDF scrive sopra il modulo ufficiale (FPDI, matrice convertita in PDF 1.4)
  invece di ricostruirlo in HTML: 20 righe per foglio come l'originale.
- Una riga per ogni territorio attivo; riporto dell'ultimo rientro prima
  dell'anno; assegnazioni a cavallo d'anno su entrambi i fogli; scelta per
  data e non per anno registrato; nomi come "Cognome I.".
- Logica spostata in App\Services\Registro\ModuloS13.

Integrità dei dati
- Export/import XML (e quindi backup/ripristino): le date non slittano più di
  un giorno; i file vecchi in UTC tornano al giorno giusto.
- Import XML: rifiuta file estranei o incompleti senza toccare i dati, errore
  con riga e motivo, territori senza zona importati con il loro storico,
  caratteri di controllo rimossi in export, chi importa conserva password e
  ruolo di amministratore.
- Assegnazioni: assegnazioneCorrente corretta (filtro dentro ofMany), periodi
  sovrapposti rifiutati in Assegna e Registro sotto lock, anno di servizio
  ricavato dalla data, niente date future nel Registro.
- Utenti: non si declassa sé stessi né l'ultimo amministratore.
- Entrypoint: non sovrascrive più la copia persistente di APP_KEY con un
  valore diverso; serve APP_KEY_ROTATE=1 per un cambio voluto.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:35:51 +02:00

171 lines
6.7 KiB
Plaintext

# =============================================================================
# TerManager2 — configurazione
#
# Questo file e' l'UNICA fonte di configurazione: docker-compose.yml lo legge
# cosi' com'e' e non ridichiara nulla.
#
# In locale: cp .env.example .env e modifica quello che serve
# Su Dokploy: incolla queste variabili in Environment, il .env lo
# genera lui
#
# Le variabili marcate [OBBLIGATORIA] non hanno default: lo stack si rifiuta
# di partire senza.
# =============================================================================
# -----------------------------------------------------------------------------
# Applicazione
# -----------------------------------------------------------------------------
APP_NAME=TerManager2
APP_ENV=production
APP_DEBUG=false
APP_TIMEZONE=Europe/Rome
# [OBBLIGATORIA] Deve combaciare ESATTAMENTE con l'indirizzo da cui accedi,
# schema e porta inclusi. L'app rifiuta richieste con un Host diverso
# (protezione contro l'host header injection): un valore sbagliato da' 400
# su tutto.
#
# accesso per IP:porta -> http://192.0.2.10:8080
# accesso in locale -> http://localhost:8080
# dominio con HTTPS -> https://territori.example.org
APP_URL=http://192.0.2.10:8080
# [OBBLIGATORIA] Genera con: echo "base64:$(openssl rand -base64 32)"
# I dati personali dei proclamatori sono cifrati con questa chiave: se la
# perdi non sono piu' leggibili nemmeno avendo il backup del database.
# Conservala in un password manager.
# Una copia sta nel volume dello storage: se questo valore cambia e non
# coincide con la copia, il container si rifiuta di partire invece di rendere
# illeggibili i dati. Per un cambio voluto aggiungi APP_KEY_ROTATE=1 (la
# chiave vecchia viene conservata accanto alla copia), poi toglila.
APP_KEY=
LOG_CHANNEL=stderr
LOG_LEVEL=warning
# -----------------------------------------------------------------------------
# Primo avvio
# -----------------------------------------------------------------------------
# L'amministratore creato al primo deploy. Cambia la password dopo il login.
INITIAL_ADMIN_NAME=Amministratore
INITIAL_ADMIN_EMAIL=
INITIAL_ADMIN_PASSWORD=
# Lasciale cosi': esistono come via di fuga se qualcosa va storto.
RUN_MIGRATIONS=true
RUN_DB_SEED_ON_FIRST_START=true
ENSURE_INITIAL_ADMIN_ON_EMPTY_DB=true
# -----------------------------------------------------------------------------
# Database
# -----------------------------------------------------------------------------
# DB_HOST deve restare "mariadb": e' il nome del servizio in
# docker-compose.yml, non un indirizzo di rete.
DB_CONNECTION=mysql
DB_HOST=mariadb
DB_PORT=3306
DB_DATABASE=termanager2
DB_USERNAME=termanager2
# [OBBLIGATORIE] Genera con: openssl rand -base64 24
DB_PASSWORD=
DB_ROOT_PASSWORD=
# -----------------------------------------------------------------------------
# Redis — cache, sessioni, code
# -----------------------------------------------------------------------------
# Come sopra: "redis" e' il nome del servizio, non va cambiato.
REDIS_HOST=redis
REDIS_PORT=6379
# [OBBLIGATORIA] openssl rand -base64 24
REDIS_PASSWORD=
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
# -----------------------------------------------------------------------------
# Dimensione massima dei file caricati (MB)
# -----------------------------------------------------------------------------
# Governa insieme nginx (client_max_body_size), PHP (upload_max_filesize e
# post_max_size) e la validazione dell'applicazione: li genera l'entrypoint da
# questo unico valore, cosi' non possono andare fuori sincrono.
#
# Il file piu' grande che passa di qui e' il pacchetto di ripristino, che
# contiene tutti i PDF dei territori: con qualche centinaio di mappe si arriva
# facilmente a oltre un giga. Se un caricamento muore senza spiegazioni e la
# barra si pianta, e' quasi sempre questo il limite che si e' incontrato.
#
# Alzarlo non costa memoria: nginx accumula il corpo su disco e PHP lavora su un
# file temporaneo. Serve pero' spazio libero nel volume.
MAX_UPLOAD_MB=2048
# Renderer delle piantine (pagina "Piantine", solo amministratore).
#
# E' il container `map-renderer` del compose: il default punta gia' li' e non
# serve impostare niente. Le variabili esistono per chi volesse spostare il
# renderer altrove o allungare il tempo concesso a un singolo rendering
# (comprende il download delle tessere OSM non ancora in cache).
# MAP_RENDERER_URL=http://map-renderer:3000
# MAP_RENDERER_TIMEOUT=180
# DEVE essere false se accedi in HTTP (tipicamente per IP:porta).
#
# Con true, il cookie di sessione viene marcato "secure" e il browser non lo
# rimanda mai su una connessione HTTP: il login risponde 419 "Page Expired"
# e si torna alla schermata di accesso, senza spiegazioni.
#
# Attenzione: provandolo su http://localhost NON te ne accorgi, perche' i
# browser trattano localhost come contesto sicuro. Il problema salta fuori
# solo accedendo per IP.
#
# Mettilo a true quando servirai l'app in HTTPS dietro un dominio.
SESSION_SECURE_COOKIE=false
# -----------------------------------------------------------------------------
# Posta
# -----------------------------------------------------------------------------
# In produzione: SMTP esterno.
# In locale con --profile dev: MAIL_HOST=mailpit, MAIL_PORT=1025
# Per disattivare del tutto l'invio: MAIL_MAILER=log
MAIL_MAILER=smtp
MAIL_HOST=
MAIL_PORT=587
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_SCHEME=tls
MAIL_FROM_ADDRESS=noreply@example.org
MAIL_FROM_NAME="${APP_NAME}"
# -----------------------------------------------------------------------------
# Porte esposte sull'host
# -----------------------------------------------------------------------------
# Per ogni servizio decidi separatamente SU QUALE INTERFACCIA ascoltare (_BIND)
# e SU QUALE PORTA (_PORT):
#
# 0.0.0.0 raggiungibile da fuori, cioe' da Internet se il server e'
# pubblico e non c'e' un firewall davanti
# 127.0.0.1 solo dalla macchina stessa; da remoto ci arrivi con un
# tunnel SSH: ssh -L 8080:127.0.0.1:8080 utente@server
# --- Applicazione ---
# Esposta, cosi' l'app risponde su http://IP-DEL-SERVER:8080
# Quando passerai a un dominio con HTTPS, rimetti APP_BIND=127.0.0.1: il
# traffico arrivera' dal reverse proxy sulla rete interna e la porta non
# servira' piu'.
APP_BIND=0.0.0.0
APP_PORT=8080
# --- Database ---
# Legato a localhost: per collegare un client grafico (DBeaver, TablePlus)
# apri un tunnel: ssh -L 3306:127.0.0.1:3306 utente@server
# Se la 3306 e' gia' occupata sull'host, cambia DB_PORT_HOST (es. 3307).
# Sconsigliato mettere DB_BIND=0.0.0.0: esporrebbe il database a Internet.
DB_BIND=127.0.0.1
DB_PORT_HOST=3306
# --- Mailpit (solo con --profile dev) ---
MAILPIT_BIND=127.0.0.1
MAILPIT_UI_PORT=8025