Structure des fichiers de configuration Nginx

11 min de lecture·Matthieu|

Un tour complet de l'organisation des fichiers de configuration Nginx sur le disque, de l'imbrication des contextes, du fonctionnement des directives include et de l'heritage des directives.

Structure des fichiers de configuration Nginx

Vous avez installe Nginx. Vous avez ouvert /etc/nginx/nginx.conf et vous avez trouve un fichier qui inclut d'autres fichiers, qui eux-memes en incluent d'autres. Certaines directives se trouvent entre des accolades, d'autres flottent au niveau racine. Avant de commencer a configurer des blocs server, du SSL ou des reverse proxies, il vous faut la carte.

Cet article vous donne cette carte. Pas de recettes. Juste le modele mental du fonctionnement de la configuration Nginx, pour que vous puissiez lire et modifier n'importe quelle config que vous rencontrez.

Ou sont stockes les fichiers de configuration Nginx ?

Sur Debian 12 et Ubuntu 24.04, le paquet apt installe tout sous /etc/nginx/. Voici a quoi ressemble ce repertoire sur une installation fraiche :

/etc/nginx/
├── nginx.conf              # Main config entry point
├── mime.types              # Maps file extensions to MIME types
├── conf.d/                 # Drop-in config files (*.conf auto-included)
├── sites-available/        # All virtual host config files
│   └── default             # Default server block
├── sites-enabled/          # Symlinks to active virtual hosts
│   └── default -> ../sites-available/default
├── snippets/               # Reusable config fragments
│   └── fastcgi-php.conf
├── modules-available/      # Available dynamic module configs
├── modules-enabled/        # Symlinks to loaded modules
├── fastcgi.conf            # FastCGI directive defaults
├── fastcgi_params          # FastCGI parameter mappings
├── proxy_params            # Proxy header defaults
├── scgi_params             # SCGI parameter mappings
├── uwsgi_params            # uWSGI parameter mappings
├── koi-utf                 # Character set mapping files
├── koi-win
└── win-utf

Vous pouvez verifier cela sur votre propre serveur :

ls -la /etc/nginx/

Le fichier que vous modifiez le plus souvent n'est pas nginx.conf lui-meme. C'est generalement un fichier dans sites-available/ ou conf.d/. Le fichier principal nginx.conf definit les parametres globaux et inclut ces fichiers via des directives include.

Comment les fichiers de configuration Nginx sont-ils organises ?

La configuration Nginx utilise un arbre de contextes (contexts) imbriques. Chaque contexte est une directive de bloc entre accolades. Les directives placees dans un contexte ne s'appliquent que dans cette portee.

La hierarchie ressemble a ceci :

main (top level, outside any braces)
├── events { }
└── http { }
    └── server { }
        └── location { }

Chaque directive de la configuration se trouve a l'un de ces niveaux. Le contexte main est le fichier lui-meme. Tout le reste s'imbrique a l'interieur.

Que controle le contexte main ?

Le contexte main represente tout ce qui se trouve en dehors de tout bloc de directives dans nginx.conf. Il controle les parametres au niveau du processus qui affectent l'ensemble de l'instance Nginx.

Directives principales a ce niveau :

