La gestion des blocs location dans Nginx devient vraiment intéressante dès qu’on mélange préfixes, expressions régulières et règles de priorité. Ce guide explique la logique derrière nginx location regex, montre quand une regex est utile, et surtout comment écrire des règles lisibles qui tiennent debout en production. Je vais aussi pointer les pièges que je vois le plus souvent en contexte DevOps, parce que c’est souvent là que les mauvaises surprises commencent.
Les points à garder en tête avant de jouer avec les `location` regex
- Nginx compare d’abord les préfixes, puis teste les regex dans l’ordre du fichier.
- Le modificateur
^~empêche Nginx d’aller chercher une regex plus loin. -
=force une correspondance exacte et s’arrête immédiatement. -
~est sensible à la casse,~*ne l’est pas. - Une regex de location ne voit que l’URI, pas la chaîne de requête après
?. - Si un simple préfixe suffit, je le préfère presque toujours à une regex.
Comment Nginx arbitre entre préfixes et regex
Le point le plus important, c’est que Nginx ne choisit pas un location au hasard. Il commence par les correspondances exactes et les préfixes, garde le préfixe le plus long, puis teste ensuite les expressions régulières dans l’ordre où elles apparaissent dans la configuration. Si un bloc porte le modificateur ^~, Nginx s’arrête sur ce préfixe et ne consulte plus les regex. Avec =, la recherche s’arrête encore plus tôt, dès qu’une correspondance exacte est trouvée.
| Type de location | Modificateur | Usage typique | Comportement |
|---|---|---|---|
| Exact | = |
Healthcheck, page précise, redirection ciblée | Correspondance unique, arrêt immédiat |
| Préfixe | Aucun | Arborescence simple comme /api/ ou /assets/
|
Le plus long préfixe gagne |
| Préfixe protégé | ^~ |
Zone qu’aucune regex ne doit surcharger | Ignore les regex |
| Regex sensible à la casse | ~ |
Motifs précis, routes structurées | Premier match regex gagne |
| Regex insensible à la casse | ~* |
Extensions de fichiers, chemins aux majuscules variables | Premier match regex gagne |
Un détail que beaucoup oublient au début: Nginx compare l’URI demandée, pas les paramètres de requête. Autrement dit, /blog/article?page=2 et /blog/article?page=9 suivent la même logique de matching. Une fois cette mécanique en tête, on comprend vite pourquoi les regex sont utiles seulement quand elles apportent une vraie valeur de routage, pas juste parce qu’elles semblent plus puissantes.
Quand une regex de location vaut vraiment le coup
Je réserve les regex de location aux cas où le chemin contient une structure que le préfixe ne sait pas exprimer proprement. C’est le cas pour des extensions de fichiers, des URLs versionnées, des slugs de contenu, ou des routes où une partie du chemin doit être capturée et réutilisée. Dès que le motif reste simple et stable, un préfixe ou une correspondance exacte est plus lisible, plus facile à relire en équipe et moins fragile lors des changements.
| Situation | Approche que je choisis | Pourquoi |
|---|---|---|
/healthz, /login, /robots.txt
|
= |
Chemin unique, lecture immédiate |
/api/, /static/, /images/
|
Préfixe | Simple, rapide, facile à maintenir |
/docs/2026/06/article-slug |
Regex | Structure du chemin utile pour router ou capturer des variables |
Extensions multiples comme .jpg, .png, .webp
|
Regex | Une seule règle couvre plusieurs variantes |
| Route protégée qui ne doit jamais être remplacée |
^~ sur un préfixe |
Empêche une regex plus générale de passer devant |
Mon critère est simple: si la regex remplace trois ou quatre préfixes presque identiques, elle a du sens. Si elle commence à décrire toute la logique métier d’un site, je considère qu’elle a dépassé son rôle. À ce moment-là, je préfère souvent déplacer une partie de la décision dans l’application ou dans un map, plutôt que de transformer Nginx en moteur de routage improvisé.
Écrire des règles regex propres et sûres
Une bonne regex de location n’est pas celle qui “matche tout”, c’est celle qui matche exactement ce qu’on attend. En pratique, je pars presque toujours d’un motif ancré avec ^ au début et $ à la fin, j’échappe les points dans les extensions, et je choisis consciemment entre ~ et ~*. Le but n’est pas d’être élégant au sens théorique, mais d’éviter les correspondances accidentelles qui ne se voient qu’en production.
~ ou ~*
~ est sensible à la casse. Je l’utilise quand je veux contrôler précisément les chemins, par exemple sur des routes d’API ou des slugs. ~* ignore la casse, ce qui peut être pratique pour des extensions de fichiers ou des URLs héritées dont la casse n’est pas fiable. En revanche, je ne le choisis pas par réflexe: plus on autorise de variantes, plus on augmente la surface de matching.
location ~ ^/blog/[0-9]{4}/[0-9]{2}/[a-z0-9-]+/?$ {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|jpeg|png|webp|svg)$ {
expires 30d;
}Captures et variables
Les captures sont très utiles quand la structure de l’URL transporte une information métier. On peut récupérer un slug, une version d’API ou un identifiant numérique, puis réutiliser ces valeurs dans un return, un rewrite ou un en-tête. Je trouve les captures nommées plus lisibles dès que la règle dépasse deux groupes, parce qu’elles réduisent le risque de se tromper entre $1, $2 et $3.
location ~ ^/api/v(?[0-9]+)/users/(?[0-9]+)$ {
proxy_pass http://backend;
add_header X-Api-Version $version;
add_header X-User-Id $id;
} Un point technique important ici: quand un location est défini par une regex, proxy_pass doit être écrit sans URI supplémentaire. C’est le genre de détail qui semble anodin jusqu’au jour où une réécriture ou un chemin partiellement remplacé produit un comportement incohérent. Cette petite discipline évite beaucoup de débogage inutile.

