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/php5/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 :
aptitude install libpcre3-dev |
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!!! |
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 aptitude update aptitude install varnish |
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 |
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" |
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 |
Passons maintenant à la configuration de notre site dans Varnish et éditons /etc/varnish/default.vcl :
nano /etc/varnish/default.vcl |
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); } |
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 |
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 |
Le fichier commence par cette ligne :
<VirtualHost *:80> |
On la remplace par :
<VirtualHost *:8080> # ajout des logs CustomLog /var/log/apache2/www-access.log varnishcombined ErrorLog /var/log/apache2/www-error.log |
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 |
et on recharge Apache pour tout prendre en compte :
/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.
Sommaire de la série 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
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_rpafpour 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 :
# Purge ACL acl purge { # Only localhost can purge my cache "127.0.0.1"; "localhost"; }et dans vcl_recv, ajoute :
# Allow purging from ACL if (req.request == "PURGE") { # If not allowed then a error 405 is returned if (!client.ip ~ purge) { error 405 "This IP is not allowed to send PURGE requests."; } # If allowed, do a cache_lookup -> vlc_hit() or vlc_miss() return (lookup); }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 :
# Example : do not cache the RSS feed if (req.url ~ "/feed") { return (pass); }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
Stopping HTTP accelerator: varnishd failed! Starting HTTP accelerator: varnishd failed! storage_file: filename: /var/lib/varnish/ksxxxxx.kimsufi.com/varnish_storage.bin size 1024 MB. Message from VCC-compiler: Unused backend default, defined: (input Line 89 Pos 9) backend default { --------#######-- Running VCC-compiler failed, exit 1 VCL compilation failedet 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.ttletapc.user_ttldé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.