Web
Difficulty: Intermediate
6 min read

Installing and Configuring NGINX on Linux

Learn how to install and configure NGINX, the high-performance web server used by the largest websites in the world.

Back to tutorials
About NGINX
NGINX is a high-performance web server, a reverse proxy and a cache server. It is known for its stability, its low resource usage and its ability to handle many concurrent connections.

Prerequisites

  • System: Ubuntu 18.04+ or Debian 9+ (adaptable to CentOS/RHEL)
  • Privileges: Root or sudo access
  • Resources: Minimum 1GB RAM, 10GB of disk space
  • Network: Ports 80 and 443 available

Installing NGINX

Method 1: Installation from the official repositories

The simplest method to install NGINX:

# Update the packages
sudo apt update

# Install NGINX
sudo apt install nginx -y

# Verify the installation
nginx -v
sudo systemctl status nginx

Method 2: Installation from the official NGINX repository

To get the latest stable version directly from NGINX:

# Install the dependencies
sudo apt install curl gnupg2 ca-certificates lsb-release -y

# Add the official GPG key
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

# Add the official repository
echo "deb http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

# Installation
sudo apt update
sudo apt install nginx -y

Starting and enabling

# Start NGINX
sudo systemctl start nginx

# Enable at boot
sudo systemctl enable nginx

# Check the status
sudo systemctl status nginx
Installation test
Open your browser and go to http://your-ip. You should see the default NGINX welcome page.

NGINX file structure

Important directories

  • /etc/nginx/: Main configuration
  • /etc/nginx/sites-available/: Available sites
  • /etc/nginx/sites-enabled/: Enabled sites
  • /var/www/html/: Default web content
  • /var/log/nginx/: Access and error logs

Main configuration files

# Main configuration
/etc/nginx/nginx.conf

# Default site configuration
/etc/nginx/sites-available/default

# Check the configuration syntax
sudo nginx -t

# Reload the configuration
sudo systemctl reload nginx

Basic configuration

Optimized global configuration

Edit the main file /etc/nginx/nginx.conf:

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

events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

http {
    # MIME types and charset
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    charset utf-8;

    # Performance optimizations
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 100M;

    # Security
    server_tokens off;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    # Compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml
        image/svg+xml;

    # Logs
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;
    error_log /var/log/nginx/error.log warn;

    # Include the site configurations
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Configuration of a simple website

Create a new site in /etc/nginx/sites-available/mysite:

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;
    root /var/www/mysite;
    index index.html index.htm index.php;

    # Site-specific logs
    access_log /var/log/nginx/mysite_access.log;
    error_log /var/log/nginx/mysite_error.log;

    # Handling static files
    location / {
        try_files $uri $uri/ =404;
    }

    # Cache for static resources
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Security - blocking sensitive files
    location ~ /\. {
        deny all;
    }

    location ~ ~$ {
        deny all;
    }
}

Enabling the site

# Create the site directory
sudo mkdir -p /var/www/mysite

# Create a welcome page
echo "

Welcome to my NGINX site

" | sudo tee /var/www/mysite/index.html # Enable the site sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/ # Disable the default site (optional) sudo rm /etc/nginx/sites-enabled/default # Test and reload sudo nginx -t sudo systemctl reload nginx

SSL configuration with Let's Encrypt

Installing Certbot

# Install Certbot
sudo apt install certbot python3-certbot-nginx -y

# Obtain an SSL certificate
sudo certbot --nginx -d example.com -d www.example.com

# Test the automatic renewal
sudo certbot renew --dry-run

Manual SSL configuration

Example configuration with SSL:

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com www.example.com;
    root /var/www/mysite;
    index index.html index.htm;

    # SSL certificates
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Secure SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # Security headers
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

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

Reverse Proxy configuration

Proxy to a Node.js application

upstream nodejs_backend {
    server 127.0.0.1:3000;
    keepalive 32;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://nodejs_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_cache_bypass $http_upgrade;
    }
}

Load Balancing

upstream backend_servers {
    least_conn;
    server 192.168.1.10:80 weight=3;
    server 192.168.1.11:80 weight=2;
    server 192.168.1.12:80 backup;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Health check
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
    }
}

Advanced optimizations

Cache and performance

# Cache configuration
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    listen 80;
    server_name cache.example.com;

    location / {
        proxy_cache my_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_lock on;

        proxy_pass http://backend;
        add_header X-Cache-Status $upstream_cache_status;
    }
}

Request rate limiting

http {
    # Limiting zone
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/m;
    limit_req_zone $binary_remote_addr zone=login:10m rate=1r/m;

    server {
        listen 80;
        server_name api.example.com;

        location /api/ {
            limit_req zone=api burst=20 nodelay;
            proxy_pass http://backend;
        }

        location /login {
            limit_req zone=login burst=5;
            proxy_pass http://backend;
        }
    }
}

Monitoring and maintenance

Monitoring with stub_status

server {
    listen 80;
    server_name localhost;

    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        allow 192.168.1.0/24;
        deny all;
    }
}

Log rotation

# logrotate configuration for NGINX
sudo tee /etc/logrotate.d/nginx > /dev/null <

Useful commands

# Test the configuration
sudo nginx -t

# Reload the configuration
sudo systemctl reload nginx

# Restart NGINX
sudo systemctl restart nginx

# View the logs in real time
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# Connection statistics
sudo netstat -tulpn | grep nginx

# NGINX processes
ps aux | grep nginx
Important security
Do not forget to configure a firewall (UFW, iptables) to protect your server and to keep NGINX updated regularly.

Common troubleshooting

Frequent issues

  • Port already in use: Check with sudo netstat -tulpn | grep :80
  • Permissions: Make sure www-data can read the files
  • Invalid configuration: Use nginx -t to diagnose
  • SSL: Check the certificate paths and the permissions

Diagnostic commands

# Check the syntax
sudo nginx -t

# Debug mode
sudo nginx -t -c /etc/nginx/nginx.conf

# Test a specific configuration
sudo nginx -t -c /etc/nginx/sites-available/mysite

# View the compiled configuration
nginx -T

Conclusion

NGINX is now installed and configured on your system. You have mastered:

  • The installation and basic configuration of NGINX
  • Creating and managing virtual sites
  • SSL configuration with Let's Encrypt
  • Usage as a reverse proxy and load balancer
  • Performance and security optimizations
  • Monitoring and maintenance

NGINX is an extremely powerful and flexible web server, capable of handling heavy loads while maintaining excellent performance. Its modular configuration allows it to be adapted to all types of needs, from a simple static site to complex microservices architectures.

Written by

Morgann Riu

Cybersecurity and Linux administration expert. I share my knowledge through free tutorials and training to help system administrators and developers secure their infrastructures.

Share this tutorial

Did you enjoy this article?

Comments

Checklist Sécurité Linux

30 points essentiels pour sécuriser un serveur Linux. Recevez aussi les nouveaux tutoriels par email.

Pas de spam. Désabonnement en 1 clic.