Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Nginx Default Configuration Structure and Logging Formats

Tech 2

Nginx loads its primary configuration from /etc/nginx/nginx.conf. Near the end of that file, an include directive pulls in additional files, commonly /etc/nginx/conf.d/*.conf, which is where most virtual hosts are defined.

List default fragments under conf.d:

  • ls -l /etc/nginx/conf.d/

Core structure of nginx.conf

  • Global (main) context

    • user: OS account used by the master/worker processses
    • worker_processes: number of workers (auto is typical)
    • error_log: global error log path and level
    • pid: location of the master PID file
    • worker_rlimit_nofile: upper bound on open FDs per worker
  • events context

    • use: event loop mechanism (epoll on modern Linux, kqueue on BSD/macOS)
    • worker_connections: max connections per worker
    • multi_accept: whether a worker accepts as many queued connections as possible
  • http context

    • MIME types and default_type
    • log_format definitions and access_log targets
    • I/O tuning (sendfile, tcp_nopush, tcp_nodelay)
    • keepalive_timeout and gzip settings
    • include of virtual host files (e.g., conf.d/*.conf)

Example nginx.conf (concise and production-safe)

# ===== main (global) =====
user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log  warn;
pid        /run/nginx.pid;
worker_rlimit_nofile  65535;

# ===== events =====
events {
  use                epoll;          # kqueue on *BSD/macOS
  worker_connections 8192;           # per worker
  multi_accept       on;
}

# ===== http =====
http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  # Extended access log with upstream timing and status
  log_format main_ext
    '$remote_addr - $remote_user [$time_local] ' 
    '"$request" $status $body_bytes_sent ' 
    '"$http_referer" "$http_user_agent" ' 
    '$request_time $upstream_addr $upstream_status';

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

  sendfile        on;
  tcp_nopush      on;
  tcp_nodelay     on;
  keepalive_timeout  65s;

  gzip on;
  gzip_comp_level 2;
  gzip_min_length 1k;
  gzip_types text/plain text/css application/json application/javascript application/xml;

  include /etc/nginx/conf.d/*.conf;
}

Load balancing pool (define upstream backends in any http context, commonly in a file under conf.d):

upstream backend_pool {
  # 192.0.2.0/24 is TEST-NET-1; replace with real backends
  server 192.0.2.11:80 weight=3 max_fails=2 fail_timeout=30s;
  server 192.0.2.12:80 weight=2;
  server 192.0.2.13:80 backup;  # only used when primaries fail or are overloaded
}

Example virtual host (/etc/nginx/conf.d/default.conf)

server {
  listen 80;
  server_name  example.com  www.example.com;
  root  /var/www/example;
  index index.html index.htm;

  # Reverse proxy to load-balanced backends
  location / {
    proxy_pass http://backend_pool;

    # Preserve client/proto info
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # Timeouts
    proxy_connect_timeout 30s;
    proxy_send_timeout    60s;
    proxy_read_timeout    60s;

    # Buffering
    proxy_buffering          on;
    proxy_buffer_size        8k;
    proxy_buffers            8 16k;
    proxy_busy_buffers_size  32k;
    proxy_temp_file_write_size 64k;

    # Bodies
    client_max_body_size     10m;
    client_body_buffer_size  128k;

    # Let nginx serve custom error pages instead of relaying upstream errors directly
    proxy_intercept_errors on;
  }

  # PHP via FastCGI (if PHP-FPM is present)
  location ~ \.ph(p|p5)$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }

  # Static asset caching
  location ~* \.(?:jpg|jpeg|png|gif|bmp|svg|webp|ico)$ {
    expires 10d;
    access_log off;
  }
  location ~* \.(?:css|js)$ {
    expires 1h;
    access_log off;
  }

  # Lightweight status (limit visibility appropriately)
  location /nginx_status {
    stub_status;
    allow 127.0.0.1;
    deny all;
  }
}

Directive highlights and tuning notes

  • worker_processes: Use auto to match CPU cores unless constrained by memory/FD limits.
  • worker_rlimit_nofile: Typically matches ulimit -n; ensure it’s high enough for expected concurrency.
  • worker_connections: Effective connection ceiling ≈ worker_processes × worker_connections.
  • use epoll: Highest-throughput choice for modern Linux; kqueue for BSD/macOS.
  • sendfile/tcp_nopush/tcp_nodelay: Optimize file transfer and packetization; keep tcp_nopush on with sendfile.
  • keepalive_timeout: 60–75s is a common balance of reuse vs. resource retention.
  • gzip: Compress text-like payloads; avoid images and already-compressed formats.

Logging fundamentals

  • error_log

    • Captures Nginx runtime issues and upstream/proxy errors.
    • Levels: debug, info, notice, warn, error, crit, alert, emerg.
    • Example: error_log /var/log/nginx/error.log warn;
  • access_log

    • Records each HTTP request and response according to a chosen log_format.
    • You can define multiple log_format entries and assign different ones per server/location.

log_format syntax

  • log_format name [escape=default|json] string ...;
  • Defined inside http { } and referenced by access_log path name;

JSON-friendly logging example

http {
  # ...
  log_format api_json escape=json '{"ts":"$time_iso8601","ip":"$remote_addr",'
                                  '"method":"$request_method","uri":"$request_uri",'
                                  '"status":$status,"bytes":$body_bytes_sent,"
                                  'ref":"$http_referer","ua":"$http_user_agent",'
                                  '"xff":"$http_x_forwarded_for","rt":$request_time}';
  access_log /var/log/nginx/api.log api_json;
  # ...
}

Common variables used in log_format

  • $remote_addr: client IP address
  • $remote_user: authenticated username (empty if not used)
  • $time_local / $time_iso8601: server timestamp
  • $request: full request line (method, URI, protocol)
  • $request_method: HTTP method
  • $request_uri: URI with args
  • $status: response status code
  • $body_bytes_sent: body bytes sent to client (no headers)
  • $bytes_sent: total bytes sent including headers
  • $http_referer: referring page
  • $http_user_agent: user agent string
  • $http_X: any inbound HTTP header accessible as $http_
  • $upstream_addr / $upstream_status / $upstream_response_time: upstream details for proxied requests
  • $request_time: total time to serve request
  • $arg_name: query parameter named name, for example $arg_token

Validating and reloading configuration

  • Syntax check: nginx -t -c /etc/nginx/nginx.conf
  • Reload without downtime: nginx -s reload -c /etc/nginx/nginx.conf

Inspecting an HTTP exchange from the client side

  • Use curl to print request/response metadata: curl -v https://example.com/ > /dev/null
    • Lines beginning with > show the request; lines with < show the response

Static and dynamic separation pattern (illustrative)

# Dynamic requests to an app server; static assets served by nginx
location ~ \.(?:jsp|jspx|do)$ {
  proxy_set_header Host              $host;
  proxy_set_header X-Real-IP         $remote_addr;
  proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_pass http://127.0.0.1:8080;
}

location ~* \.(?:htm|html|gif|jpg|jpeg|png|bmp|swf|ico|rar|zip|txt|flv|pdf|xls|doc|ppt|mp3|wma)$ {
  expires 15d;
}

location ~* \.(?:js|css)$ {
  expires 1h;
}

Discovering included configuration files at runtime

  • The default http block usually ends with: include /etc/nginx/conf.d/*.conf;
  • Enumerate included files with: ls /etc/nginx/conf.d/

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.