Directive Fonction Valeur typique
user Utilisateur systeme sous lequel tournent les workers www-data
worker_processes Nombre de processus worker auto (correspond aux coeurs CPU)
pid Chemin vers le fichier PID /run/nginx.pid
error_log Chemin et niveau du log d'erreur global /var/log/nginx/error.log
include Charge les configs des modules /etc/nginx/modules-enabled/*.conf

Voici le contexte main du fichier nginx.conf par defaut sur Debian 12 :

user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

Ces cinq lignes s'executent avant tout le reste. Elles definissent l'utilisateur sous lequel Nginx tourne, le nombre de workers a lancer et l'emplacement des logs d'erreur.

Que contient le bloc events ?

Le bloc events configure la facon dont Nginx gere les connexions au niveau du systeme d'exploitation. Il se trouve a l'interieur du contexte main.

events {
    worker_connections 768;
    # multi_accept on;
}

worker_connections definit le nombre maximum de connexions simultanees par processus worker. Avec worker_processes auto sur une machine 4 coeurs, vous obtenez 4 x 768 = 3 072 connexions concurrentes. La valeur par defaut dans le code source de Nginx est 512, mais Debian la fixe a 768.

A quoi sert le contexte http ?

Le bloc http contient toute la configuration liee au traitement du trafic HTTP. Chaque bloc server se trouve a l'interieur. Les directives placees ici s'appliquent a tous les virtual hosts, sauf si un bloc server ou location les remplace.

http {
    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;
    server_tokens off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log /var/log/nginx/access.log;

    gzip on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Notez server_tokens off; vers le haut. Cela masque le numero de version de Nginx dans les en-tetes de reponse. La divulgation de la version aide les attaquants a cibler des failles connues. La config par defaut de Debian n'inclut pas cette ligne. Ajoutez-la.

Les deux lignes include en bas sont la facon dont Nginx charge vos configurations de sites. Nous verrons include en detail plus bas.

Comment fonctionnent les blocs server ?

Un bloc server definit un virtual host. Il se trouve a l'interieur du contexte http. Chaque bloc server ecoute sur une combinaison adresse/port et fait correspondre les requetes par l'en-tete Host.

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Quand une requete arrive, Nginx selectionne le bloc server en comparant server_name avec l'en-tete Host. Si aucun bloc ne correspond, Nginx utilise le default_server :

listen 80 default_server;

En general, vous creez un fichier par domaine dans sites-available/, chacun contenant un bloc server (ou deux, si vous avez a la fois HTTP et HTTPS).

Comment Nginx fait-il correspondre les blocs location ?

Un bloc location definit la facon dont Nginx traite les requetes pour des motifs d'URI specifiques. Il se trouve a l'interieur d'un bloc server (ou a l'interieur d'un autre location).

Nginx evalue les blocs location dans un ordre precis :

Modificateur Type Exemple Comportement
= Correspondance exacte location = / Correspond uniquement a /. Arrete la recherche immediatement.
^~ Prefixe prioritaire location ^~ /images/ Correspond au prefixe. Ignore les expressions regulieres.
~ Regex (sensible a la casse) location ~ \.php$ La premiere regex correspondante gagne.
~* Regex (insensible a la casse) location ~* \.(jpg|png)$ La premiere regex correspondante gagne.
(aucun) Prefixe location /api/ Le prefixe le plus long gagne, mais une regex peut le supplanter.

L'algorithme de correspondance :

  1. Nginx verifie tous les prefixes de location et memorise le plus long.
  2. Si cette correspondance utilise = ou ^~, stop. Elle est utilisee.
  3. Sinon, Nginx verifie les locations regex dans l'ordre ou elles apparaissent dans le fichier de config.
  4. La premiere regex correspondante gagne. Si aucune regex ne correspond, le prefixe le plus long de l'etape 1 est utilise.

Cela signifie que l'ordre des locations par prefixe dans votre fichier de config n'a pas d'importance. Mais l'ordre des regex, si.

Comment fonctionne la directive include ?

La directive include insere le contenu d'un autre fichier (ou des fichiers correspondant a un motif glob) a la position actuelle dans la config. Nginx la resout au chargement de la config, avant que celle-ci ne soit analysee dans son ensemble.

include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

Le glob *.conf correspond a tous les fichiers se terminant par .conf dans ce repertoire. Le glob * correspond a tout. Les deux motifs sont courants.

La directive include fonctionne dans n'importe quel contexte. Vous pouvez l'utiliser dans les blocs http, server ou location :

server {
    listen 443 ssl;
    include snippets/ssl-params.conf;
}

C'est ainsi que fonctionne le repertoire snippets/. Vous ecrivez un fragment reutilisable une seule fois et vous l'incluez ou vous en avez besoin.

Un point a surveiller : Nginx refuse de demarrer si un include sans glob ne correspond a aucun fichier. Si vous ecrivez include /etc/nginx/conf.d/*.conf; et que le repertoire est vide, Nginx demarre sans probleme (les globs peuvent ne rien correspondre). Mais include /etc/nginx/ssl.conf; echouera si ce fichier n'existe pas.

Quelle est la difference entre sites-available, sites-enabled et conf.d ?

Ces trois repertoires servent des objectifs differents. Debian et Ubuntu utilisent les trois.

Repertoire Fonction Comment Nginx le lit Quand l'utiliser
sites-available/ Stocke toutes les configs de virtual hosts Pas lu directement Toujours. Un fichier par domaine.
sites-enabled/ Contient des liens symboliques vers les configs actives Inclus via include /etc/nginx/sites-enabled/*; Creez un lien symbolique ici pour activer un site.
conf.d/ Fragments de config a chargement automatique Inclus via include /etc/nginx/conf.d/*.conf; Parametres http globaux, blocs upstream, maps.

Le modele sites-available / sites-enabled permet de desactiver un site sans supprimer sa configuration. Pour activer un site :

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Pour le desactiver :

rm /etc/nginx/sites-enabled/example.com

Puis rechargez :

sudo nginx -t && sudo systemctl reload nginx

Lancez toujours nginx -t avant de recharger. Cette commande valide la config sans affecter le trafic en cours.

Le repertoire conf.d/ est plus simple. Chaque fichier .conf qu'il contient est automatiquement charge. Pas de liens symboliques. Certains administrateurs preferent conf.d/ pour sa simplicite et n'utilisent pas du tout sites-available/sites-enabled. Les deux approches fonctionnent. Choisissez-en une et restez coherent.

Un piege : si vous utilisez a la fois conf.d/ et sites-enabled/, assurez-vous de ne pas definir de blocs server en conflit dans les deux endroits. Nginx chargera les deux, et le resultat depend des regles de fusion des directives et de la correspondance server_name.

Comment fonctionne l'heritage des directives Nginx ?

Nginx transmet les directives des contextes parents vers les contextes enfants. C'est la partie que la plupart des gens comprennent mal, et la source de bugs subtils en production.

Il existe trois types de directives, et chacun herite differemment.

Directives normales

Les directives normales contiennent une seule valeur. Si un contexte enfant definit la meme directive, il remplace entierement la valeur du parent. Si l'enfant ne la definit pas, la valeur du parent est heritee.

Exemple : root est une directive normale.

http {
    root /var/www/default;

    server {
        server_name example.com;
        # root is inherited: /var/www/default

        location /app {
            root /var/www/app;
            # root is overridden: /var/www/app
        }

        location /blog {
            # root is inherited: /var/www/default
        }
    }
}

Autres directives normales : index, access_log (quand utilise une seule fois), error_log, client_max_body_size.

Directives de type tableau

Les directives de type tableau (array directives) peuvent apparaitre plusieurs fois dans un meme contexte pour accumuler des valeurs. Mais quand un contexte enfant en definit ne serait-ce qu'une seule instance, il remplace toutes les valeurs du parent. Il ne les fusionne pas. Il les remplace.

add_header est la directive de type tableau la plus courante. Ce comportement cause un bug bien connu en production.

Que se passe-t-il quand vous ajoutez des en-tetes dans les blocs http et location ?

Si vous definissez add_header dans le contexte http puis un autre add_header dans un bloc location, le bloc location efface tous les en-tetes du contexte http. Pas seulement celui que vous remplacez. Tous.

http {
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    server {
        server_name example.com;

        location /api/ {
            add_header X-Custom "api-response";
            # X-Frame-Options is GONE
            # X-Content-Type-Options is GONE
            # Only X-Custom is sent
        }
    }
}

Pour verifier que cela se produit sur votre serveur :

curl -I https://example.com/api/

Verifiez les en-tetes de reponse. Si vos en-tetes de securite sont absents des reponses /api/ mais presents sur les autres chemins, c'est la raison.

La solution : repeter tous les en-tetes dans le contexte enfant.

location /api/ {
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-Custom "api-response";
}

Ou utiliser un snippet :

# /etc/nginx/snippets/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=63072000" always;
location /api/ {
    include snippets/security-headers.conf;
    add_header X-Custom "api-response";
}

Note : Nginx 1.29.3+ a introduit add_header_inherit merge; qui change ce comportement. Avec merge, les contextes enfants ajoutent aux en-tetes du parent au lieu de les remplacer. Si vous utilisez Nginx 1.28.x (la version stable actuelle en mars 2026), vous n'avez pas encore cette fonctionnalite.

Le meme comportement d'effacement s'applique a proxy_set_header. Si vous definissez un proxy_set_header dans un bloc location, toutes les directives proxy_set_header du contexte server ou http sont perdues. La documentation officielle le dit explicitement : « These directives are inherited from the previous configuration level if and only if there are no proxy_set_header directives defined on the current level. »

server {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location /api/ {
        proxy_set_header X-Request-ID $request_id;
        # Host, X-Real-IP, X-Forwarded-For are all GONE
        proxy_pass http://backend;
    }
}

Corrigez de la meme facon : repetez tous les en-tetes dans le bloc location, ou utilisez un snippet include.

Directives d'action

Les directives d'action comme rewrite et return ne sont pas heritees dans les contextes imbriques. Elles s'executent uniquement dans le contexte ou elles sont definies.

server {
    rewrite ^/old/(.*)$ /new/$1 permanent;

    location /app {
        # The rewrite above does NOT apply here
        # Requests matching /app are handled by this location
    }
}

La directive try_files presente un piege lie a ce fonctionnement. Quand elle est placee dans le contexte server, Nginx cree une pseudo-location implicite avec la priorite la plus basse. Si un bloc location classique correspond a la requete, le try_files au niveau du serveur ne s'execute jamais :

server {
    try_files $uri /index.php;   # Never runs for /app/* requests
    location /app { }            # This catches them first
}

Placez toujours try_files a l'interieur d'un bloc location specifique.

Comment inspecter la configuration effective de Nginx ?

Deux commandes vous aident a comprendre ce que Nginx voit reellement apres avoir resolu toutes les directives include.

Tester la config pour les erreurs de syntaxe :

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Lancez toujours cette commande avant de recharger. Si le test echoue, Nginx vous indique le fichier et le numero de ligne.

Afficher la configuration complete fusionnee :

sudo nginx -T

Cette commande affiche la configuration effective complete avec tous les includes resolus et inseres en ligne. Envoyez la sortie vers less pour une meilleure lisibilite :

sudo nginx -T | less

Ou recherchez une directive specifique :

sudo nginx -T | grep -n "add_header"

Cela affiche chaque directive add_header dans tous les fichiers inclus, avec les numeros de ligne dans la sortie fusionnee. Utilisez ceci pour deboguer les problemes d'heritage. Si un en-tete apparait dans le bloc http mais pas dans un bloc location, et que vous ne voyez aucun add_header dans cette location, l'en-tete est herite. Si vous voyez un add_header different dans la location, tous les en-tetes du parent sont effaces.

Utilisez nginx -T chaque fois que les modifications de config ne se comportent pas comme prevu.

Reference rapide : la vue d'ensemble

/etc/nginx/nginx.conf
│
├─ main context (process-level: user, worker_processes, pid)
│
├─ events { }  (connection handling: worker_connections)
│
└─ http { }    (all HTTP config)
   │
   ├─ include conf.d/*.conf      (global HTTP settings, upstreams, maps)
   ├─ include sites-enabled/*    (virtual host configs)
   │
   └─ server { }                 (one per domain/port)
      │
      ├─ listen, server_name     (routing)
      ├─ root, index             (defaults for this host)
      │
      └─ location { }           (URI pattern matching)
         ├─ try_files, root      (per-path behavior)
         └─ proxy_pass           (reverse proxy target)

Inheritance: parent -> child (down only)
Normal directives: child overrides parent
Array directives: child REPLACES ALL parent values
Action directives: no inheritance

Copyright 2026 Virtua.Cloud. Tous droits reserves. Ce contenu est une creation originale de l'equipe Virtua.Cloud. Toute reproduction, republication ou redistribution sans autorisation ecrite est interdite.

Prêt à essayer ?

Déployez votre serveur en quelques secondes. Linux, Windows ou FreeBSD.

Voir les offres VPS