Déploiement et hébergement d'une application PHP

Apprenez à préparer votre application PHP pour la production, choisir le bon type d'hébergement et configurer correctement votre serveur pour une sécurité et des performances optimales.

Préparer son application PHP pour la production

Le déploiement d'une application PHP en production nécessite plusieurs étapes importantes pour assurer sa stabilité, sa sécurité et ses performances.

Checklist avant déploiement

Les points essentiels à vérifier
  1. Sécurité : Audit du code pour détecter les vulnérabilités
  2. Optimisation : Tests de performance et d'optimisation
  3. Configuration : Adaptation des paramètres PHP et du serveur web
  4. Dépendances : Vérification et mise à jour des bibliothèques tierces
  5. Base de données : Optimisation des requêtes et indexation
  6. Environnement : Séparation des configurations de dev et prod
  7. Surveillance : Mise en place d'outils de monitoring
  8. Sauvegarde : Stratégie de backup et de récupération

Configuration PHP pour la production

Paramètres php.ini recommandés
# Désactiver l'affichage des erreurs pour les utilisateurs
display_errors = Off
display_startup_errors = Off

# Mais les enregistrer dans des logs
error_reporting = E_ALL
log_errors = On
error_log = /chemin/vers/php_errors.log

# Limiter l'exposition d'informations
expose_php = Off

# Optimiser l'utilisation de la mémoire
memory_limit = 256M
max_execution_time = 60

# Cache d'opcodes pour de meilleures performances
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0
opcache.save_comments = 1

# Sécurité des sessions
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
session.cookie_samesite = "Lax"

Cette configuration désactive l'affichage d'erreurs tout en les journalisant, limite les informations exposées et active l'OPCache pour de meilleures performances.

Fichier .htaccess de base
# Activation du moteur de réécriture
RewriteEngine On

# Redirection HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Protection des fichiers sensibles
<FilesMatch "(^\.env|\.gitignore|composer\.json|composer\.lock)">
    Order allow,deny
    Deny from all
</FilesMatch>

# Masquer la signature du serveur
ServerSignature Off

# Désactiver le listage des répertoires
Options -Indexes

# Compresser les fichiers statiques
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/json
</IfModule>

# Mettre en cache les fichiers statiques
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType text/javascript "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
</IfModule>

Ce fichier .htaccess configure la redirection HTTPS, protège les fichiers sensibles, désactive l'indexation des répertoires, compresse et met en cache les fichiers statiques.

Gestion des environnements avec des fichiers .env

Utilisation de variables d'environnement

Les fichiers .env permettent de stocker des informations sensibles et des configurations spécifiques à chaque environnement hors du code source.

Exemple de fichier .env :

# Environnement
APP_ENV=production
APP_DEBUG=false
APP_URL=https://monsite.com

# Base de données
DB_HOST=localhost
DB_NAME=app_production
DB_USER=user_prod
DB_PASS=password_securise_production

# Email
MAIL_HOST=smtp.mondomaine.com
MAIL_PORT=587
MAIL_USERNAME=noreply@mondomaine.com
MAIL_PASSWORD=mot_de_passe_securise
MAIL_ENCRYPTION=tls

# API Keys
STRIPE_KEY=pk_live_xxxxxxxxxxxxxxxxxxxxxxxx
STRIPE_SECRET=sk_live_xxxxxxxxxxxxxxxxxxxxxxxx

Exemple d'utilisation avec la bibliothèque vlucas/phpdotenv :

// Installer via : composer require vlucas/phpdotenv

require_once 'vendor/autoload.php';

// Charger les variables d'environnement
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

// Utiliser les variables d'environnement
$dbConnection = new PDO(
    'mysql:host=' . $_ENV['DB_HOST'] . ';dbname=' . $_ENV['DB_NAME'],
    $_ENV['DB_USER'],
    $_ENV['DB_PASS']
);

Bonnes pratiques :

  • Ne jamais commiter le fichier .env dans le contrôle de version (ajouter à .gitignore)
  • Fournir un exemple de fichier .env.example avec la structure mais sans les informations sensibles
  • Utiliser des valeurs différentes pour chaque environnement (développement, test, production)

Optimisation des performances

Mise en cache
// Utilisation de APCu pour le cache en mémoire
function getCachedData($key, $ttl = 3600) {
    if (function_exists('apcu_exists') && apcu_exists($key)) {
        return apcu_fetch($key);
    }
    
    $data = fetchDataFromDatabase(); // Fonction coûteuse
    
    if (function_exists('apcu_store')) {
        apcu_store($key, $data, $ttl);
    }
    
    return $data;
}

