Mise à jour de la configuration NGINX

PPmarcelPPmarcel Member
mars 2017 modifié dans Discussions générales
Bonjour,

-- Suite à cette discussion la page du wiki nginx est régulièrement mis à jour, avec des profils full HTTP/HTTP et hybride HTTP/HTTPS --

[del]La configuration nginx présente sur le wiki (voir ici) est maintenant ancienne et ne correspond vraiment plus aux bonnes pratiques de l'application.
Il faut notamment éviter l'emplois des bloc "if" dans la mesure du possible (voir documentation en anglais).[/del]

Je me suis penché sur la question pour en arriver à cette configuration (presque) minimale.
server {
    listen 80;
    server_name nom_du_site;

    root    /var/www/site;
    index  index.php index.html;

    ## WEBSITE BASICS

    # Main rule: check if file, folder, else redirect to the handler
    location / {
        try_files $uri $uri/ @handler;
    }

    # Rewrite to index
    location @handler {
        rewrite ^/(.*)$ /index.php?$1 last;
    }

    # Process PHP
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
        include fastcgi.conf;
        fastcgi_index index.php;

	# Use PHP5 or PHP7, NOT both
        #fastcgi_pass unix:/run/php5-fpm.sock;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    ## REDIRECTS

    # RSS feeds
    location /feed/ {
        rewrite ^/feed\/(.*)$ /feed.php?$1 last;
    }

    # Sitemap
    location = /sitemap.xml {
        rewrite .* /sitemap.php;
    }

    ## DIRECTORY PROTECTION

    location /data/configuration { deny all; }
    location /version   { deny all; }
    location /update    { deny all; }
    location /readme    { deny all; }
}

EDIT 1: Suppression du bloc "location /core/admin {}", inutile (merci Bazooka07)

EDIT 2: Le comportement du bloc "location ^~ /(data/configuration|version|update|\.ht)" était invalidé par "location /". Résultat on ne protégeait rien. c'est maintenant fixé dans le template.

EDIT 3: Ajout de la réécriture vers le sitemap.


Je fais appel aux utilisateurs de nginx pour avoir des retours sur cette configuration.
Vos critiques me permettront de l'affiner ou à défaut d'expliquer les choix.

Le but est de remplacer l'ancienne configuration du wiki qui n'est plus vraiment fonctionnelle avec les version récentes de nginx.

A côté de ça, si vous utilisez une configuration exotique que vous souhaitez adapter, je me ferai un plaisir de vous y aider.

Bonne soirée.

Matthieu
«1

