What best practices do you use while using NGinx?
15 Answers
By far, the best tips I have ever seen are from the author on it's pitfall page: https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
- 252,907
- 493
Generally, using "if" is a bad practice (according to author of nginx). if possible, better to use try_file of error_page directives instead "if (-f ...)"
Combining tip with maintenence.html file and tip with try_files we get:
location / {
try_files /maintenance.html $uri $uri/ @wordpress;
}
When maintenance ends, just mv maintenance.html from $root.
- 66
- 1
- 4
Configure nginx to use stronger SSL ciphers. By default, SSLv2 is enabled (which you should disable if possible).
ssl_ciphers DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA:DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5;
http://tumblelog.jauderho.com/post/121851623/nginx-and-stronger-ssl
- 5,645
Its often more efficient to use the map directive in place of regular expressions when switching the root for matching subdomains:
server {
server_name mysite.tld ~^.+\.mysite\.tld$;
map $host $files {
default common;
mysite.tld common;
www.mysite.tld common;
admin.mysite.tld admin;
system.mysite.tld system;
*.mysite.tld users;
}
root /var/www/mysite/$files;
}
- 1,046
The empty_gif module is also very useful, especially if you need monitor responses from the webserver (using nagios/monit/etc):
location /token {
empty_gif;
}
location /favicon.ico {
empty_gif;
}
location /img/1px.gif {
empty_gif;
}
- 1,046
We set up Nginx with Chef, using this cookbook which contains scripts for handling nginx configuration similar to how Debian does Apache2, and also some sample templates with sane defaults.
- 7,665
Here's a good method for returning a maintenance page. All requests are rewritten and the correct http code is returned. (503 - Service unavailable)
error_page 503 /maintenance.html;
location /
{
if (-f $document_root/maintenance.html)
{
return 503;
}
try_files $uri /index.php?$args;
}
location = /maintenance.html
{
rewrite ^ /maintenance.html break;
}
From nginx 0.7.12 and later, a "" is usable in server_name to catch requests without a "Host" header.
You can use the following as a catchall for undefined virtual hosts.
server {
server_name _ "";
}
- 1,765
I also posted a while ago about how to properly handle gzip compression with nginx as older browsers may have issues with just a blanket gzip statement. HTH.
http://tumblelog.jauderho.com/post/27655495/gzip-compression-with-nginx
- 5,645
I don't know if it is a best practice, but definitely a neat hack to get nested conditions in nginx. Here's a sample from the nginx wiki.
location /xxxx/ {
set $test "";
if ($request_method = POST) {
set $test P;
}
if ($http_cookie ~* "CCCC=.+(?:;|$)" ) {
set $test "${test}C";
}
if ($test = PC) {
#rewrite rule goes here.
}
}
- 4,447
- 602
If you need to flip contextually between http and https for subdomains handled by the same server block, you can use variables to do so. Might not be the most efficient way to do things, but it works:
server {
server mysite.tld ~^.+\.mysite\.tld$;
set $req_ssl = 0;
map $host $files {
default common;
mysite.tld common;
www.mysite.tld common;
admin.mysite.tld admin;
system.mysite.tld system;
*.mysite.tld users;
}
root /var/www/mysite/$files;
if ( $files = "admin" ){
set $req_ssl 1;
}
if ( $files = "common" ){
set $req_ssl 2;
}
if ( $scheme = http )
{
set $req_ssl $req_ssl.1;
}
if ( $scheme = https )
{
set $req_ssl $req_ssl.2;
}
if ($req_ssl = 1.1){
rewrite ^ https://$host$uri;
}
if ($req_ssl = 2.2){
rewrite ^ http://$host$uri;
}
}
- 1,046
I always try to use the root directive in the top of the server block so I can take advantage of the $document_root variable and never, but never, include the root directive inside a location block.
The Pitfalls Page from the Nginx wiki has some great tips about best practices.
- 252,907
If you are using nginx as a proxy, having the timeout settings adjusted can be important to ensure you are not having nginx drop connections before your application is done with them, especially if you are dealing with a high traffic application:
proxy_connect_timeout
proxy_send_timeout
- 749