Nginx Production Configuration
Collection of Nginx tweaks that improve performance, strengthen security, and ease application deployments in production.
After every change, test the syntax and reload the service.
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo service nginx restart
1. Let's Encrypt SSL Certificates
Follow the guide Installing Let's Encrypt SSL certificates with Nginx on Debian that issues the certificate, then apply the configuration below.
sudo nano /etc/nginx/sites-available/your_domain.com
your_domain.com
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain.com www.your_domain.com;
location / {
try_files $uri $uri/ =404;
}
ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
listen 80;
listen [::]:80;
server_name your_domain.com www.your_domain.com;
return 301 https://$host$request_uri;
}
2. Self-signed SSL Certificates
Install the ssl-cert
package to generate self-signed certificates on Debian 10.
sudo apt-get update && sudo apt-get install -y ssl-cert
Then adjust the server block as follows:
sudo nano /etc/nginx/sites-available/your_domain.com
your_domain.com
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain.com www.your_domain.com;
location / {
try_files $uri $uri/ =404;
}
include snippets/snakeoil.conf;
}
server {
listen 80;
listen [::]:80;
server_name your_domain.com www.your_domain.com;
return 301 https://$host$request_uri;
}
3. Verify HTTPS Navigation
Self-signed certificates trigger warnings. You will see an error like this:
curl https://your_domain.com
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
Use the -k
flag to ignore the warning and continue.
curl -k https://your_domain.com
<html>
<head>
<title>Welcome to your_domain.com!</title>
</head>
<body>
<h1>Success! The your_domain.com server block is working!</h1>
</body>
</html>
Finally, test the HTTP-to-HTTPS redirect:
curl http://your_domain.com
<html>
<head>
<title>301 Moved Permanently</title>
</head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr />
<center>nginx/1.14.2</center>
</body>
</html>
4. Enable Cache Control
Specify which file types should be cached and for how long.
sudo nano /etc/nginx/sites-available/your_domain.com
your_domain.com
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain.com www.your_domain.com;
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 10m;
add_header Cache-Control "public, no-transform";
}
location / {
try_files $uri $uri/ =404;
}
include snippets/snakeoil.conf;
}
5. Enable File Compression
Turn on gzip
to shrink static responses.
sudo nano /etc/nginx/sites-available/your_domain.com
your_domain.com
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain.com www.your_domain.com;
location / {
try_files $uri $uri/ =404;
}
gzip on;
gzip_comp_level 3;
gzip_min_length 1000;
gzip_types text/xml text/css;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [4-6] \.";
include snippets/snakeoil.conf;
}
6. Custom Error Pages
Create an HTML page and reference it from the site block.
sudo nano /usr/share/nginx/html/custom_404.html
custom_404.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>404 Not Found</title>
</head>
<body>
404 Not Found
</body>
</html>
sudo nano /etc/nginx/sites-available/your_domain.com
your_domain.com
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain.com www.your_domain.com;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /custom_404.html;
location = /custom_404.html {
root /usr/share/nginx/html;
internal;
}
include snippets/snakeoil.conf;
}
7. Proxy for Node.js Applications
Expose your Node.js app behind a dedicated location
block.
sudo nano /etc/nginx/sites-available/your_domain.com
your_domain.com
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain.com www.your_domain.com;
location / {
try_files $uri $uri/ =404;
}
location /node-app/ {
proxy_pass http://127.0.0.1:3000;
}
include snippets/snakeoil.conf;
}
8. Remove the .html Extension
Serve clean URLs without forcing the .html
suffix.
sudo nano /etc/nginx/sites-available/your_domain.com
your_domain.com
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain.com www.your_domain.com;
location / {
try_files $uri.html $uri $uri/ =404;
}
include snippets/snakeoil.conf;
}
For example, the request https://your_domain.com/page
will try paths in this order:
/page.html
/page
/page/
If none exist, Nginx returns the 404 error page.
References
Published: June 8, 2020