- Modifié
En ce moment je développe la nouvelle version de seedbox-manager (sbm)
J'ai eu des soucis avec la configuration, surtout pour faire fonctionner l'application dans une uri.
Donc à cette occasion je me suis littéralement plongé dans la doc nginx pour comprendre comment fonctionne réellement nginx. Et j'ai appris pas mal de chose notamment sur les bonnes pratiques.
Vous avez surement déjà vu cette erreur php-fpm dans vos logs nginx elle est relativement très répandue
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
Pour ma part elle a presque réussi à me rendre fou
Pour faire simple dans la plupart des cas c'est un mauvais chemin attribué à la variable SCRIPT_FILENAME
lorsque nginx essaye de résoudre l'uri. Nginx en fonction des location
dans le vhost server
détermine le chemin physique pour afficher le fichier.
Et là ça devient intéressant puisque les location
on peut les configurer de plein de manière différente.
Les location
nginx
Donc voici les types
server {
location = /coucou {
}
location /hello-world {
}
location ~ /rutorrent/(conf|share)$ {
alias /var/www/site/web;
}
location ~* /rutorrent/(conf|share)$ {
# config ...
}
location ^~ /salut {
}
}
Donc il y a 5 directives en tout, une vide et le reste =
~
~*
^~
Nginx commence par les directives =
s'il trouve rien il enchaine sur les directives vide ensuite ^~
ensuite ~
et ~*
Pour les directives =
match exactement /coucou
dans mon exemple. Ensuite il fait la routine que vous décidez dans location
Pour les directives vide comme celle-ci location /hello-world {}
nginx match toutes les uri qui commence par /hello-world
mais aussi /hello-world/jaime/ma/femme
Pour les directives ^~
elle empêche que d'autre location
match l'uri que vous allez configurer, de plus vous pouvez utiliser les expressions régulières PCRE
Exemple :
location /rutorrent {}
location ^~ ^/rutorrent/conf/(.+)$ {}
Dans cet exemple la location location /rutorrent
match aussi l'uri /rutorent/conf/blalbla
Et bien comme la location location ^~ ^/rutorrent/conf/(.+)$ {}
match aussi la première location va se faire sortir. Et donc la deuxième location est prioritaire en quelque sorte.
Pour les autres directives ~
~*
ça indique que l'on peut utiliser les expressions régulières PCRE.
A la différence de ^~
les autres location
peuvent match l'uri choisie.
~
sensible à la casse
~*
insensible à la casse
Pour les expressions régulières vous pouvez tester sur des sites comme celui-ci si votre regex est correct.
exemple : http://www.regexpal.com/97251
Primary script unknown et SCRIPT_FILENAME
Pour parler de cette erreur je suis d'abord obligé de faire une petite explication sur les directives root
et alias
Donc root
sert à déterminer dans quel dossier nginx va travailler.
Il est d'ailleurs déconseillé de mettre root
partout.
L'idéal est de mettre root
dans server
et d'éviter autant que possible d'en mettre dans les location
.
Ex :
server {
root /var/www;
index index.html index.php;
location /coucou {
# on évite les directives root ici.
}
location /hello/world {
alias /var/www/application/public;
}
}
Ici contenu de cette configuration lorsque la requête /coucou
est appelée, nginx va chercher soit :
- le fichier /var/www/coucou/index.html
- ou le fichier /var/www/coucou/index.php
- ou une erreur 404 si les deux fichiers n'existent pas.
Pour la requête /hello/world
c'est différent ici il y a une directive alias
C'est comme root à l'exception que nginx ne rajoute pas dans le chemin l'uri comme un dossier
Exemple avec comme root dans le vhost server
/var/www
- Sans rien et la requête /coucou nginx va résoudre comme ceci :
/var/www/coucou
- Avec
alias
et la requête /hello/world nginx va résoudre comme ceci :/var/www/application/public
Contenu de tout cela on peut maintenant regarder le problème avec php-fpm et SCRIPT_FILENAME
Pour cela j'ai une petite astuce pour debug que j'ai trouvé ici http://serverfault.com/a/754378
Ajouter ceci dans http {}
dans normalement dans le fichier nginx.conf
http {
log_format php '$document_root$fastcgi_script_name > $request';
}
et ajouter ceci dans le server
concerné par le souci
server {
access_log /var/log/nginx/php.log php;
}
on reload nginx
nginx -s reload
Maintenant il y a plus qu'à ajuster la configuration des location
de root
ou alias
en fonction des logs
Voilà avec cela vous avez quelques armes pour vous débrouiller sur votre prochaine config nginx