Différentes options de cache pour PHP :

  • APCu : Cache en mémoire rapide et simple
  • Redis : Store clé-valeur en mémoire avec persistance
  • Memcached : Système de cache distribué
  • Cache de fichiers : Solution simple sans dépendances
Compression et minification
// Minification de HTML à la volée
function minifyHtml($html) {
    // Supprimer les commentaires HTML
    $html = preg_replace('//', '', $html);
    
    // Supprimer les espaces, tabulations et retours à la ligne superflus
    $search = [
        '/\>[^\S ]+/s',  // Espaces après tag fermant
        '/[^\S ]+\,  // Espaces avant tag ouvrant
        '/(\s)+/s',      // Espaces consécutifs
        '/>\s+,       // Espaces entre les balises
    ];
    
    $replace = ['>', '<', '\\1', '><'];
    
    return preg_replace($search, $replace, $html);
}

// Utilisation avec la mise en tampon de sortie
ob_start('minifyHtml');

En production, pensez également à :

  • Minifier les fichiers CSS et JavaScript
  • Activer la compression GZIP/Brotli sur le serveur
  • Optimiser les images (WebP, compression, redimensionnement)
  • Regrouper les fichiers CSS/JS pour réduire les requêtes HTTP

Hébergement mutualisé vs VPS vs Cloud

Le choix d'une solution d'hébergement dépend de nombreux facteurs : budget, compétences techniques, besoins en ressources, évolutivité et spécificités de votre application.

Comparaison des solutions d'hébergement

Types d'hébergement PHP
Critère Hébergement mutualisé VPS Serveur dédié Cloud (PaaS/IaaS)
Coût Très économique
3-10€/mois
Abordable
10-50€/mois
Élevé
50-200€/mois
Variable selon l'usage
Pay-as-you-go
Contrôle Très limité Élevé (accès root) Total Variable selon le service
Gestion Facile, géré par l'hôte Nécessite des compétences Nécessite des compétences avancées Variable selon le service
Performance Limitée, ressources partagées Bonne, ressources garanties Excellente, matériel dédié Excellente, facilement extensible
Évolutivité Très limitée Moyenne Limitée (nécessite migration) Excellente (auto-scaling)
Idéal pour Sites simples, blogs, petits projets Applications web moyennes, sites d'entreprise Gros sites à trafic élevé, applications spécifiques Applications évolutives, startups en croissance

Conseil : Commencez avec une solution adaptée à vos besoins immédiats, mais avec un chemin de migration clair pour évoluer à mesure que votre application se développe.

Hébergement mutualisé

Avantages :
  • Solution la moins chère
  • Facile à configurer et à gérer
  • Interface d'administration conviviale (cPanel, Plesk)
  • Configuration PHP pré-installée
  • Support technique généralement inclus
Inconvénients :
  • Ressources limitées et partagées
  • "Mauvais voisins" peuvent affecter les performances
  • Peu ou pas de contrôle sur la configuration du serveur
  • Extensions PHP et versions souvent limitées
  • Problèmes pour les applications à fort trafic

Serveurs VPS (Virtual Private Server)

Avantages des VPS pour PHP
  • Ressources dédiées : CPU, RAM et stockage garantis
  • Isolation : indépendance vis-à-vis des autres clients
  • Contrôle total : configuration sur mesure du serveur
  • Accès root : installation de logiciels personnalisés
  • Flexibilité : choix de distributions Linux, version PHP
  • Scalabilité : possibilité d'augmenter les ressources
  • Coût raisonnable : rapport qualité-prix excellent
Administration d'un VPS

