Il contesto
Gestisco oltre 15 applicazioni in produzione su un singolo VPS Ubuntu, in self-hosted: Symfony, servizi Node, front React statici. Stack Apache + PHP-FPM + MySQL. Ecco come regge tutto questo.
Un vhost per applicazione
<VirtualHost *:80>
    ServerName baccalaureat.sn
    DocumentRoot /var/www/baccalaureat/public

    <Directory /var/www/baccalaureat/public>
        AllowOverride All
        Require all granted
        FallbackResource /index.php
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/baccalaureat.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>
Pool PHP-FPM isolati: la chiave della stabilità
L'errore del principiante: un unico pool per tutto. Se un'applicazione va in tilt, si porta dietro tutto il server. La soluzione: un pool per applicazione, con il proprio user di sistema.
; /etc/php/8.4/fpm/pool.d/baccalaureat.conf
[baccalaureat]
user = www-baccalaureat
listen = /run/php/baccalaureat.sock
pm = dynamic
pm.max_children = 10
Una vulnerabilità su un sito non dà accesso ai file degli altri.
MySQL: un database e un user per applicazione
CREATE DATABASE blog_db CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
CREATE USER 'blog_user'@'localhost' IDENTIFIED BY '...';
GRANT ALL PRIVILEGES ON blog_db.* TO 'blog_user'@'localhost';
Mai un user MySQL condiviso. Se delle credenziali trapelano, i danni sono contenuti.
I servizi Node sotto systemd
# /etc/systemd/system/trackos.service
[Service]
ExecStart=/usr/bin/node /var/www/trackos/server.js
Restart=always
User=www-trackos
Cosa ne ricavo
  • Un pool PHP-FPM + un user di sistema per applicazione = compartimentazione e stabilità.
  • Un database + un user MySQL per progetto, mai condivisi.
  • systemd per tutto ciò che deve restare attivo.
  • Il self-hosting impone rigore sull'isolamento.