Il problema reale
Tre anni fa ho lanciato myBand.it — una piattaforma per musicisti, una sorta di Linktree evoluto. Ha funzionato. I musicisti erano soddisfatti. Poi è arrivata la domanda inevitabile: “Posso installare questo sul mio dominio?”
Era la domanda giusta. Una piattaforma centralizzata sul mio server è comoda per me, ma fragile per loro. Io controllo i dati, i backup, la continuità del servizio. Se chiudo domani, loro rimangono con niente. Se cambio i termini di servizio, non hanno scelta.
I musicisti volevano proprietà dei dati. Autonomia. Indipendenza.
Non potevo dargli myBand.it. Dovevo dargli qualcosa che potessero installare sul loro hosting, controllare completamente, spostare dove vogliono.
Così è nata CHIFACOSA.
Cosa significa renderlo installabile?
Non basta copiare il codice. Il vero problema è: come faccio in modo che lo stesso codice funzioni su tre ambienti completamente diversi?
- Docker (per chi è tecnico, vuole il meglio)
- WSL + Apache locale (per chi sviluppa su Windows come me)
- Aruba Hosting Basic (hosting condiviso vecchio stile, niente SSH, solo FTP)
Questi ambienti hanno esigenze opposte:
- Docker: variabili d’ambiente, container networking, storage volumes
- WSL: permessi file Windows, path locali, single machine
- Aruba: zero comandi shell, solo interfacce web, accesso limitato al filesystem
La sfida architetturale: Un unico codebase che capisce automaticamente dove gira e si configura di conseguenza.
Il primo bug: il database non era agnostico
Quando ho copiato il codice di myBand, il file schema.sql conteneva:
CREATE DATABASE myband;
USE myband;
Semplice? No. Chi installa CHIFACOSA su Aruba non può eseguire comandi SQL arbitrari — ha solo phpMyAdmin con una GUI. E il nome del database sarà user_chifacosa123, non myband.
Questo era il momento decisivo: o accettavo che il software fosse hardcoded a myBand (e quindi non realmente installabile), o ricostruivo tutto partendo da una premessa diversa.
Ho scelto la seconda strada.
La soluzione: configurazione stratificata
L’idea è semplice: il codice non deve sapere dov’è. Deve solo chiedere le credenziali al suo ambiente.
Ho implementato una gerarchia di configurazione:
Livello 1: Variabili d’ambiente (Docker, server moderni)
# docker-compose.yml
environment:
DB_HOST: mysql
DB_NAME: chifacosa
DB_USER: chifacosa_user
DB_PASS: secure_password
SITE_NAME: CHI FA COSA
ADMIN_EMAIL: admin@chifacosa.it
Il codice PHP legge queste variabili:
$db_host = getenv('DB_HOST') ?: 'localhost';
$db_name = getenv('DB_NAME') ?: 'chifacosa';
Livello 2: File config locale (Aruba, hosting condiviso)
Su Aruba le variabili d’ambiente non funzionano (non c’è modo di impostarle). Allora il codice controlla se esiste un file config.local.php:
if (file_exists(__DIR__ . '/../../config.local.php')) {
require __DIR__ . '/../../config.local.php';
$db_host = $LOCAL_DB_HOST ?? getenv('DB_HOST') ?: 'localhost';
}
L’utente di Aruba crea semplicemente:
<?php
// config.local.php (mai committato su GitHub)
$LOCAL_DB_HOST = '192.168.x.x';
$LOCAL_DB_NAME = 'user_chifacosa';
$LOCAL_DB_USER = 'user_chifacosa';
$LOCAL_DB_PASS = 'password_dal_pannello_aruba';
Questo significa: Il codice funziona ovunque. Su Docker legge le variabili d’ambiente. Su Aruba legge il file locale. Su WSL legge i defaults, ma puoi anche aggiungere un file locale se vuoi.
Il wizard: automazione intelligente
Non posso chiedere all’utente di importare manualmente schema.sql con phpMyAdmin. Troppo complicato. Allora ho creato install.php — una pagina che:
- Controlla se il database è già stato inizializzato
- Se no, guida l’utente passo per passo
- Su Aruba (dove non posso eseguire SQL), fornisce il file SQL pre-generato da importare via phpMyAdmin
- Su Docker, esegue direttamente lo schema
- Una volta completato, chiede nome del sito, email admin, password
- Blocca il wizard — non può essere rilancato
function check_installation_complete() {
try {
$stmt = $pdo->query("SELECT COUNT(*) FROM users");
if ($stmt->fetchColumn() === 0) {
header('Location: /install.php');
exit;
}
} catch (Exception $e) {
// Database non inizializzato
header('Location: /install.php');
exit;
}
}
Ogni pagina chiama questa funzione. Se zero utenti nel database, ti reindirizza automaticamente all’installer. È semplice, elegante, e funziona su tutti e tre gli ambienti.
Il costo di questa portabilità
Non è gratis. Ho dovuto:
- Niente path assoluti: Tutto relativo a costanti definite al boot
- PDO con prepared statements: Non optional — SQL injection è un rischio reale quando il software viene installato su hosting di bassa qualità
- Schema SQL puro, no migration tool: Laravel Migrations o Doctrine sarebbero troppi per hosting condiviso. Uso schema.sql puro + note di upgrade nel README
- Gestione dei permessi file: Su WSL, cambiare proprietario a
www-datarende i file illeggibili da Esplora File. Soluzione: mantenere proprietariogianluca, usare ACL o gestire permessi via PHP
Il flusso di deploy: tre realtà diverse
Docker
git clone https://github.com/posillipo/chifacosa.git
docker-compose up
# Accesso a http://localhost, install.php auto-configura tutto
Aruba
- Crea database via pannello di controllo
- Importa schema.sql via phpMyAdmin
- Carica file via FTP
- Crea
config.local.phpcon credenziali - Visita
https://tuodominio.it/install.php
Lo stesso codice. Due install path diversi. Zero modifiche.
Perché è importante
CHIFACOSA è uno strumento di liberazione. Non per i developer — per i creativi, i musicisti, i professionisti che non vogliono dipendere da una SaaS.
Ma questo è possibile solo se il software è realmente autonomo. Se richiede SSH, comandi shell, variabili d’ambiente custom — allora non è per persone normali. È per persone che sanno come amministrare un server.
Io voglio che CHIFACOSA sia per persone normali.
Tutto il tecnicismo che vedrai negli articoli seguenti serve a un unico scopo: nascondi la complessità dietro a un’interfaccia semplice che funziona dovunque.
Nel prossimo articolo: Come ho strutturato la directory, il pattern MVC minimalista senza framework, e come il database schema comunica con il frontend tramite API REST semplici.