Gérer un VPS nécessite des compétences en administration système :

  • Installation et configuration du serveur web (Apache/Nginx)
  • Installation et sécurisation de MySQL/MariaDB
  • Configuration de PHP et des extensions nécessaires
  • Mise en place de SSL/TLS (Let's Encrypt)
  • Configuration du pare-feu et sécurité
  • Maintenance, mises à jour, monitoring
  • Sauvegardes régulières

Des panneaux de contrôle comme VestaCP, HestiaCP ou CyberPanel peuvent faciliter l'administration d'un VPS pour PHP.

Solutions cloud pour PHP

Options cloud populaires pour PHP
  • Platform as a Service (PaaS)
    • Heroku (avec buildpack PHP)
    • Platform.sh (spécialisé PHP)
    • Google App Engine
    • AWS Elastic Beanstalk
    • Laravel Forge (spécialisé Laravel)
  • Infrastructure as a Service (IaaS)
    • AWS EC2
    • Google Compute Engine
    • Microsoft Azure Virtual Machines
    • DigitalOcean Droplets
    • Linode
    • OVH Cloud
  • Containerisation
    • Docker avec PHP-FPM
    • Kubernetes pour orchestration
    • AWS Fargate/ECS

Les solutions cloud offrent une grande flexibilité et évolutivité, mais nécessitent une bonne compréhension de l'architecture cloud et peuvent engendrer des coûts plus élevés pour les applications à fort trafic.

Configuration et sécurisation des serveurs pour PHP

Une configuration appropriée du serveur web est essentielle pour les performances et la sécurité de votre application PHP.

Configuration Apache pour PHP

Virtual Host Apache pour PHP
# /etc/apache2/sites-available/monsite.conf
<VirtualHost *:80>
    ServerName monsite.com
    ServerAlias www.monsite.com
    ServerAdmin webmaster@monsite.com
    DocumentRoot /var/www/monsite/public

    # Redirection vers HTTPS
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>

<VirtualHost *:443>
    ServerName monsite.com
    ServerAlias www.monsite.com
    ServerAdmin webmaster@monsite.com
    DocumentRoot /var/www/monsite/public

    # Configuration SSL
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/monsite.crt
    SSLCertificateKeyFile /etc/ssl/private/monsite.key
    SSLCertificateChainFile /etc/ssl/certs/ca-chain.crt

    # Paramètres de sécurité SSL
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLHonorCipherOrder on
    SSLCompression off
    SSLSessionTickets off
    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM

    # Configuration PHP
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php8.1-fpm.sock|fcgi://localhost"
    </FilesMatch>

    # Paramètres du répertoire
    <Directory /var/www/monsite/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
        
        # Règles de sécurité supplémentaires
        <IfModule mod_headers.c>
            Header set X-Content-Type-Options "nosniff"
            Header set X-Frame-Options "SAMEORIGIN"
            Header set X-XSS-Protection "1; mode=block"
            Header set Content-Security-Policy "default-src 'self'"
        </IfModule>
    </Directory>

    # Fichiers de log
    ErrorLog ${APACHE_LOG_DIR}/monsite_error.log
    CustomLog ${APACHE_LOG_DIR}/monsite_access.log combined
</VirtualHost>

Cette configuration crée deux VirtualHosts : un pour HTTP qui redirige vers HTTPS, et un pour HTTPS avec une configuration sécurisée. PHP est configuré pour utiliser PHP-FPM via un socket Unix pour de meilleures performances.

Optimisation des performances Apache
# Performance tuning pour Apache
# /etc/apache2/mods-available/mpm_event.conf

<IfModule mpm_event_module>
    StartServers             2
    MinSpareThreads         25
    MaxSpareThreads         75
    ThreadLimit             64
    ThreadsPerChild         25
    MaxRequestWorkers      150
    MaxConnectionsPerChild   0
</IfModule>

# Activation des modules Apache essentiels
# a2enmod rewrite headers ssl http2 expires deflate

# Configuration de la compression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css text/javascript application/javascript application/json application/xml
</IfModule>

# Configuration de la mise en cache
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
</IfModule>

Ces configurations optimisent Apache pour de meilleures performances avec PHP :

  • MPM Event pour une meilleure gestion des connexions
  • Compression des réponses pour réduire la bande passante
  • En-têtes d'expiration pour le cache côté client
  • Modules essentiels pour les fonctionnalités modernes

Configuration Nginx pour PHP

Configuration Nginx de base
# /etc/nginx/sites-available/monsite.conf
server {
    listen 80;
    server_name monsite.com www.monsite.com;
    
    # Redirection vers HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name monsite.com www.monsite.com;
    root /var/www/monsite/public;
    index index.php index.html;
    
    # Configuration SSL
    ssl_certificate /etc/ssl/certs/monsite.crt;
    ssl_certificate_key /etc/ssl/private/monsite.key;
    ssl_trusted_certificate /etc/ssl/certs/ca-chain.crt;
    
    # Paramètres de sécurité SSL optimisés
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_stapling on;
    ssl_stapling_verify on;
    
    # En-têtes de sécurité
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Content-Security-Policy "default-src 'self'" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    
    # Traitement des fichiers PHP
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    # Accès aux fichiers statiques
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires max;
        log_not_found off;
        access_log off;
    }
    
    # Interdire l'accès aux fichiers cachés
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
    
    # Redirection pour les frameworks MVC (comme Laravel)
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

Nginx est souvent préféré pour PHP car il gère mieux les connexions concurrentes et consomme moins de ressources qu'Apache. Cette configuration inclut :

  • Support HTTPS avec paramètres optimisés
  • En-têtes de sécurité importants
  • Configuration PHP-FPM
  • Gestion efficace des fichiers statiques
  • Support pour les frameworks MVC
Optimisation de Nginx
# /etc/nginx/nginx.conf - Configuration principale
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 1024;
    multi_accept on;
    use epoll;
}

