Questa guida spiega come installare e far funzionare LibreBooking (fork di MRBS) in una sottodirectory di un sito, con WordPress installato nella root. L’obiettivo tipico è raggiungere l’app a un URL come https://esempio.it/prenotazioni/
servendo i file pubblici dalla cartella Web/
dell’applicazione.
Punti chiave da ricordare:
- La parte pubblica di LibreBooking è in
Web/
. - Nel file
config/config.php
imposta$conf['script']['url']
coerente con l’URL pubblico. - Le cartelle
tpl/
etpl_c/
devono essere scrivibili dal web server (Smarty compila i template intpl_c/
).
Prerequisiti
- Server web (Apache o nginx) con PHP (consigliato PHP-FPM) e MySQL/MariaDB.
- Estensioni PHP comuni:
mysqli
opdo_mysql
,mbstring
,intl
,json
,xml
. - mod_rewrite attivo su Apache e AllowOverride All dove serve.
Struttura delle cartelle
/var/www/html/
├── index.php ← WordPress (root del sito)
├── wp-content/ …
└── prenotazioni/ ← LibreBooking
├── Web/ ← entrypoint pubblico
│ └── index.php
├── config/
│ ├── config.dist.php
│ └── config.php
├── tpl/ ← template sorgente
└── tpl_c/ ← cache Smarty (scrivibile)
Database
CREATE DATABASE librebooking CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'lb_user'@'localhost' IDENTIFIED BY 'password_sicura';
GRANT ALL PRIVILEGES ON librebooking.* TO 'lb_user'@'localhost';
FLUSH PRIVILEGES;
Configurazione di LibreBooking
Copia config/config.dist.php
in config/config.php
e imposta almeno:
<?php
$conf['script']['url'] = 'https://esempio.it/prenotazioni/Web';
$conf['db']['type'] = 'mysqli';
$conf['db']['host'] = 'localhost';
$conf['db']['name'] = 'librebooking';
$conf['db']['user'] = 'lb_user';
$conf['db']['password'] = 'password_sicura';
date_default_timezone_set('Europe/Rome');
Permessi delle cartelle
Imposta i permessi per l’utente del web server (es. www-data
, apache
, nginx
):
cd /var/www/html/prenotazioni
mkdir -p tpl tpl_c
sudo chown -R www-data:www-data tpl tpl_c
sudo chmod -R 755 tpl tpl_c
# Durante l'installazione, se necessario:
sudo chown -R www-data:www-data config
sudo chmod -R 775 config
WordPress in root: regole di esclusione
Nel .htaccess
della root (dove c’è WordPress), aggiungi una regola che bypassi la sottocartella prima del blocco WP:
RewriteEngine On
RewriteRule ^prenotazioni/ - [L]
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
.htaccess nella sottodirectory di LibreBooking
Nel file /var/www/html/prenotazioni/.htaccess
usa destinazioni relative (senza /
iniziale) per redirigere verso Web/
. In una .htaccess
di sottodirectory, lo slash iniziale indirizzerebbe la radice del vHost, causando 404/loop.
RewriteEngine On
# Durante i test usa 302; a regime usa 301
RewriteRule ^$ Web/ [R=302,L]
RewriteRule !^Web/ Web/$0 [R=302,L]
Options -Indexes
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Non inserire direttive php_value qui se usi PHP-FPM
Require all denied
Alternativa nginx (con PHP-FPM)
Servire esplicitamente /prenotazioni/Web/
server {
listen 80;
server_name esempio.it;
root /var/www/html;
index index.php index.html;
location /prenotazioni/Web/ {
index index.php;
try_files $uri $uri/ /booking/Web/index.php?$args;
location ~* \.(ini|dist|md|lock|env|ya?ml)$ { deny all; }
autoindex off;
}
location ~ ^/prenotazioni/Web/.*\.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include snippets/fastcgi-php.conf;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include snippets/fastcgi-php.conf;
}
location ~* .(ini|dist|md|lock|env|yml|yaml)$ { deny all; }
autoindex off;
}
Alias “pulito” /prenotazioni/ → cartella fisica /prenotazioni/Web/
server {
listen 80;
server_name esempio.it;
location /prenotazioni/ {
alias /var/www/html/prenotazioni/Web/;
index index.php index.html;
try_files $uri $uri/ /index.php$args;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
# Con alias va impostato manualmente:
fastcgi_param SCRIPT_FILENAME /var/www/html/prenotazioni/Web/$fastcgi_script_name;
include snippets/fastcgi-php.conf;
}
}
location ~* .(ini|dist|md|lock|env|yml|yaml)$ { deny all; }
autoindex off;
}
Se usi l’alias per nascondere /Web/
, imposta $conf['script']['url']
a https://esempio.it/prenotazioni/
per coerenza.
Smoke test
- Crea
prenotazioni/Web/ping.txt
con contenutook
e visita/prenotazioni/Web/ping.txt
: deve dare 200. - Visita
/prenotazioni/
: deve redirigere a/prenotazioni/Web/
(302 finché testi). - Crea
prenotazioni/Web/phpinfo.php
con<?php phpinfo();
e verifica che PHP risponda.
Troubleshooting: 500 vs 404
- 500 (Internal Server Error): spesso direttive non permesse in
.htaccess
(php_value
con FPM), moduli mancanti (Header
senzamod_headers
), permessi insufficenti sutpl_c/
oconfig/
, estensioni PHP non caricate. - 404: in genere la richiesta finisce su WordPress (manca la regola di bypass in root) o le regole di
prenotazioni/.htaccess
usano destinazioni con/
iniziale.
Controlla i log del server:
# Apache (Debian/Ubuntu)
tail -n 100 /var/log/apache2/error.log
# Apache (RHEL/CentOS)
tail -n 100 /var/log/httpd/error_log
# nginx
tail -n 100 /var/log/nginx/error.log
Best practice di sicurezza
- Esporre pubblicamente solo la cartella
Web/
(o un alias che la mappi), non l’intera app. - Bloccare l’accesso a file sensibili (
.env
,.dist
,.ini
, ecc.). - Evitare
chmod 777
; preferire owner o group corretti. - Non usare
php_value
in.htaccess
con PHP-FPM; configurare inphp.ini
o nel pool FPM. - Impostare
session.autostart = 0
edate.timezone
coerente.
Note importanti su rewrite in .htaccess
- In una
.htaccess
di sottodirectory le sostituzioni dovrebbero essere relative (niente/
iniziale). Esempio corretto:RewriteRule !^Web/ Web/$0
. - La regola di bypass in root per WordPress evita che le richieste a
/prenotazioni/
cadano nell’index.php del CMS.
Checklist finale
mod_rewrite
attivo e AllowOverride All dove serve.- Regola di bypass in root:
RewriteRule ^prenotazioni/ - [L]
sopra il blocco WordPress. - In
prenotazioni/.htaccess
destinazioni senza/
iniziale versoWeb/
. tpl/
etpl_c/
scrivibili dal web server.$conf['script']['url']
coerente con l’URL pubblico esposto.- Redirect 302 → 301 solo quando tutto funziona e la cache del browser è pulita.