Allez, on continue d’optimiser notre serveur : aujourd’hui, je vous montre comment améliorer nettement les performances du serveur.
Nous allons d’abord installer un système de cache – j’ai choisi APC – qui va soulager un peu le système en mettant en cache les pages du site les plus demandées.
Cela aura un impact sur le temps de traitement des pages (moins de traitement PHP) et sur la base de données (moins de requêtes SQL).
Dans un second temps, nous installons Varnish comme reverse-proxy pour Apache : tous les objets statiques (images, CSS, JS) seront traités par Varnish, le reste (PHP) sera traité par Apache. Cela divise sensiblement la charge serveur.
Installation d’APC
APC est un système de cache que je trouve très performant. On l’installe avec :
pecl install apc
puis on crée le fichier de configuration :
nano /etc/php/7.4/conf.d/apc.ini
et on y ajoute :
extension=apc.so
apc.enabled=1
apc.shm_size=128M
apc.stat=0
apc.ttl=7200
apc.user_ttl=7200
apc.enable_cli=1
apc.max_file_size=10M
apc.rfc1867 = On
Si vous avez une erreur de compilation lors de l’installation d’APC, c’est sûrement que le paquet libpcre3-dev
n’est pas installé. Dans ce cas :
apt-get install libpcre3-dev
Code language: JavaScript (javascript)
Il ne reste plus qu’à relancer Apache : :
/etc/init.d/apache2 restart
A noter qu’APC est livré avec un script PHP (nommé apc.php) qui vous permet de voir quelques statistiques sur la mise en cache de vos fichiers. Petit exemple de ce que cela donne :
Pour installer apc.php, il faut le copier le fichier à la racine de notre site :
cp /usr/share/doc/php-apc/apc.php /home/skyminds/public_html/
puis l’éditer :
nano /home/skyminds/public_html/apc.php
pour y modifier le mot de passe :
defaults('ADMIN_USERNAME','apc'); // Admin Username
defaults('ADMIN_PASSWORD','password'); // Admin Password - CHANGE THIS TO ENABLE!!!
Code language: JavaScript (javascript)
Voilà, APC est installé et actif.
Installation de Varnish
Passons maintenant à l’installation du serveur Varnish :
wget http://repo.varnish-cache.org/debian/GPG-key.txt
apt-key add GPG-key.txt
echo "deb http://repo.varnish-cache.org/debian/ lenny varnish-2.1" >> /etc/apt/sources.list
apt-get update
apt-get install varnish
Code language: JavaScript (javascript)
Principe de fonctionnement : Varnish va écouter sur le port 80. C’est lui qui va traiter toutes les requêtes : il va transmettre à Apache (sur le port 8080) tout ce qui est dynamique (PHP etc) et s’occupera lui-même des fichiers statiques (images, javascripts etc).
Cela va donc alléger notre serveur Apache et nous allons pouvoir mettre en cache tous les éléments statiques.
On configure le serveur Varnish en éditant le fichier de configuration :
nano /etc/default/varnish
Code language: JavaScript (javascript)
Dans ce fichier, naviguez jusqu’à l’alternative #2 et changez le port 6081 en 80 (première ligne) :
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
Code language: JavaScript (javascript)
Le fichier varnish_storage.bin
sera limité à 1 Go, sachant que ma Kimsufi possède 2 Go de RAM.
Comme Varnish tourne maintenant sur le port 80, il faut maintenant forcer Apache à écouter sur le port 8080.
On édite donc :
nano /etc/apache2/ports.conf
et on change toutes les références à 80 en 8080 :
NameVirtualHost *:8080
Listen 8080
Code language: CSS (css)
Passons maintenant à la configuration de notre site dans Varnish et éditons /etc/varnish/default.vcl
:
nano /etc/varnish/default.vcl
Code language: JavaScript (javascript)
on y met :
/* ------------------------------------------------------------ */
/* VCL Configuration by Matt - www.skyminds.net */
/* ------------------------------------------------------------ */
# Redirect requests to Apache
backend www {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
# Called after a document has been successfully retrieved from the backend.
sub vcl_fetch {
# set minimum timeouts to auto-discard stored objects
set beresp.grace = 5m;
if (beresp.ttl < 8h)
{
set beresp.ttl = 8h;
}
if (req.url ~ "\.(png|gif|jpg|swf|css|js)$")
{
unset beresp.http.set-cookie;
}
## Deliver the content
return(deliver);
}
sub vcl_recv {
# Serve objects up to 5 minutes past their expiry if the backend is slow to respond.
set req.grace = 5m;
# Compatiblity with Apache log
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
if (req.http.host ~ "^(www\.)?skyminds\.net$")
{
set req.backend = www;
}
### always cache these images & static assets & Remove cookies and query string for real static files
if (req.url ~ "^/[^?]+\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|rar|lzma|bz2|tgz|tbz|html|htm)(\?.*|)$")
{
unset req.http.cookie;
set req.url = regsub(req.url, "\?.*$", "");
}
# Normalize Content-Encoding
if (req.http.Accept-Encoding)
{
if (req.url ~ "\.(jpg|png|gif|gz|rar|tgz|bz2|lzma|tbz|mp3|ogg)(\?.*|)$")
{
remove req.http.Accept-Encoding;
}
elsif (req.http.Accept-Encoding ~ "gzip")
{
set req.http.Accept-Encoding = "gzip";
}
elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE")
{
set req.http.Accept-Encoding = "deflate";
}
else
{
remove req.http.Accept-Encoding;
}
}
### never cache POST requests
if (req.request == "POST")
{
set req.backend = www;
return(pass);
}
return(lookup);
}
Code language: PHP (php)
et on ouvre les ports dans iptables :
iptables -A OUTPUT -p tcp --dport 8080 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 6082 -s 127.0.0.1 -j ACCEPT
Code language: CSS (css)
on redémarre pour appliquer les changements :
/etc/init.d/varnish restart
/etc/init.d/apache2 restart
Modification du Virtual Host
Il faut mettre à jour notre virtual host :
nano /etc/apache2/sites-available/www.skyminds.net
On remplace la ligne des logs par:
# ajout des logs
CustomLog /var/log/apache2/www-access.log varnishcombined
ErrorLog /var/log/apache2/www-error.log
Code language: PHP (php)
Ensuite, on édite /etc/apache2/apache2.conf
:
nano /etc/apache2/apache2.conf
et on y ajoute, en bas du fichier, au niveau des logs :
# VARNISH
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnishcombined
# Access log for VirtualHosts that don't define their own logfile
CustomLog /var/log/apache2/other_vhosts_access.log vhost_combined
Code language: PHP (php)
et on recharge Apache pour prendre en compte nos changements:
/etc/init.d/apache2 reload
Voilà, vos fichiers statiques sont mis en cache et servis par Varnish.
Les fichiers dynamiques sont servis par Apache et mis en cache avec APC.
Synopsis » Monter un serveur dédié de A à Z
- Serveur dédié : installation d’Apache, PHP, MySQL et Webmin
- Serveur dédié : créer la base de données MySQL et importer WordPress
- Serveur dédié : créer et activer un Virtual Host sous Apache
- Serveur dédié : changer les DNS du nom de domaine et le faire pointer vers le serveur
- Serveur dédié : sécurisation des services avec iptables et fail2ban
- Serveur dédié : sécurisation de la couche TCP/IP
- Serveur dédié : création d’un serveur mail Postfix (sécurisé avec Saslauthd et certificat SSL) et Courier (accès POP et IMAP) utilisant une base MySQL d’utilisateurs/domaines virtuels
- Serveur dédié : sécuriser Apache 2 avec ModSecurity
- Serveur dédié : CHMOD récursif sur des fichiers ou répertoires en ligne de commande
- Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse-proxy pour Apache pour améliorer les performances
- Serveur dédié : afficher la véritable IP derrière un reverse-proxy comme Varnish
- Serveur dédié : intégrer SSH à WordPress pour mettre à jour le core, les plugins et les thèmes
- Serveur dédié : installer la dernière version d’APC par SVN
- Serveur dédié : analyse des performances du serveur
- Serveur dédié : mettre à jour le noyau Debian de la Kimsufi
- Serveur dédié : sauvegarde automatique des fichiers avec Backup Manager sur le serveur de sauvegarde OVH
- Serveur dédié : configurer la limite mémoire pour PHP et Suhosin
- Bash : supprimer tous les fichiers et sous-répertoires d’un répertoire
- Serveur dédié : impossible de se connecter à un port distant
- Rsync: rapatrier les fichiers du serveur à la maison
- Bash : réparer les tables MySQL en cas de crash
- Serveur dédié : création d’une seedbox avec Transmission
- Serveur dédié : des paquets LAMP à jour sous Debian
- Serveur dédié : mise à jour vers Debian 7 Wheezy
- Serveur dédié : activer X11 forwarding pour SSH
- Serveur dédié : optimiser toutes les images JPG et PNG avec OptiPNG et JpegOptim
- Postfix : résoudre l’erreur “fatal: www-data(33): message file too big”
- Serveur dédié : mise en place de l’IPv6
- WordPress : accorder les bonnes permissions aux fichiers et dossiers avec chown et chmod
- WordPress : héberger les images sur un sous-domaine
- Serveur dédié : ajouter l’authentification SPF, Sender-ID et DKIM à Postfix et Bind9 avec opendkim
- Apache : lorsque le domaine seul (sans WWW) renvoie une erreur 403
- Serveur dédié : sécuriser Apache avec HTTPS (HTTP avec la couche TLS/SSL) en Perfect Forward Secrecy
- Serveur dédié : passer WordPress en HTTPS (TLS/SSL)
- Serveur dédié : configurer Webmin en TLS avec un certificat SSL
- Serveur dédié : configurer Transmission pour accéder au WebUI via TLS-SSL
- Serveur dédié : installer et configurer Varnish 4
- Serveur dédié : passage au mod FastCGI et PHP-FPM avec Apache MPM Worker
- Récupérer un serveur Kimsufi après un plantage de kernel avec le mode rescue OVH
- Serveur dédié : configurer Postfix et Courier pour utiliser TLS-SSL en Perfect Forward Secrecy
- Serveur dédié : retirer Varnish, devenu inutile avec HTTPS
- Serveur dédié : installer la dernière version d’OpenSSL sous Debian
- Serveur dédié : activer l’IP canonique du serveur sous Apache
- Serveur dédié : mise à jour vers PHP 5.6
- MySQL : convertir les tables MyISAM au format InnoDB
- Serveur dédié : optimiser toutes les images GIF avec GIFsicle
- Serveur dédié : migration de MySQL vers MariaDB
- BASH : lister, bloquer et débloquer des adresses IP avec iptables
- Serveur dédié : produire une meilleure réserve d’entropie avec haveged
- Serveur dédié : mettre en place DNSSEC pour sécuriser les DNS du domaine
- Serveur dédié : mise en place du protocole DANE
- 8 règles d’or pour bien déployer DNSSEC et DANE
- Serveur dédié : installer PHP7 FPM avec FastCGI sous Debian
- Serveur dédié : optimiser la couche TCP
- Fail2Ban: protéger Postfix contre les attaques DoS de types AUTH, UNKNOWN et EHLO
- Serveur dédié : mettre à jour Apache pour HTTP/2
- Serveur dédié : ajouter le domaine à la liste HSTS preload
- Serveur dédié : ajouter l’authentification DMARC à Postfix et BIND
- Serveur dédié : à la recherche de l’inode perdue ou comment résoudre le problème “no space left on device”
- Serveur dédié : installer NginX avec support HTTP2 et certificat SSL, PHP, MariaDB sous Debian
Recherchez-vous un expert WordPress ou WooCommerce sur qui vous pouvez compter? Ne cherchez plus.
Bonjour,
Merci pour tes tutos ils me sont très utiles pour la mise en place d’un serveur dédie
J’ai mis en place mod-security pour sécuriser plusieurs sites en drupal, mais du aux nombres de requêtes a analysées, je l’ai supprime, je perdais trop de performances.
A propos de varnish, j’ai deux petites questions
1/ Lorsque varnish fonctionne, les logs d’apache ont comme adresse ip 127.0.0.1, y a t-il moyen de retrouver l’adresse réel du client ?
2/ Seconde question, comment peut on voir ce que varnish a en cache ? pour apc il existe une page apc.php qui se trouve dans /usr/share/doc/php-apc/ mais pour varnish ?
Il y a bien varnishtop mais c’est pas super compréhensible
Merci
Bonjour salcin,
J’ai aussi désactivé pas mal de modules pour mod-security qui ralentissait le site. Je referai une liste plus propre.
Pour l’IP en 127.0.0.1 dans les logs, il faut installer le
mod_rpaf
pour Apache. J’ai gardé ça pour le prochain tuto qui sera mis en ligne dans quelques jours :En ce qui concerne le cache de Varnish, on ne peut pas voir vraiment les pages en cache mais si tu tapes :
tu peux avoir pas mal d’informations en temps réel : request rate, mémoire utilisée, thread usage, uptime…
Bonjour,
Merci pour ces super tuto.
Je rencontre un soucis pour mettre en place varnish avec la boutique prestashop.
Le cache est affiché constament sur la boutique du coup on ne voit pas les modification faite.
le problème est présent dans le back office /front
J’ai cherché un peu comment faire tout ca mais ne maitrisant pas du tout le language vcl, ca vas être dur. Apparament il y a un histoire de purge a faire mais je ne trouve pas.
cheers
Bonjour Majeri,
Si tu veux ajouter la fonction PURGE, ajoute ceci dans ton fichier .vcl :
et dans vcl_recv, ajoute :
Si tu veux exclure une zone de ton site du cache (backoffice ou flux RSS par exemple), tu peux utiliser ce type de code dans vcl_recv :
Merci Matt.
Entre temps je me suis renseigné et j’ai trouvé les même commande que ce que tu m’as donnée.
Par contre apres faut que je trouve une solution simple pour mettre a jour mes page web en faisant un purge.
Comment tu fais toi pour par exemple mettre a jour le cache des page qui ont un subie une modification de ta part ou tout simplement des pages ou de nouveau commentaire on été posté.
Tu utilise le plugin wordpress pour varnish je suppose ?
cheers
Oui, sous WP c’est le plugin Varnish HTTP Purge.
Merci,
Apres quelques tatonement, beacoup de lecture et une nuit blanche, j’ai reussi a faire tourner comme je le souhaite varsnih avec mon prestashop.
Aussi j’ai rajouter qq ligne pour la sécurité du serveur:
Au choix: Cela trompera l’attaquant en lui indiquant un mauvais serveur web a rajouter dans le vcl_fetch:
unset beresp.http.Server;
set beresp.http.Server = “Lighthttpd Server”;
Ou encore plus radical: (même si apache sera la cible de choix)
sub vcl_deliver {
# Secure the header
remove resp.http.Via;
remove resp.http.X-Varnish;
remove resp.http.Server;
remove resp.http.X-Powered-By;
}
++
Oui, j’ai retiré les mêmes entêtes dans vcl_deliver :)
Finalement comment as tu réussi a configurer varnish avec Prestashop?
Pour moi ca me parait impossible car même en “bypassant” varnish via un return(pass); juste pour les sites prestashop j’ai toujours une erreur 503 Guru Meditation lorsque je filtre mes resultat dans la partie administration.
Finalement j’ai le même problème que toi rc183, quand je filtre une page d’administration dans le catalogue, j’ai la meme erreur :une erreur 503
POur le moment j’ai toujours pas trouvé une solution.
De plus j’ai toujours un problème pour que mes pages se purge quand il y a une mise a jour de prix par exemple.
Certaine page sont mise a jour, d’autre pas.
Salut Matt
j’ai suivi le tuto (sans tout comprendre je reconnais :( )
aucun soucis à l’install apc. Par contre à la derniere étape de restart varnish j’ai une erreur
et mon serveur est complètement down …
Une idée de solution ? je ne comprends pas du tout le message d’erreur.
Bonjour Lisa,
Apparemment, tu n’utilises pas le bon backend (ou tu en a plusieurs définis ?). Quel est le contenu de ton fichier VCL ?
Bonjour,
j’ai suivi votre excellent tutoriel pour l’installation de Varnish. Mais je rencontre une erreur 503 sur toutes les pages, qu’elles soient en html ou en php. Je n’ai pourtant rien de spécial dans mes codes de page. Celles-ci sont très longues à charger et au bout d’un certain temps, apparait une erreur 503.
Savez-vous comment il est possible de diagnostiquer le problème ?
Merci,
Je m’auto réponds. En fait, pour chaque domaine, dans la config de Varnish, il faut utiliser un backend différent ? Car j’ai configuré un backend “nomdusite” en modifiant la requête http.host et les pages fonctionnent comme il faut maintenant.
Bonjour,
Je n’utilise qu’un seul backend mais je le définis pour chaque site.
Bonjour,
“PHP Warning: Module ‘apc’ already loaded in Unknown on line 0
PHP Warning: PHP Startup: apc.shm_size now uses M/G suffixes, please update your ini files in Unknown on line 0”
Pouvez-vous mettre à jour votre tuto – excellent au passage – pour les prochains visiteurs ?
Infos : Debian 6, dédié, apache2, mysql, php5.
Bonjour PunKeel,
L’article vient d’être mis à jour, les corrections avaient été ajoutée dans un article ultérieur (Serveur dédié : installer la dernière version d’APC par SVN) mais j’avais visiblement oublié de refléter les changements ici. Merci !
Right, j’avais même pas fait attention au second article.
Merci de votre réactivité ( et du tuto :) ), PunKeel.
PS: je n’ai pas “vu” de config pour fonctionner avec CloudFlare (ouaip, une idée de mise à jour du tuto :D)
Comme ils le signalent sur leur site :
sub vcl_recv {
# Remove has_js and CloudFlare/Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
et
remove req.http.X-Forwarded-For;
if (req.http.cf-connecting-ip) {
set req.http.X-Forwarded-For = req.http.cf-connecting-ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
Cordialement, bis.
Bonjour,
merci pour ce tuto.
une petite question me tarrode concernant la configuration d’APC.
Pourquoi mettre apc.ttl=7200 au lieu de apc.ttl=0 qui ne va définir de temps.
Bonjour Djib’s,
apc.ttl
etapc.user_ttl
définissent le temps (en secondes) pendant lequel un fichier reste dans le cache.Avec 7200 secondes, les fichiers sont mis en cache pendant 2 heures, ce qui est adapté à ma configuration. On pourrait mettre une expiration beaucoup plus longue si la taille du segment (
apc.shm_size
) était plus importante.