http {
    # Paramètres de base
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;
    
    # Taille des buffers
    client_max_body_size 20M;
    client_body_buffer_size 128k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;
    output_buffers 1 32k;
    postpone_output 1460;
    
    # Cache des fichiers
    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    
    # Compression gzip
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/json
        application/xml
        application/xml+rss
        application/x-javascript
        application/xhtml+xml
        application/rss+xml
        font/opentype
        image/svg+xml;
    
    # Inclure les autres fichiers de configuration
    include /etc/nginx/mime.types;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Cette configuration principale de Nginx optimise les performances :

  • Nombre de workers automatique basé sur les CPU
  • Configuration optimisée des connexions
  • Mise en cache des fichiers ouverts
  • Configuration avancée de la compression
  • Paramètres de buffer optimisés

Sécurisation des serveurs PHP

Meilleures pratiques de sécurité
  1. Utilisez PHP-FPM avec un utilisateur dédié : Isolation des processus PHP
  2. Limitez les permissions de fichiers : 644 pour fichiers, 755 pour dossiers
  3. Désactivez les fonctions dangereuses : via disable_functions dans php.ini
  4. Implémentez un pare-feu : UFW ou iptables pour filtrer le trafic
  5. Utilisez fail2ban : Protection contre les attaques par force brute
  6. Configuration automatique de Let's Encrypt : via Certbot
  7. Surveillez les journaux : Installation et configuration de logwatch ou logcheck
  8. Mises à jour automatiques : Au minimum pour les correctifs de sécurité
  9. Utilisez ModSecurity : WAF pour Apache/Nginx
  10. Sauvegardez régulièrement : Implémentez une stratégie de sauvegarde 3-2-1
  11. Audit de sécurité : Scans réguliers avec des outils comme Lynis

Exemple de configuration disable_functions dans php.ini :

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,eval

Monitoring et maintenance

Outils de surveillance
  • New Relic : Surveillance d'applications PHP professionnelle
  • Datadog : Monitoring complet avec tableaux de bord personnalisables
  • Monit : Outil léger pour surveiller les services
  • Munin/Nagios : Solutions open source éprouvées
  • Prometheus + Grafana : Monitoring puissant et visualisation

Exemple d'installation et configuration basique de Monit pour PHP-FPM :

# Installation
apt-get install monit

# Configuration pour PHP-FPM
cat > /etc/monit/conf.d/php-fpm << EOF
check process php-fpm with pidfile /var/run/php/php8.1-fpm.pid
    start program = "/etc/init.d/php8.1-fpm start"
    stop program = "/etc/init.d/php8.1-fpm stop"
    if failed unixsocket /var/run/php/php8.1-fpm.sock then restart
    if 5 restarts within 5 cycles then timeout
EOF

# Redémarrage de Monit
systemctl restart monit
Stratégie de sauvegarde

La règle 3-2-1 pour les sauvegardes :

  • 3 copies des données au total
  • 2 copies sur des supports différents
  • 1 copie hors site (cloud ou autre emplacement physique)

Script simple de sauvegarde pour une application PHP :

#!/bin/bash
# Sauvegarde d'une application PHP et de sa base de données

# Variables
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
BACKUP_DIR="/var/backups/monsite"
APP_DIR="/var/www/monsite"
DB_NAME="monsite_db"
DB_USER="db_user"
DB_PASS="db_password"
S3_BUCKET="monsite-backups"

# Créer le répertoire de sauvegarde s'il n'existe pas
mkdir -p $BACKUP_DIR

# Sauvegarde de la base de données
mysqldump -u $DB_USER -p"$DB_PASS" $DB_NAME | gzip > "$BACKUP_DIR/$DB_NAME-$TIMESTAMP.sql.gz"

# Sauvegarde des fichiers de l'application
tar -czf "$BACKUP_DIR/app-$TIMESTAMP.tar.gz" -C "$(dirname "$APP_DIR")" "$(basename "$APP_DIR")"

# Sauvegarde vers S3 (nécessite l'installation d'awscli)
aws s3 sync $BACKUP_DIR s3://$S3_BUCKET/

# Supprimer les sauvegardes locales de plus de 7 jours
find $BACKUP_DIR -type f -name "*.gz" -mtime +7 -delete

echo "Sauvegarde complétée à $(date)"

Pour automatiser, ajoutez ce script dans crontab :

0 1 * * * /chemin/vers/script_sauvegarde.sh > /var/log/backup.log 2>&1