VPS & DedicatedLinux

Nginx configuration

Host a PHP website or proxy an application behind Nginx with a free SSL certificate.

This guide sets up Nginx for a website or as a proxy to an app, and puts it online with a free SSL certificate from Let's Encrypt.

  1. Install Nginx and Certbot

    bash
    apt update && apt upgrade -y && apt install -y nginx certbot
  2. Create a new Nginx configuration

    bash
    nano /etc/nginx/sites-available/<configname>.conf

    Replace <configname> with the name of your site, or any name you like.

  3. Paste the configuration you need

    Pick the configuration you need below and paste it into the editor (right-click in the terminal).

    nginx-php-web.conf
    nginx
    server_tokens off;
     
    server {
        listen 80;
        listen [::]:80;
        server_name exemplu.dns;
        return 301 https://$server_name$request_uri;
    }
     
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name exemplu.dns;
     
        root /var/www/path_site;
        index index.php;
     
        # allow larger file uploads and longer script runtimes
        client_max_body_size 100m;
        client_body_timeout 120s;
     
        sendfile off;
     
        # SSL configuration - replace exemplu.dns with your domain
        ssl_certificate /etc/letsencrypt/live/exemplu.dns/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/exemplu.dns/privkey.pem;
        ssl_session_cache shared:SSL:10m;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
        ssl_prefer_server_ciphers on;
     
        # See https://hstspreload.org/ before uncommenting the line below.
        # add_header Strict-Transport-Security "max-age=15768000; preload;";
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header Content-Security-Policy "frame-ancestors 'self'";
        add_header X-Frame-Options DENY;
        add_header Referrer-Policy same-origin;
     
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
     
        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Change to the PHP version you have installed (e.g. 7.4, 8.0, 8.1, 8.2, 8.3)
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param PHP_VALUE "upload_max_filesize=256M \n post_max_size=40M"; # Maximum size of an uploaded file (upload_max_filesize) and of a webserver request (post_max_size)
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param HTTP_PROXY "";
            fastcgi_intercept_errors off;
            fastcgi_buffer_size 16k;
            fastcgi_buffers 4 16k;
            fastcgi_connect_timeout 300;
            fastcgi_send_timeout 300;
            fastcgi_read_timeout 300;
            include /etc/nginx/fastcgi_params;
        }
     
        set_real_ip_from 173.245.48.0/20;
        set_real_ip_from 103.21.244.0/22;
        set_real_ip_from 103.22.200.0/22;
        set_real_ip_from 103.31.4.0/22;
        set_real_ip_from 141.101.64.0/18;
        set_real_ip_from 108.162.192.0/18;
        set_real_ip_from 190.93.240.0/20;
        set_real_ip_from 188.114.96.0/20;
        set_real_ip_from 197.234.240.0/22;
        set_real_ip_from 198.41.128.0/17;
        set_real_ip_from 162.158.0.0/15;
        set_real_ip_from 104.16.0.0/13;
        set_real_ip_from 104.24.0.0/14;
        set_real_ip_from 172.64.0.0/13;
        set_real_ip_from 131.0.72.0/22;
        set_real_ip_from 2400:cb00::/32;
        set_real_ip_from 2606:4700::/32;
        set_real_ip_from 2803:f800::/32;
        set_real_ip_from 2405:b500::/32;
        set_real_ip_from 2405:8100::/32;
        set_real_ip_from 2a06:98c0::/29;
        set_real_ip_from 2c0f:f248::/32;
        real_ip_header CF-Connecting-IP;
     
        location ~ /\.ht {
            deny all;
        }
    }

    Replace path_site with your site's folder in /var/www/ and exemplu.dns with your domain.

    Then press CTRL + X, Y and ENTER to save.

  4. Create the SSL certificate and enable the site

    1. Stop Nginx first, so the certificates can be created:

      bash
      systemctl stop nginx
    2. Create the SSL certificate with Certbot (replace exemplu.dns with the domain of your site):

      bash
      certbot certonly --standalone -d exemplu.dns
    3. Give Nginx the right permissions on the site (replace path_site with the location of your site in /var/www/):

      bash
      chown -R www-data:www-data /var/www/path_site/*
    4. Enable the site configuration (replace <configname> with the name you used in the previous step):

      bash
      rm /etc/nginx/sites-enabled/default && sudo ln -s /etc/nginx/sites-available/<configname>.conf /etc/nginx/sites-enabled/<configname>.conf
  5. Start Nginx

    bash
    systemctl enable nginx && systemctl start nginx