03-comment-je-travaille/vps/02-stack-web.md

Stack web — Apache, PHP-FPM, MySQL, Node, Composer

Prérequis : serveur durci (01-provisionement.md). Point d'arrivée : stack complète installée, PHP-FPM actif, MySQL opérationnel.


1. Apache 2.4

Installation

sudo apt install -y apache2

Modules indispensables

# SSL + headers HTTP
sudo a2enmod ssl
sudo a2enmod headers

# Réécriture d'URL (Symfony routing)
sudo a2enmod rewrite

# HTTP/2 (performance)
sudo a2enmod http2

# FastCGI pour PHP-FPM
sudo a2enmod proxy_fcgi
sudo a2enmod setenvif

# Compression (Brotli en priorité, Gzip en fallback)
sudo apt install -y libapache2-mod-brotli
sudo a2enmod brotli
sudo a2enmod deflate

# Module MPM Event (obligatoire avec PHP-FPM — remplace prefork)
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event

sudo systemctl restart apache2

Vérifier les modules actifs

apache2ctl -M | sort

2. PHP 8.5-FPM

PHP-FPM (FastCGI Process Manager) est requis avec MPM Event. Il gère les processus PHP séparément d'Apache.

Installation

# Dépôt PHP 8.5 si non disponible sur la distribution
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

# PHP-FPM + extensions
sudo apt install -y \
  php8.5-fpm \
  php8.5-mysql \
  php8.5-sqlite3 \
  php8.5-zip \
  php8.5-gd \
  php8.5-mbstring \
  php8.5-curl \
  php8.5-xml \
  php8.5-intl \
  php8.5-bcmath \
  php8.5-dom \
  php8.5-pdo

# Lier PHP-FPM Ă  Apache
sudo a2enconf php8.5-fpm
sudo systemctl restart apache2 php8.5-fpm

Configuration du pool PHP-FPM

Fichier : /etc/php/8.4/fpm/pool.d/www.conf

[www]
user  = www-data
group = www-data

; Socket UNIX (plus rapide que TCP pour un serveur local)
listen = /run/php/php8.5-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode  = 0660

; Gestion dynamique des processus
pm = dynamic
pm.max_children      = 20
pm.start_servers     = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests      = 500   ; recycler les workers après N requêtes (prévient les fuites mémoire)

OPcache — configuration de production

Fichier : /etc/php/8.4/fpm/conf.d/10-opcache.ini

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=0

; ⚠️ CLEF DE PROD : ne jamais valider les timestamps (perf max)
; Conséquence : reload PHP-FPM OBLIGATOIRE après tout git pull
opcache.validate_timestamps=0

Le piège OPcache en production. Avec validate_timestamps=0, PHP-FPM sert le bytecode compilé en mémoire indéfiniment. Après un git pull, le web sert l'ancien code même si le CLI exécute le nouveau. Symptôme classique : SQLSTATE[42S22] Unknown column 't0.username' — la migration est passée, le web ignore le nouveau schéma. Toujours sudo systemctl reload php8.5-fpm après chaque déploiement.

sudo systemctl reload php8.5-fpm
# (reload = graceful, pas de coupure de service)

3. MySQL 8.4

Installation

sudo apt install -y mysql-server
sudo mysql_secure_installation

Création base et utilisateur

-- Se connecter en root
sudo mysql

CREATE DATABASE telaria_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'telaria_user'@'localhost' IDENTIFIED BY 'mot_de_passe_fort';
GRANT ALL PRIVILEGES ON telaria_db.* TO 'telaria_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Convention de nommage : telaria_db / telaria_user (underscores — pas de tirets, incompatibles avec certains outils MySQL).

Restriction réseau

MySQL doit écouter uniquement en local (pas de port 3306 exposé sur le réseau public) :

# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
bind-address = 127.0.0.1
sudo systemctl restart mysql

Vérifier :

sudo ss -tlnp | grep 3306
# Doit afficher : 127.0.0.1:3306 (pas 0.0.0.0:3306)

Vérification

mysql -u telaria_user -p telaria_db -e "SELECT 1;"

Sauvegarde

# Export (seule donnée non régénérable — à automatiser)
mysqldump -u telaria_user -p telaria_db > backup_$(date +%Y%m%d).sql

# Restauration
mysql -u telaria_user -p telaria_db < backup_YYYYMMDD.sql

4. Node.js v20

Node est requis pour la compilation des assets front (AssetMapper Symfony peut l'utiliser selon la configuration).

# Via NodeSource (version LTS stable)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

node -v    # v20.x.x
npm -v

5. Composer

# Téléchargement et installation globale
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
chmod +x /usr/local/bin/composer

composer --version   # 2.9.x

6. Vérification globale

apache2 -v          # Apache/2.4.63
php8.5 -v           # PHP 8.5 (fpm-fcgi)
mysql --version     # 8.4.7
node -v             # v20.x
composer --version  # 2.9.x
python3 --version   # 3.13.x (pour le microservice embeddings)
# Services actifs
sudo systemctl status apache2 php8.5-fpm mysql

État attendu à l'issue

  • Apache actif avec MPM Event + proxy_fcgi + http2 + brotli
  • PHP 8.5-FPM sur socket UNIX, OPcache configurĂ© pour la prod
  • MySQL 8.4 avec base telaria_db et utilisateur telaria_user
  • Composer et Node installĂ©s globalement

Étape suivante : 03-vhosts-multisite.md

Assistant documentaire

Posez une question sur la documentation. Les réponses citent leurs sources — un clic ouvre le document à gauche.

Loading…
Loading the web debug toolbar…
Attempt #