Nginx [engine x] is a web server (or HTTP) software written by Igor Sysoev, whose development began in 2002 for the needs of a high-traffic Russian site.
I've been looking for an alternative to Apache for some time because it's too resource-hungry. When discovering lighttpd, I realized that other servers existed besides Apache and IIS. It was time to dig deeper into this question.
Installation
For the installation on Debian, it's always simple:
For the configuration, we will create a basic configuration (if possible, delete the default configuration). We will change it later, but this gives you an idea of a minimal working configuration:
; The address on which to accept FastCGI requests.; Valid syntaxes are:; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on; a specific port;; 'port' - to listen on a TCP socket to all addresses on a; specific port;; '/path/to/unix/socket' - to listen on a unix socket.; Note: This value is mandatory.listen=/var/run/php5-fpm.sock
server{listen80;server_namelocalhost;access_log/var/log/nginx/localhost.access.log;location/{root/var/www/nginx-default;indexindex.htmlindex.htmindex.php;}location/doc{root/usr/share;autoindexon;allow127.0.0.1;denyall;}location/images{root/usr/share;autoindexon;}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page500502503504/50x.html;location=/50x.html{root/var/www/nginx-default;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {#proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000#location~\.php${root/var/www/nginx-default;include/etc/nginx/fastcgi_params;fastcgi_pass127.0.0.1:9000;fastcgi_indexindex.php;fastcgi_paramSCRIPT_FILENAME/var/www/nginx-default/$fastcgi_script_name;}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {#deny all;#}}
nginx.conf
Here is the global server configuration. I added comments on important lines:
userwww-data;# Number of working processworker_processes2;worker_rlimit_nofile2000;pid/var/run/nginx.pid;events{# Maximum connection numberworker_connections2048;useepoll;# multi_accept on;}http{### Basic Settings##sendfileon;tcp_nopushon;tcp_nodelayon;keepalive_timeout65;types_hash_max_size2048;map_hash_bucket_size64;# Security to hide versionserver_tokensoff;server_names_hash_bucket_size64;# server_name_in_redirect off;# Grow this 2 values if you get 502 error messagefastcgi_buffers25616k;fastcgi_buffer_size32k;# Nginx cache to boost performancesfastcgi_cache_path/usr/share/nginx/cachelevels=1:2
keys_zone=mycache:10m
inactive=1hmax_size=256m;include/etc/nginx/mime.types;default_typeapplication/octet-stream;### Logging Settings##access_log/var/log/nginx/access.log;error_log/var/log/nginx/error.log;### Gzip Settings##gzipon;gzip_disable"msie6";gzip_staticon;gzip_varyon;gzip_proxiedany;gzip_comp_level6;gzip_buffers168k;gzip_http_version1.1;gzip_typestext/plaintext/cssapplication/jsonapplication/x-javascripttext/xmlapplication/xmlapplication/xml+rsstext/javascript;### nginx-naxsi config### Uncomment it if you installed nginx-naxsi###include /etc/nginx/naxsi_core.rules;### nginx-passenger config### Uncomment it if you installed nginx-passenger###passenger_root /usr;#passenger_ruby /usr/bin/ruby;### Virtual Host Configs##include/etc/nginx/conf.d/*.conf;include/etc/nginx/sites-enabled/*;}
drop.conf
This file will allow us to not log non-essential information and prevent access to potentially sensitive files:
# Do not log robots.txt if not foundlocation=/robots.txt{access_logoff;log_not_foundoff;}# Do not log favicon.ico if not foundlocation=/favicon.ico{access_logoff;log_not_foundoff;}# Do not give access to hidden fileslocation~/\.{access_logoff;log_not_foundoff;denyall;}# Do not give access to vim backuped fileslocation~~${access_logoff;log_not_foundoff;denyall;}
Then in your configuration files, just add these 2 lines:
All that remains is to reload the server and it works :-)
htaccess
To restrict access to some of your sites, here's one of the oldest but effective solutions - htaccess! To enable them, we will need the htpasswd binary:
All that remains is to reload the server and it works :-)
Default Port
To specify the default port, you can use an include in your configuration files that will call a file containing the port. This way it will be very easy to modify the default port in one go:
server{listen443ssl;server_namelocalhost;ssl_certificate/etc/nginx/ssl/server.crt;ssl_certificate_key/etc/nginx/ssl/server.key;# Resumptionssl_session_cacheshared:SSL:10m;# Timeoutssl_session_timeout10m;# Security optionsssl_ciphersECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA;ssl_prefer_server_cipherson;# HSTS (force users to come in SSL if they've already been once)add_headerStrict-Transport-Security"max-age=31536000; includeSubdomains";access_log/var/log/nginx/localhost.access.log;location/{root/var/www/nginx-default/webmail;indexindex.htmlindex.htmindex.php;}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000#location~\.php${root/var/www/nginx-default;include/etc/nginx/fastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_indexindex.php;fastcgi_paramSCRIPT_FILENAME/var/www/nginx-default/$fastcgi_script_name;}}
FastCGI cache is useful to increase the speed of your website. We'll allocate a few MB for the cache and put it in a tmpfs to speed things up even more. In the main configuration, we'll create this cache:
All you need to do is insert a maintenance.html page at the root of your site and this page will be displayed while you make your changes. You can also use this method:
It can happen that a malicious person tries to bring your server to its knees by making many requests that typically saturate PHP processes and make your CPUs go to 100%. To avoid this, it is possible to limit the number of requests per IP by using the limit_req module^1. To enable this module, insert this line in your Nginx core (global) configuration:
zone=limit: IPs will be stored in a zone called limit of 10M. Provide enough space in this zone to avoid 503 errors if there is no more space. A 1M zone can contain 16,000 binary_remote_addr type entries.
rate: we allow 5 requests per second.
log_level: you can remove this line if you don't want to know in the logs if the limits are reached. Here I want to track this kind of event.
Next, we need to inform on which virtualhost or location we want to apply this security measure:
server{includelisten_port.conf;listen443ssl;server_namewww.deimos.fr;access_log/var/log/nginx/www.deimos.fr_access.log;error_log/var/log/nginx/www.deimos.fr_error.log;# Blog redirectrewrite^/$$scheme://blog.deimos.frpermanent;rewrite^/blog(/.*)?$$scheme://blog.deimos.fr$1permanent;# mytechnotebook redirectrewrite^/mytechnotebook(/.*)?$$scheme://wiki.deimos.fr$1permanent;# Piwikrewrite^/piwik(/.*)?$$scheme://piwik.deimos.fr$1permanent;# Gitwebrewrite^/gitweb(/.*)?$$scheme://git.deimos.fr$1permanent;# Drop configincludedrop.conf;}
Server Status
By default, it's possible to get information about the server status, like this:
server{includelisten_port.conf;listen443ssl;server_namewww.deimos.fr;access_log/var/log/nginx/www.deimos.fr_access.log;error_log/var/log/nginx/www.deimos.fr_error.log;# Nginx statuslocation/server-status{# Turn on nginx statsstub_statuson;# I do not need logs for statsaccess_logoff;# Allow from localhostallow127.0.0.1;# Deny othersdenyall;}# PHP-FPM statuslocation/php-fpm_status{includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;# I do not need logs for statsaccess_logoff;# Allow from localhostallow127.0.0.1;# Deny othersdenyall;}# Cache APClocation/apc-cache{root/usr/share/doc/php-apc;}location~\.php${includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_intercept_errorson;# I do not need logs for statsaccess_logoff;# Allow from localhostallow127.0.0.1;# Deny othersdenyall;}# Blog redirectrewrite^/$$scheme://blog.deimos.frpermanent;rewrite^/blog(/.*)?$$scheme://blog.deimos.fr$1permanent;# mytechnotebook redirectrewrite^/mytechnotebook(/.*)?$$scheme://wiki.deimos.fr$1permanent;# Piwikrewrite^/piwik(/.*)?$$scheme://piwik.deimos.fr$1permanent;# Gitwebrewrite^/gitweb(/.*)?$$scheme://git.deimos.fr$1permanent;# Drop configincludedrop.conf;}
server{includelisten_port.conf;listen443ssl;ssl_certificate/etc/nginx/ssl/deimos.fr/server-unified.crt;ssl_certificate_key/etc/nginx/ssl/deimos.fr/server.key;ssl_session_timeout5m;server_nameblog.deimos.fr;root/usr/share/nginx/www/deimos.fr/blog;indexindex.php;access_log/var/log/nginx/blog.deimos.fr_access.log;error_log/var/log/nginx/blog.deimos.fr_error.log;location/{try_files$uri$uri//index.php?$args;}location~\.php${fastcgi_cachemycache;fastcgi_cache_key$request_method$host$request_uri;fastcgi_cache_validany1h;includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_intercept_errorson;}# Drop configincludedrop.conf;# BEGIN W3TC Browser Cachegzipon;gzip_typestext/cssapplication/x-javascripttext/x-componenttext/richtextimage/svg+xmltext/plaintext/xsdtext/xsltext/xmlimage/x-icon;location~\.(css|js|htc)${expires31536000s;add_headerPragma"public";add_headerCache-Control"public, must-revalidate, proxy-revalidate";add_headerX-Powered-By"W3 Total Cache/0.9.2.4";}location~\.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)${expires3600s;add_headerPragma"public";add_headerCache-Control"public, must-revalidate, proxy-revalidate";add_headerX-Powered-By"W3 Total Cache/0.9.2.4";}location~\.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)${expires31536000s;add_headerPragma"public";add_headerCache-Control"public, must-revalidate, proxy-revalidate";add_headerX-Powered-By"W3 Total Cache/0.9.2.4";}# END W3TC Browser Cache# BEGIN W3TC Minify corerewrite^/wp-content/w3tc/min/w3tc_rewrite_test$/wp-content/w3tc/min/index.php?w3tc_rewrite_test=1last;rewrite^/wp-content/w3tc/min/(.+\.(css|js))$/wp-content/w3tc/min/index.php?file=$1last;# END W3TC Minify core}}
Mediawiki
For setting up Mediawiki with Nginx and short URLs, here's the configuration to adopt. I've also added SSL and forced redirects from the login page to SSL:
server{includelisten_port.conf;listen443ssl;ssl_certificate/etc/nginx/ssl/deimos.fr/server-unified.crt;ssl_certificate_key/etc/nginx/ssl/deimos.fr/server.key;ssl_session_timeout5m;server_namewiki.deimos.frwiki.m.deimos.fr;root/usr/share/nginx/www/deimos.fr/mytechnotebook;client_max_body_size5m;client_body_timeout60;access_log/var/log/nginx/wiki.deimos.fr_access.log;error_log/var/log/nginx/wiki.deimos.fr_error.log;location/{rewrite^/$$scheme://$host/index.phppermanent;# Short URL redirecttry_files$uri$uri/@rewrite;}location@rewrite{if(!-f$request_filename){rewrite^/(.*)$/index.php?title=$1&$args;}}# Force SSL Loginset$ssl_requested0;if($arg_title~Sp%C3%A9cial:Connexion){set$ssl_requested1;}if($scheme=https){set$ssl_requested0;}if($ssl_requested=1){return301https://$host$request_uri;}# Drop configincludedrop.conf;# Deny direct access to specific folderslocation^~/(maintenance|images)/{return403;}location~\.php${fastcgi_cachemycache;fastcgi_cache_key$request_method$host$request_uri;fastcgi_cache_validany1h;includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;}location=/_.gif{expiresmax;empty_gif;}location^~/cache/{denyall;}location/dumps{root/usr/share/nginx/www/deimos.fr/mytechnotebook/local;autoindexon;}# BEGIN W3TC Browser Cachegzipon;gzip_typestext/cssapplication/x-javascripttext/x-componenttext/richtextimage/svg+xmltext/plaintext/xsdtext/xsltext/xmlimage/x-icon;location~\.(css|js|htc)${expires31536000s;add_headerPragma"public";add_headerCache-Control"public, must-revalidate, proxy-revalidate";add_headerX-Powered-By"W3 Total Cache/0.9.2.4";}location~\.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)${expires3600s;add_headerPragma"public";add_headerCache-Control"public, must-revalidate, proxy-revalidate";add_headerX-Powered-By"W3 Total Cache/0.9.2.4";}location~\.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)${expires31536000s;add_headerPragma"public";add_headerCache-Control"public, must-revalidate, proxy-revalidate";add_headerX-Powered-By"W3 Total Cache/0.9.2.4";try_files$uri$uri/@rewrite;}# END W3TC Browser Cache}
Gitweb
With Nginx, you need to allow certain extensions in php-fpm:
server{listen80;listen443ssl;ssl_certificate/etc/nginx/ssl/deimos.fr/server-unified.crt;ssl_certificate_key/etc/nginx/ssl/deimos.fr/server.key;ssl_session_timeout5m;server_namegit.deimos.fr;root/usr/share/gitweb/;access_log/var/log/nginx/git.deimos.fr_access.log;error_log/var/log/nginx/git.deimos.fr_error.log;indexgitweb.cgi;# Drop configincludedrop.conf;# Git over httpslocation/git/{alias/var/cache/git/;if($scheme=http){rewrite^https://$host$request_uripermanent;}}# Gitweblocation~gitweb\.cgi{fastcgi_cachemycache;fastcgi_cache_key$request_method$host$request_uri;fastcgi_cache_validany1h;includefastcgi_params;fastcgi_passunix:/run/fcgiwrap.socket;}}
Here I have my git over https working (http is redirected to https) and my gitweb also since everything that matches gitweb.cgi is matched. Now, for the git part, we'll need to authorize the repositories we want. For this, we'll need to rename a file in our repository and run a command:
server{includelisten_port.conf;listen443ssl;ssl_certificate/etc/nginx/ssl/deimos.fr/server-unified.crt;ssl_certificate_key/etc/nginx/ssl/deimos.fr/server.key;ssl_session_timeout5m;server_namepiwik.deimos.fr;root/usr/share/nginx/www/deimos.fr/piwik;indexindex.php;access_log/var/log/nginx/piwik.deimos.fr_access.log;error_log/var/log/nginx/piwik.deimos.fr_error.log;# Drop configincludedrop.conf;location/{try_files$uri$uri//index.php?$args;}location~\.php${fastcgi_cachemycache;fastcgi_cache_key$request_method$host$request_uri;fastcgi_cache_validany1h;includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_intercept_errorson;}location~*\.(js|css|png|jpg|jpeg|gif|ico)${expiresmax;log_not_foundoff;}}
ownCloud
ownCloud 4.X
Here's the configuration for ownCloud 4.X with Nginx:
server{includelisten_port.conf;listen443defaultssl;sslon;ssl_certificate/etc/nginx/ssl/deimos.fr/server-unified.crt;ssl_certificate_key/etc/nginx/ssl/deimos.fr/server.key;server_nameowncloud.deimos.fr;root/usr/share/nginx/www/deimos.fr/owncloud;indexindex.php;client_max_body_size1024M;access_log/var/log/nginx/cloud.deimos.fr_access.log;error_log/var/log/nginx/cloud.deimos.fr_error.log;# Force SSLif($scheme=http){return301https://$host$request_uri;}# deny direct accesslocation~^/(data|config|\.ht|db_structure\.xml|README){denyall;}# default try orderlocation/{try_files$uri$uri/@webdav;}# owncloud WebDAVlocation@webdav{fastcgi_cachemycache;fastcgi_cache_key$request_method$host$request_uri;fastcgi_cache_validany1h;fastcgi_split_path_info^(.+\.php)(/.*)$;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;fastcgi_paramHTTPSon;includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_intercept_errorson;}location~\.php${try_files$uri=404;fastcgi_cachemycache;fastcgi_cache_key$request_method$host$request_uri;fastcgi_cache_validany1h;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;fastcgi_paramHTTPSon;includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_intercept_errorson;}# Drop configincludedrop.conf;}
server{includelisten_port.conf;listen443defaultssl;sslon;ssl_certificate/etc/nginx/ssl/deimos.fr/server-unified.crt;ssl_certificate_key/etc/nginx/ssl/deimos.fr/server.key;server_namecloud.deimos.fr;root/usr/share/nginx/www/deimos.fr/owncloud;indexindex.php;client_max_body_size1024M;access_log/var/log/nginx/cloud.deimos.fr_access.log;error_log/var/log/nginx/cloud.deimos.fr_error.log;# Force SSLif($scheme=http){return301https://$host$request_uri;}rewrite^/caldav((/|$).*)$/remote.php/caldav$1last;rewrite^/carddav((/|$).*)$/remote.php/carddav$1last;rewrite^/webdav((/|$).*)$/remote.php/webdav$1last;error_page403=/core/templates/403.php;error_page404=/core/templates/404.php;location~^/(data|config|\.ht|db_structure\.xml|README){denyall;}location/{rewrite^/.well-known/host-meta/public.php?service=host-metalast;rewrite^/.well-known/host-meta.json/public.php?service=host-meta-jsonlast;rewrite^/.well-known/carddav/remote.php/carddav/redirect;rewrite^/.well-known/caldav/remote.php/caldav/redirect;rewrite^(/core/doc/[^\/]+/)$$1/index.html;try_files$uri$uri/index.php;}location~^(?<script_name>.+?\.php)(?<path_info>/.*)?${try_files$script_name=404;fastcgi_cache_validany1h;includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;}location~*^.+.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)${expires30d;# Optional: Don't log access to assetsaccess_logoff;}# Drop configincludedrop.conf;}
Firefox Sync Server
For Firefox Server Sync, it's proxification. We forward requests to another service:
server{includelisten_port.conf;listen443ssl;ssl_certificate/etc/nginx/ssl/server.crt;ssl_certificate_key/etc/nginx/ssl/server.key;ssl_session_timeout5m;# Force SSLif($scheme=http){return301https://$host$request_uri;}server_namefirefoxsync.deimos.fr;access_log/var/log/nginx/firefoxsync.deimos.fr_access.log;error_log/var/log/nginx/firefoxsync.deimos.fr_error.log;location/{proxy_pass_headerServer;proxy_set_headerHost$http_host;proxy_redirectoff;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Scheme$scheme;proxy_connect_timeout10;proxy_read_timeout10;proxy_passhttp://localhost:5000/;}# Drop configincludedrop.conf;}
server{includelisten_port.conf;server_namefeed.deimos.fr;root/usr/share/nginx/www/selfoss;indexindex.php;access_log/var/log/nginx/feed.deimos.fr_access.log;error_log/var/log/nginx/feed.deimos.fr_error.log;location~*\ (gif|jpg|png){expires30d;}location~^/favicons/.*${try_files$uri/data/$uri;}location~*^/(data\/logs|data\/sqlite|config\.ini|\.ht){denyall;}location/{try_files$uri/public/$uri/index.php$is_args$args;}location~\.php${client_body_timeout360;send_timeout360;includefastcgi_params;fastcgi_passunix:/var/run/php5-fpm.sock;fastcgi_intercept_errorson;}# Drop configincludedrop.conf;}
server{includelisten_port.conf;server_nameseafile.deimos.fr;# Force redirect http to httpsrewrite^https://$http_host$request_uri?permanent;}server{includessl/deimos.fr_ssl.conf;includepagespeed.conf;server_nameseafile.deimos.fr;root/usr/share/nginx/www/deimos.fr/seafile;access_log/var/log/nginx/seafile.deimos.fr_access.log;error_log/var/log/nginx/seafile.deimos.fr_error.log;# Max upload sizeclient_max_body_size1G;location/{fastcgi_pass127.0.0.1:8090;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;fastcgi_paramPATH_INFO$fastcgi_script_name;fastcgi_paramSERVER_PROTOCOL$server_protocol;fastcgi_paramQUERY_STRING$query_string;fastcgi_paramREQUEST_METHOD$request_method;fastcgi_paramCONTENT_TYPE$content_type;fastcgi_paramCONTENT_LENGTH$content_length;fastcgi_paramSERVER_ADDR$server_addr;fastcgi_paramSERVER_PORT$server_port;fastcgi_paramSERVER_NAME$server_name;fastcgi_paramREMOTE_ADDR$remote_addr;fastcgi_paramHTTPSon;fastcgi_paramHTTP_SCHEMEhttps;}# Webdavlocation/seafdav{fastcgi_pass127.0.0.1:8080;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;fastcgi_paramPATH_INFO$fastcgi_script_name;fastcgi_paramSERVER_PROTOCOL$server_protocol;fastcgi_paramQUERY_STRING$query_string;fastcgi_paramREQUEST_METHOD$request_method;fastcgi_paramCONTENT_TYPE$content_type;fastcgi_paramCONTENT_LENGTH$content_length;fastcgi_paramSERVER_ADDR$server_addr;fastcgi_paramSERVER_PORT$server_port;fastcgi_paramSERVER_NAME$server_name;fastcgi_paramHTTPSon;}location/seafhttp{rewrite^/seafhttp(.*)$$1break;proxy_passhttp://127.0.0.1:8082;client_max_body_size0;}location/media{root/var/www/deimos.fr/seafile/seafile-server-latest/seahub;}}
Gogs
For Gogs, it's simple because all you need to set is a proxy pass:
server{includelisten_port.conf;server_namegit.deimos.fr;# Force redirect http to httpsrewrite^https://$http_host$request_uri?permanent;}server{includessl/deimos.fr_ssl.conf;server_namegit.deimos.fr;access_log/var/log/nginx/git.deimos.fr_access.log;error_log/var/log/nginx/git.deimos.fr_error.log;location/{proxy_passhttp://127.0.0.1:3000;}}
FAQ
How to Analyze Rules
You can see the behavior of your rules (e.g., 301 redirects) using curl: