Prerequisiti verificati
Stack server sul Raspberry Pi prima di iniziare
Raspberry Pi — server locale
PHP 8.2.28 installato e funzionante OK
MariaDB 10.11.11 installato e attivo OK
Apache 2.4.62 in esecuzione OK
Accesso SSH con utente lecchese configurato OK
FileZilla disponibile per trasferimento file via SFTP OK
💾
1 Export database da Hostinger
Dump dei database di produzione tramite phpMyAdmin
hPanel → phpMyAdmin
Aperto phpMyAdmin dal pannello hPanel di Hostinger
Esportato database u568594947_pren_mesa → file .sql salvato in locale esportato
Esportato database u568594947_mgsw_prodotti → file .sql salvato in locale esportato
🚀
2 Creazione database su Raspberry (MariaDB)
Accesso con autenticazione unix_socket (nessuna password root)
sudo mariadb
Accesso MariaDB via sudo mariadb (autenticazione unix_socket, senza password root)
Creato database mensa_prenotazioni con CHARACTER SET utf8mb4 creato
Creato database mensa_prodotti con CHARACTER SET utf8mb4 creato
Creato utente mensa_user@localhost con password sicura creato
GRANT ALL PRIVILEGES su entrambi i database → FLUSH PRIVILEGES
SQL — MariaDB
CREATE DATABASE mensa_prenotazioni CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE mensa_prodotti CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mensa_user'@'localhost' IDENTIFIED BY 'PASSWORD_SCELTA';
GRANT ALL PRIVILEGES ON mensa_prenotazioni.* TO 'mensa_user'@'localhost';
GRANT ALL PRIVILEGES ON mensa_prodotti.* TO 'mensa_user'@'localhost';
FLUSH PRIVILEGES;
📥
3 Import database su Raspberry
Due problemi risolti durante l'import di mensa_prenotazioni
mariadb import
mensa_prenotazioni — Problema 1: primo tentativo con mariadb -u mensa_user -p FALLITO
Causa: password non impostata correttamente al momento della creazione utente (sintassi errata)
Fix: dentro sudo mariadb eseguito ALTER USER 'mensa_user'@'localhost' IDENTIFIED BY 'password' risolto
mensa_prenotazioni — Problema 2: secondo tentativo fallito con ERROR 1227 — Access denied su VIEW con DEFINER Hostinger FALLITO
Causa: il dump conteneva CREATE VIEW v_buoni_saldo con DEFINER=`u568594947_pren_mesa`@`127.0.0.1` — richiede privilegio SUPER non disponibile per utenti normali
Fix: DROP DATABASE e ricreazione pulita, poi import come root tramite sudo mariadb risolto
Correzione DEFINER: DROP VIEW IF EXISTS v_buoni_saldo + ricreazione con DEFINER=mensa_user@localhost risolto
Verifica finale: SHOW TABLES;12 tabelle presenti OK
Bash — import come root
sudo mariadb mensa_prenotazioni < ~/u568594947_pren_mesa.sql
mensa_prodotti: creato file SQL ridotto mgsw_prodotti_raspberry.sql con soli dati necessari
Incluso: struttura di tutte le tabelle • solo prodotto ID 15 (Prenotazioni_Mensa) • solo utente ID 16 (CINZIA COLOMBI — admin Mollificio) • solo acquisto attivo utente 16 per prodotto 15 (scadenza 2026-12-31)
Import: sudo mariadb mensa_prodotti < ~/mgsw_prodotti_raspberry.sql OK
📁
4 Copia file progetto
Trasferimento via FileZilla (SFTP)
FileZilla SFTP → /var/www/html/
Via FileZilla (SFTP): copiata cartella prenotazionimensa in /var/www/html/Mensa/prenotazionimensa/ trasferito
Cartella include/ (con file di connessione DB) copiata in /var/www/html/include/ trasferito
Aggiunto /var/www/html/include/.htaccess con Require all denied per bloccare l'accesso web diretto alla cartella dei file di connessione sicurezza
.htaccess — /var/www/html/include/
Require all denied
🔑
5 Aggiornamento credenziali database
Sostituzione dei parametri di connessione Hostinger con quelli locali
include/db_conn*.php
Modificato db_conn_prenotazioni.php: host, dbname, user e password aggiornati per connessione locale aggiornato
Modificato db_conn.php: host, dbname, user e password aggiornati per connessione locale aggiornato
Bug trovato e corretto in db_conn.php: commento con slash singolo / Crea connessione invece di // Crea connessione → causava un Parse error PHP fix
PHP — db_conn_prenotazioni.php
$host   = 'localhost';
$dbname = 'mensa_prenotazioni';
$user   = 'mensa_user';
$pass   = 'PASSWORD_SCELTA';
PHP — db_conn.php
$host   = 'localhost';
$dbname = 'mensa_prodotti';
$user   = 'mensa_user';
$pass   = 'PASSWORD_SCELTA';
🔒
6 Permessi Apache
Proprietario lecchese + gruppo www-data per upload FileZilla e lettura Apache
chown / chmod
Strategia permessi: proprietario impostato a lecchese (permette upload via FileZilla), gruppo www-data (Apache può leggere i file)
Cartella cuoca/ con permessi 775 per permettere scrittura file last_scan*.json da parte di Apache (www-data) nota
Bash — impostazione permessi
sudo chown -R lecchese:www-data /var/www/html/Mensa/
sudo chmod -R 755 /var/www/html/Mensa/
sudo find /var/www/html/Mensa/ -name "*.php" -exec chmod 644 {} \;
sudo chmod 775 /var/www/html/Mensa/prenotazionimensa/cuoca/
🔧
7 Modifiche a auth_mensa.php
Adattamento per installazione locale privata (senza dipendenza obbligatoria dallo store)
auth_mensa.php
Problema: auth_mensa.php era progettato per funzionare con il sistema store di mydigitaltools.it — in installazione locale privata il DB prodotti non è obbligatorio
Modifica 1: commentato require_once __DIR__ . "/db_conn.php" — il DB prodotti non blocca l'avvio modificato
Modifica 2: commentato il blocco che terminava l'esecuzione se il DB prodotti non era disponibile modificato
Modifica 3: redirect di login cambiato da /login.php a /Mensa/prenotazionimensa/login.php (path corretto per installazione in sottocartella) modificato
Modifica 4: aggiunta guardia al controllo licenza — il check viene saltato se il DB prodotti non è connesso aggiunto
PHP — guardia controllo licenza
if ($storeUserId > 0 && ($pdoProd instanceof PDO || $connProd instanceof mysqli)) {
    // controllo licenza solo se DB prodotti è connesso
}
🔗
8 Fix redirect duplicato dopo login
URL admin diventava doppio: /Mensa/prenotazionimensa/Mensa/prenotazionimensa/admin/
auth_mensa.php · login.php
Problema: dopo login admin, l'URL diventava /Mensa/prenotazionimensa/Mensa/prenotazionimensa/admin/ → pagina non trovata
Causa: $WEB_PREFIX = /Mensa/prenotazionimensa concatenato a $next = Mensa/prenotazionimensa/admin/ → prefisso duplicato
Fix auth_mensa.php: $next = $req (path assoluto con slash iniziale, es. /Mensa/prenotazionimensa/admin/) risolto
Fix login.php — mensa_normalize_next(): rimosso ltrim($next, "/") per preservare lo slash iniziale risolto
Fix login.php — redirect: $dest = ($next[0] === '/') ? $next : $WEB_PREFIX . "/" . $next risolto
🎨
9 Fix CSS admin (style_admin.css)
Path hardcoded senza WEB_PREFIX causava 404 sul foglio di stile
admin.php — riga 2293
Problema: <link href="/admin/style_admin.css"> hardcoded senza $WEB_PREFIX → HTTP 404, pannello admin senza stili
Fix: sostituito con tag dinamico usando $WEB_PREFIX risolto
Modifica applicata direttamente sul server con sudo sed -i dopo aver risolto i permessi
HTML/PHP — admin.php riga 2293 (dopo fix)
<link rel="stylesheet" href="<?= htmlspecialchars($WEB_PREFIX, ENT_QUOTES) ?>/admin/style_admin.css">
📷
10 Fix display monitor
Dopo scansione il display non mostrava nulla — problema di proprietà file JSON
cuoca/last_scan*.json
Problema: dopo scansione il display display.php non mostrava nulla
Causa: file last_scan_16.json e last_scan.json copiati dal PC con proprietario lecchese → Apache (www-data) non poteva sovrascriverli durante la scansione
Fix: rimossi i file JSON preesistenti — da quel momento scan_relay.php ricrea i file direttamente come www-data risolto
Bash — rimozione file JSON bloccanti
sudo rm /var/www/html/Mensa/prenotazionimensa/cuoca/last_scan*.json
🏆
Risultato finale
Migrazione completata con successo — app operativa sul Raspberry Pi
🌐
URL applicazione
https://areaftp.mollificiolecchese.it/Mensa/prenotazionimensa/
📺
URL display monitor (cuoca)
https://areaftp.mollificiolecchese.it/Mensa/prenotazionimensa/cuoca/display.php?token=4683a4ea2f967c4768d60068d5755e87
Login dipendenti e admin funzionante OK
Pannello admin con CSS corretto OK
Scansione QR code e display monitor operativi OK
Hostinger (mydigitaltools.it) rimane attivo e indipendente per demo/vendita invariato
📌
Note importanti per future manutenzioni
Differenze rispetto all'ambiente Hostinger/MySQL standard
⚠️
RANDOM_BYTES() non disponibile