Des exemples concrets qui tiennent la route en production
Quand je dois expliquer ce sujet à une équipe, je pars rarement de la théorie pure. Les exemples parlent beaucoup mieux, surtout quand ils montrent pourquoi une règle existe et ce qu’elle protège vraiment. Voici les cas que je vois le plus souvent dans des configurations DevOps sérieuses.
Servir des assets sans se battre avec les regex
Si votre application expose une zone statique claire, je privilégie d’abord le préfixe. Le rôle de la regex devient alors secondaire, par exemple pour attraper des extensions dispersées dans plusieurs répertoires, mais pas pour remplacer une structure simple déjà connue.
location ^~ /assets/ {
root /var/www/site;
access_log off;
expires 30d;
}
location ~* \.(css|js|png|jpg|jpeg|webp|svg)$ {
access_log off;
expires 30d;
}Ici, ^~ protège la zone /assets/ contre des regex plus générales. C’est utile quand je veux que les assets statiques suivent une règle stable, sans dépendre de l’ordre de blocs plus globaux.
Router une API versionnée
Les APIs versionnées sont un bon terrain pour les regex, parce qu’une partie du chemin change de façon structurée. Une capture permet de conserver la version dans les logs, dans un header ou dans une logique de proxy sans dupliquer plusieurs blocs quasi identiques.
location ~ ^/api/v[0-9]+/users/[0-9]+$ {
proxy_pass http://users-api;
}Ce motif est volontairement strict. Je préfère rater une URL invalide plutôt que de laisser passer des variantes ambiguës. C’est une logique saine en production: mieux vaut une règle étroite qu’une regex permissive qui masque un bug applicatif.
Lire aussi : Commentaires .env - Évitez les pièges et optimisez vos fichiers
Rediriger une arborescence documentaire
Pour une migration de contenu ou une refonte d’URL, les regex simplifient beaucoup de redirections. On capte une partie du chemin, puis on la réécrit proprement vers une nouvelle structure. Ici, la regex sert surtout à préserver l’intention de navigation sans multiplier les règles manuelles.
location ~ ^/docs/(.+)/?$ {
return 301 /documentation/$1;
}Ce type de règle me plaît parce qu’il garde la migration lisible: l’ancien chemin reste reconnaissable, et le nouveau format est centralisé dans un seul bloc. En revanche, si la réécriture devient trop complexe, je préfère arrêter le bricolage et gérer la transformation plus haut dans la pile.
Les pièges qui changent le résultat sans prévenir
Les erreurs les plus coûteuses avec les regex de location ne sont pas toujours des erreurs de syntaxe. Ce sont souvent des erreurs de compréhension: ordre des blocs, faux positif sur la casse, ou croyance qu’une query string participe au matching. Je les résume souvent dans un tableau, parce qu’on les corrige plus vite quand l’effet et la cause sont visibles d’un coup.
| Piège | Ce qui se passe | Correction pragmatique |
|---|---|---|
| Regex trop large placée avant une regex précise | La première capture le trafic avant la seconde | Classer du plus spécifique au plus général |
| Oublier que la query string n’entre pas dans le matching |
?page=2 ne change rien au choix du location
|
Tester uniquement l’URI |
| Utiliser un point non échappé | La regex matche trop large | Écrire \. pour les extensions |
Mettre proxy_pass avec une URI dans une location regex |
Le comportement devient difficile à prévoir | Garder proxy_pass http://backend;
|
Choisir ~* sans raison |
On accepte des variantes de casse inutiles | Utiliser ~ si la casse doit rester stricte |
Ne pas protéger un préfixe critique avec ^~
|
Une regex générale peut le surcharger | Marquer le chemin sensible comme prioritaire |
Quand j’audite une configuration, ce sont ces détails que je cherche d’abord. Je ne commence pas par vérifier si la regex est “jolie”; je vérifie si elle prend la bonne décision dans le bon ordre. C’est beaucoup plus utile, et beaucoup plus proche de la réalité d’un incident.
Ce que je vérifie avant de livrer une configuration Nginx
Dans un contexte DevOps, la meilleure règle est souvent celle qu’on peut tester vite, relire vite et expliquer vite. Avant de pousser une configuration, je valide toujours la syntaxe avec nginx -t, j’inspecte la configuration effective avec nginx -T quand nécessaire, puis je teste quelques chemins concrets avec curl. Ce trio réduit énormément le risque de découvrir un mauvais matching au moment où le trafic réel arrive.
Je garde aussi un principe simple: plus la configuration comporte de regex, plus je deviens conservateur. Je préfère déplacer la complexité vers un préfixe, une règle exacte ou une logique applicative dès que la lisibilité commence à s’effriter. Une bonne configuration Nginx ne cherche pas à impressionner; elle cherche à faire exactement ce qu’on attend, sans ambiguïté, et sans surprise au prochain déploiement.