Réponses

  • ppmtppmt Member
    J'ai copier ta config a la place de la mienne (en adaptant le root). Resultat un 403 Forbidden

    Apres avoir compare avec ma config d'origine (je suis un peu bete et ne comprends pas tout :) j'ai reussi a faire marcher en rajoutant la ligne suivante au debut du fichier
    [== Indéfini ==]
        index index.php index.html;
    

    Tout a l'air de marcher

    ah et aussi rajoute un # devant la ligne: Use PHP5 or PHP7, NOT both
    Sinon ca plante
  • PPmarcelPPmarcel Member
    mars 2016 modifié
    ppmt: Merci pour tes retours, j'ai tout intégré.

    Concernant la directive "index", elle définit quels fichiers nginx va aller lire par défaut lorsqu'on arrive dans une répertoire (la racine du site y compris). Par défaut il n'y que le index.html qui est évalué (doc), or PluXML arrive avec un index.php --> pas d'index.html --> erreur 403 (accès interdit).

    Comme je l'avais modifié dans mon /etc/nginx/nginx.conf il y a longtemps, j'avais oublié ce détail.
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    Bonne idée de parler de Nginx. Il est plus rapide que Apache.

    J'ai 2 versions de Pluxml installées chacune dans un dossier différent: pluxml-54/ et pluxml-55. De plus, j'ai quelques applis écrites en python qui tournent derrière NGinx via gunicorn.

    Et ma config pour le serveur NGINX est celle-ci :
    [== Indéfini ==]
    server {
    	listen 80 default_server;
    	listen [::]:80 default_server;
    
    	# root /var/www/html;
    	root /var/www;
    
    	# Add index.php to the list if you are using PHP
    	index html/index.nginx-debian.html index.html index.php index.htm;
    
    	server_name _;
    
    	location / {
    		# First attempt to serve request as file, then
    		# as directory, then fall back to displaying a 404.
    		try_files $uri $uri/ =404;
    	}
    
    	location ~ \.xml$ {
    		deny all;
    	}
    
    	# re-ecriture url pour Pluxml
    	rewrite ^/(?<pluxml>pluxml[^/]*)/(?<pattern>(?:(?:article|static|categorie)\d*|tag|archives)(/.*)?)$ /$pluxml/index.php?$pattern;
    	rewrite ^/(?:<pluxml>pluxml[[^/]*)/feed/(?<feed>.*)$ /$pluxml/feed.php\?$feed;
    
    	location ~ ^/pluxml[^/]*/(?:data/medias/|themes/[^/]*/(?:css|img)/|core/lib/js.src/).* {
    		try_files $uri $uri/ =404;
    	}
    	location ~ ^/pluxml[^/]*/core/lib/.*\.js {
    		try_files $uri $uri/ =404;
    	}
    	location ~ ^/pluxml[^/]*/(?:data/|themes/|core/lib/).* {
    		deny all;
    	}
    	location ~ ^/pluxml[^/]*/config.php {
    		deny all;
    	}
    
    	# remplace directive userdir de Apache2
    	location ~ ^/~(?<user>\w+)(?<path>/.*)?$ {
    		alias /home/$user/public_html$path;
    		autoindex on;
    		access_log /var/log/nginx/userdir-access.log;
    		error_log /var/log/nginx/userdir-error.log;
    		rewrite_log on;
    		location ~ \.php$ {
    			fastcgi_split_path_info ^/~\w+(/.+?\.php)(.*)$;
    			include fastcgi.conf;
    			fastcgi_param SCRIPT_NAME /~$user$fastcgi_script_name;
    			fastcgi_param DOCUMENT_ROOT /home/~$user/public_html;
    			fastcgi_index index.php;
    			fastcgi_pass unix:/var/run/php5-fpm.sock;
    		}
    	}
    
    	# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    	#
    	location ~ \.php$ {
    		include snippets/fastcgi-php.conf;
    		
    	
    	#	# With php5-cgi alone:
    	#	fastcgi_pass 127.0.0.1:9000;
    	#	# With php5-fpm:
    		# return 200 "$document_root|$fastcgi_script_name|$query_string|$content_type|$fastcgi_script_name|$request_uri|$path_info|$fastcgi_path_info";
    		fastcgi_pass unix:/var/run/php5-fpm.sock;
    	}
    
    	# deny access to .htaccess files, if Apache's document root
    	# concurs with nginx's one
    	#
    	location ~ /\.ht {
    		deny all;
    	}
    }
    
    Je précise que /var/www est en réalité un lien symbolique qui pointe vers /home/www. Le dossier home a une partition dédiée.

    Plutôt que de mettre la config sur le Wiki, je pense qu'il serait plus sympa que Pluxml propose la configuration dans le back-office au lieu de nous écrire un fichier .htaccess inutile à la racine du site.
    Hélas, il y a encore pléthore de gens qui ne connaissent que Windows et Apache :mad:
  • ppmtppmt Member
    Ca doit venir de moi mais je trouve ces config vraiment tres difficile a comprendre!

    J'ai essaye il y a quelque temps de comprendre en lisant un peu la doc, des tutorial et un livre mais au final je suis encore plus melange.

    Qu'en est-il de lighttpd? il etait a la mode fut un temps puis soudain tout le monde est passe a nginx!
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    C'est vrai que la doc de Ngins n'est pas très user-friendly.
    Comprendre les expressions régulières aide aussi beaucoup.

    Nginx est mal pris en compte par Pluxml. On mélange les fichiers statiques, qui sont juste renvoyés tels quels par le serveur qui fait proxy, et les fichiers php qui doivent être analysés par le moteur PHP. Du coup cela complique la config de Nginx.
    Le dernier example en date pour ce problème : on met l'aperçu du thème dans le même dossier que les fichiers php au lieu de le mettre dans le dossier img. Même souci avec le fichier core/lib/pluxml.min.js dans le dossier core/lib/

    Avant d'étudier Nginx, j'avais essayé Lighttpd et je j'avais trouvé plus sympa que Nginx.
    Mais il y aussi une profusion de framboises dans la nature :lol:
    Beaucoup de gens ont acheté des monocartes Raspberry pi et dessus le serveur web par défaut est Nginx. Solution sympathique pour avoir un petit serveur qui tournent 24heures/7jours chez soi, sans se ruiner en électricité, à côté de son PC de gamer :D
  • Bazzoka: Merci d'avoir partagé ta configuration. J'y revois des points abordés dans d'autres discussions déjà. :)
    Au passage j'ignorais qu'on pouvais nommer les variables sauvegardées dans les expressions régulières.

    J'ai moi même une configuration personnelle assez touffue avec du HTTPS en back-office et du cache.
    bazooka07 a écrit:
    Plutôt que de mettre la config sur le Wiki, je pense qu'il serait plus sympa que Pluxml propose la configuration dans le back-office au lieu de nous écrire un fichier .htaccess inutile à la racine du site.

    Pourquoi pas, si Stéphane est d'accord. Par contre je préconise la conservation le wiki histoire de garder la ressource facilement accessible à quiconque.

    Il faudrait aussi se mettre d'accord sur la version "standard" à adopter, probablement la plus simple possible.
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    mars 2016 modifié
  • Il n'y a pas forcément que des débutants qui y passent dans le wiki. :)
    Ca peut aussi être des gens avec de bonnes compétences voudraient juste vouloir regarder comment est gérée la configuration sans forcément vouloir installer le CMS.

    Mais on s'éloigne du sujet.

    Aurais-tu des commentaire sur la configuration du début, pour une installation de base ? (note qu'elle fonctionnera aussi avec le plugin MyBetterUrl et qu'il faut la garder simple au possible).
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    mars 2016 modifié
    Je n'ai pas testé mais le "location @handler"; qui ne me parait pas fiable.
    http://themes/defaut/css/site.css devrait se transformer en http://index.php?themes/defaut/css/site.css d'après cette régle

    location /core/admin {} ne semble pas être utile non plus.

    Cela serait mieux si Pluxml faisait la distinction entre Apache2, Nginx et Lighttpd et générait le fichier de config au lieu d'un .htaccess à la racine du site.
    Je sens que je vais devoir m'y coller :(
  • PPmarcelPPmarcel Member
    mars 2016 modifié
    En fait le "location @quelquechose"; est une approche préconisée par la doc si on utilise try_files (par là).
        location / {
            try_files $uri $uri/ @handler;
        }
    

    Le cas de figure que tu mentionnes n'arrive pas avec la directive try_files. Celle-ci teste si l'URL pointe sur un fichier ($uri), ou un répertoire ($uri/). C'est l'équivalent actualisé du test "if (-e $request_filename)", mais sans le if.
    Si l'URL est ni fichier, ni url alors l'on envoie au location nommé @handler qui fait le job de réécriture vers l'index.php.

    Pour "location /core/admin {}" tu as raison. Le fait de tester "try_files $uri/" suffit pour trouver /core/admin/index.php sans aboutir dans le handler.
    J'ai mis à jour la conf.

    Tu peux tester ce site qui fonctionne avec la configuration d'en haut: http://preprod55.maoli.fr/
  • PPmarcelPPmarcel Member
    mars 2016 modifié
    En fait on pourrait presque se passer sur handler en utilisant ce try_files :
    try_files $uri $uri/ /index.php?$uri;
    

    Le problème c'est que $uri commence par un slash, or pluxml ne peut pas ingérer ce premier slash.
    C'est bien dommage car on aurait pu se passer de la réécriture d'URL à un caractère près.

    EDIT : d'après mes tests, sans réécriture on ne tombera plus dans le location PHP et donc l'index ne sera pas interprété. Donc à première vue un équivalent du handler reste la seule option préconisée. Je creuse le sujet en marge.
  • D'autres utilisateurs de nginx pourraient-il nous partager leur avis ?
  • PPmarcelPPmarcel Member
    août 2016 modifié
    Il y avait un soucis sur la protection des répertoires clés. Le bloc "location ^~ /(data/configuration|version|update|\.ht)" était pris d'avance par "location /", car nginx traite ne traite les regex qu'en tout dernier.

    En bref: j'ai mis à jour le template du premier message, pour ceux qui l'utilisent, pensez à mettre à jours vos confs !
  • HarukaHaruka PluXml Project Manager
    Salut!

    J'utilise ton template depuis quelques mois, suite à la mise jour d'un serveur en nginx 1.10.0 et php 7.0, et ça marche nickel. Merci à toi !
  • HarukaHaruka PluXml Project Manager
    Ça mérite bien une page sur le wiki : http://wiki.pluxml.org/index.php?page=NGINX_PluXml
  • Bonjour,

    Je me suis rendu compte que le sitemap n'était pas lié à l'URL /sitemap.xml. C'est corrigé dans le premier billet ainsi que sur le wiki.
    location = /sitemap.xml {
        rewrite .* /sitemap.php;
    }
    

    Au passage, merci Peter pour le wiki. :)
  • J'ai enrichi le wiki avec des configurations mixtes HTTP/HTTPS que j'utilise ainsi que full HTTPS.
  • HarukaHaruka PluXml Project Manager
    Merci PPmarcel pour les configurations HTTPS.

    Je viens de les tester sur mon serveur et tout est OK. En revanche, j'ai ajouté une note sur le wiki concernant la gestion du HTTP/2, qui n'est disponible que depuis NGINX 1.9.5. Pour les versions précédentes il faut penser à retirer le "http2" sur la ligne "listen", dans les confs HTTPS. Dans les dépôt officiels de Debian, NGINX est en 1.6.2.
  • Merci pour cette précision dans le wiki.
  • HarukaHaruka PluXml Project Manager
    Après vérification, j'ai bien un soucis avec la réécriture d'url. Jusqu'à présent j’utilisais la règle ci-dessous, mais en remplaçant ma conf par celle proposée dans le wiki (cas 3), la réecriture ne fonctionnait plus. Mais je ne sais pas d'où vient le problème.

    Ma conf :
        location @handler {
            rewrite ^/(.*)$ /index.php?$1 last;
        }
    

    Celle du wiki :
        location @handler {
            rewrite /(.*)$ /index.php? last;
        }
    
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    Pour un dollar de plus, cela devrait mieux marcher :
    [== Indéfini ==]
    location @handler {
            rewrite /(.*)$ /index.php?$1 last;
        }
    
  • PPmarcelPPmarcel Member
    avril 2017 modifié
    Vous avez raison pour la résolution. Le problème vient du moteur du wiki qui mange les $[0-9]. Ce comportement existe depuis longtemps (toujours?), je l'avais oublié. J'ignore si on peut le by-passer.

    Attention pour les flux : même problème.

    EDIT: j'ai remplacé le symbole dollar par sa forme HTML ($). Le $1 est mieux transcrit par le wiki.
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    D'après le lien qui suit, apparament il faut mettre le caractère ^ pour éviter que le wiki cherche à interpréter le texte qui suit. Voir à la fin du lien
    http://wiki.pluxml.org/index.php?page=Syntax+reference
  • bazooka07 a écrit:
    D'après le lien qui suit, apparament il faut mettre le caractère ^ pour éviter que le wiki cherche à interpréter le texte qui suit

    Exact cela fonctionne comme un charme. La relecture n'en sera que plus aisée. Merci.
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
  • HoraceHorace Member
    Bonjour à tous,
    D’abord, merci à Pluxml !
    J’ai commencé un blog local avec EasyPhP sous Win XP, et je suis ravi de la facilité d’usage.
    J’ai aussi créé un site, www.reguin-elies.bzh, qui fonctionne très bien, sur un Raspberry Pi, supporté par NginX.
    Vous me voyez venir ?
    Donc j’ai regardé un peu la config de NginX, et celle préconisée par PPMarcel me semble tout à fait conforma à mon besoin. Mais je ne suis un gourou ni de Linux, ni de NginX, encore moins de PluxMl config !
    Question :
    Si je fais un copié-collé de cette config, en changeant simplement la ligne
    server_name nom_du_site;
    par
    www.reguin-elies.bzh,
    Ais-je une chance que ça fonctionne sans trop de problème ?
    Merci à tous ceux qui voudront bien de pencher sur ma misère !
    Je serai absent une semaine, de retour vers le 6 juin, et je me livrerai à cette expérience !
    Cordialement
    Horace
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    mai 2017 modifié
    Je suppose que tu fais référence à cette page du Wiki:
    http://wiki.pluxml.org/index.php?page=NGINX_PluXml

    Tu as 3 paramètres à ajuster selon ta config:
    [list=*]
    [*]server_name qui correspond au hostname de ton raspberry ou une entrée de ton serveur DNS qui a la même adresse IP[/*]
    [*]root qui correspond au chemin absolu du dossier qui contient PluXml[/*]
    [*]fastcgi_pass: une ligne à choisir selon ta version de PHP. Il faut commenter celle qui n'est pas la bonne.[/*]
    [/list]


    Pour info, j'ai un orange pi PC+ qui tourne sans souci avec NginX sous Debian et Ubuntu
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    @PPmarcel,

    Quand on regarde dans l'onglet réseau de l'inspecteur Web de Firefox les entêtes échangés entre le navigateur et le serveur, on s'aperçoit qu'à chaque changement de page, le navigateur va interroger le serveur pour savoir si la balise Etag a été modifiée pour chaque fichier faisant parti de la page demandée, en particulier css, javascript, images, ...
    Certes le serveur répond seulement si la balise Etag a changé ou pas. Mais à chaque fois, il y a un délai pour chaque réponse.

    Et cela parce que le serveur ne dit pas jusqu'à quand sont valides les fichiers déjà envoyés ( La fameuse date de péremption sur les boites de conserves )

    Pour remédier à cela il suffit juste de rajouter quelques règles pour notre beau serveur Nginx :
    [== NGINX ==]
    # https://www.theodo.fr/blog/2016/06/improve-the-performance-of-your-webapp-configure-nginx-to-cache/
    # http://www.supinfo.com/articles/single/2843-implementer-cache-navigateur-avec-nginx
    
    # cache-control
    location /data/ {
    	add_header Cache-Control public;
    	expires 12h;
    }
    location /core/ {
    	add_header Cache-Control public;
    	expires 12h;
    }
    location /plugins/ {
    	add_header Cache-Control public;
    	expires 12h;
    }
    location /themes/ {
    	add_header Cache-Control public;
    	expires 12h;
    }
    
    Les 2 commentaires ci-dessus renvoient des sites où j'ai pêché les infos.

    Les gains sont assez impressionnants.

    Il doit certainement exister un équivalent pour Apache2 mais il faut que j'aille lire le manuel.

    Je te laisse faire tes tests et mettre à jour le wiki.

    Note générale.
    On voit depuis quelques versions de PluXml que le numéro est ajouté aux liens vers les fichiers CSS et autres.
    Cela me semble inutiles car les fichiers sont signés avec leurs balises ETag. Donc s'il y a changement de versions, leurs balises Etags vont changer.
    Un peu de lecture:
    https://fr.wikipedia.org/wiki/Balise-entit%C3%A9_ETag_HTTP
  • Bonjour Bazooka,

    Pour apache l'équivalent est le module expire : https://httpd.apache.org/docs/2.4/fr/mod/mod_expires.html

    Comment vois-tu les gains ? Pour un asset donné, par exemple un script .js, je vois bien un temps d'attente même lorsque l'objet est en cache dans le navigateur. Je suppose que c'est de ce délai dont tu parles ?

    Ce que je ne comprends pas c'est que même en ajoutant un header expire j'ai tout de même ce délai qui apparaît pour cet asset. Qu'obtiens-tu de ton côté ?

    En revanche sous chrome un objet en cache = 0 secondes, je n'avais pas remarqué ce phénomène du coup.
  • bazooka07bazooka07 PluXml Lead Developer, Moderator
    août 2017 modifié
    Dans Firefox, l'inspecteur Web a un onglet pour le réseau avec les échanges entre le navigateur et le serveur.
    Attention quand on clique la 1ère fois, il faut recharger la page html pour que l'inspecteur Web étudie les échanges.
    Si le serveur envoie un code 304, cela veut dire que le fichier sur le serveur n'a pas chargé depuis le dernier téléchargement.
    Mais si le serveur envoie ce code 304, c'est qu'avant le navigateur a fait une requête au serveur pour savoir si le fichier a chargé.
    Et selon le trafic réseau, le serveur mettra un temps plus ou moins long pour répondre.

    Par contre si le code est 200, cela peut signifie 2 choses:
    Si le 1er téléchargement du fichier, le serveur envoie le code 200 avec le fichier. Mais il envoie la date du fichier et une signature Etag qui est calculé à partir du contenu du fichier.
    Et si le serveur est bien configuré, il envoie la date d'expiration du fichier, paramétrable sur le serveur, et le droit de mettre le fichier en cache.

    Quand on passe à une autre page et qui a besoin du même fichier (css ou js par exemple), si on a pas dépassé la date d'expiration, le navigateur va chercher le fichier dans son cache. Ce qui évite d'attendre la réponse du serveur pour savoir si le fichier a changé, plus le temps de transfert du fichier sur le réseau .
    Et l'onglet de l'inspecteur affiche "mise en cache".

    Attention que sur Chrome en mode développeur, il y a une case à cocher pour refuser l'utilisation du cache pour les fichiers.
Connectez-vous ou Inscrivez-vous pour répondre.