MariaDB non ha RANDOM_BYTES() (funzione MySQL). Usare REPLACE(UUID(),'-','') oppure MD5(RAND()) come alternativa.

🔐
Accesso MariaDB — no password root

Il comando di accesso su Raspberry è sudo mariadb. L'autenticazione avviene tramite unix_socket, non serve password per root.

🔗
Comandi import/export: mariadb

I comandi di import ed export usano mariadb invece di mysql. Esempio: sudo mariadb db_name < file.sql

📄
Cartella include/ protetta

La cartella include/ è dentro /var/www/html/ ma protetta da .htaccess con Require all denied. Nessun accesso web diretto ai file di connessione DB.

📄
Permessi cuoca/ — 775

La cartella cuoca/ deve rimanere con permessi 775 per permettere la scrittura dei file last_scan*.json da parte di Apache (www-data).

👥
Proprietario file: lecchese

Il proprietario dei file è lecchese (non www-data) per permettere upload via FileZilla. Il gruppo è www-data per la lettura Apache.

🔄
11 Aggiornamento futuro — Sincronizza dati da Hostinger
Da fare tra qualche settimana — solo dati Mollificio Lecchese (azienda_id = 16)
mensa_prenotazioni
Perché: dopo qualche settimana di uso su Hostinger, il DB del Mollificio avrà prenotazioni, dipendenti e dati aggiornati. Questa procedura sposta quei dati sul Raspberry mantenendo solo quelli di azienda_id = 16, senza toccare la configurazione.
A — Esporta il DB da Hostinger phpMyAdmin
Seleziona u568594947_pren_mesa → Esporta → SQL → Esegui. Salva il file .sql sul PC.
B — Copia il file sul Raspberry via FileZilla
Carica il file .sql nella home directory /home/lecchese/
C — Importa in un database temporaneo
Bash — crea DB temporaneo e importa
# Crea DB temporaneo e importa il dump di Hostinger
sudo mariadb -e "CREATE DATABASE temp_mensa CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mariadb temp_mensa < ~/u568594947_pren_mesa.sql
D — Copia solo i dati di azienda_id = 16 nel DB produzione
SQL — sincronizza solo azienda_id = 16
-- Tabella azienda
DELETE FROM mensa_prenotazioni.azienda WHERE id = 16;
INSERT INTO mensa_prenotazioni.azienda
    SELECT * FROM temp_mensa.azienda WHERE id = 16;

-- Dipendenti
DELETE FROM mensa_prenotazioni.dipendente WHERE azienda_id = 16;
INSERT INTO mensa_prenotazioni.dipendente
    SELECT * FROM temp_mensa.dipendente WHERE azienda_id = 16;

-- Prenotazioni
DELETE FROM mensa_prenotazioni.prenotazione WHERE azienda_id = 16;
INSERT INTO mensa_prenotazioni.prenotazione
    SELECT * FROM temp_mensa.prenotazione WHERE azienda_id = 16;

-- Piatti sostituzione (se presenti)
DELETE FROM mensa_prenotazioni.azienda_pasto_sostituzione WHERE azienda_id = 16;
INSERT INTO mensa_prenotazioni.azienda_pasto_sostituzione
    SELECT * FROM temp_mensa.azienda_pasto_sostituzione WHERE azienda_id = 16;

-- Sessioni auth — forza nuovo login a tutti
DELETE FROM mensa_prenotazioni.auth_sessions WHERE dipendente_id IN (
    SELECT id FROM mensa_prenotazioni.dipendente WHERE azienda_id = 16
);

EXIT;
E — Elimina il database temporaneo
Bash — pulizia
sudo mariadb -e "DROP DATABASE temp_mensa;"
sudo rm -f /var/www/html/Mensa/prenotazionimensa/cuoca/last_scan*.json
Fatto. Il Raspberry ora ha tutti i dati aggiornati del Mollificio. Credenziali e configurazione rimangono invariate. completato
Nota: se nel frattempo hai aggiunto tabelle nuove sul Raspberry non presenti su Hostinger, non vengono toccate — questa procedura opera solo sulle tabelle elencate sopra.