Additional notes on NGINX

Static vs. reverse-proxy

Serve static pages

                location / {
            root /var/www/html;
            index index.html index.htm;
                    try_files $uri $uri/ =404;

Reverse-proxy something

                location / {
                    proxy_pass http://x.x.x.x/;

More on reverse-proxy

To setup an http reverse proxy, simply change location in the server stanza

location / {
    proxy_pass http://APPLICATION_ADDRESS:PORT;

apply with systemctl restart nginx or /usr/local/nginx/sbin/nginx -s reload

Be careful, some applications need to know about the vhost and port that are called. So you shall play with those settings. Here is some specific conf for GitLab

    proxy_set_header Host $http_host;

here’s a working specific conf for Gollum, assuming you’re running SSL only on the nginx side

location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto https;

also jenkins conf

some other possible configs

    #proxy_set_header Host $host; #instead of http_host
            #proxy_set_header X-Real-IP $remote_addr;
    #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #proxy_redirect off;

and here is another one

    proxy_set_header X-Real-IP $remote_addr;

Note there is also proxy_redirect to deal with backend’s 301s


in location or server

    ssi on;

then use as such

<!--# include file="HTML-FILE-TO-INCLUDE-HERE" -->


custom format & compression – enable compression and define a custom log format to display the compression ratio

gzip  on;
log_format compression '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" "$gzip_ratio"';

separate files

server {
        access_log logs/DOMAIN.TLD.access.log compression;
        error_log  logs/DOMAIN.TLD.error.log warn;


in the server or http stanza

            location ^~ /private/ {
                    auth_basic "Restricted area";
                    auth_basic_user_file htpasswd;

then create or edit a password file

cd /usr/local/nginx/conf/

#apt install apache2-utils
#yum install httpd-?

or build and install THTTPD

htpasswd -c htpasswd NEW_USER
#DO NOT chmod 600 htpasswd as the www-data user needs to read it

if files exists already

htpasswd htpasswd EXISTING_USER

apply with systemctl restart nginx or /usr/local/nginx/sbin/nginx -s reload


Install and run the FastCGI helper

apt -y install fcgiwrap
systemctl list-unit-files | grep fcgi
systemctl status fcgiwrap.socket
ls -lhF /var/run/fcgiwrap.socket
systemctl status fcgiwrap.service

Make sure NGINX is ready for that

ls -lhF $confdir/../fastcgi_params
ls -lhF $confdir/../fastcgi.conf

Make sure your script is executable and test it

mkdir -p /data/www/$vhost/

cat > /data/www/$vhost/index.cgi <<-EOF9

cat <<EOF
Content-type: text/html

<p>hello \`host \$REMOTE_ADDR | awk '{print \$NF}'\` (\$REMOTE_ADDR)

chmod +x /data/www/$vhost/index.cgi
ls -lhF /bin/ksh
export REMOTE_ADDR=::1

and setup those parms into the vhost server stanza e.g.

vi $confdir/$vhost.conf

root /data/www/$server_name;
    index index.cgi maintenance.html;

location ~ (\.cgi|\.py|\.sh|\.pl|\.lua)$ {
    gzip off;
    fastcgi_pass unix:/var/run/fcgiwrap.socket;
    include fastcgi_params;
    fastcgi_param DOCUMENT_ROOT /data/www/$server_name;
    fastcgi_param SCRIPT_FILENAME /data/www/$server_name$fastcgi_script_name;

Note. Be careful with $server_name in the fastcgi parameters: if you do not use a vhost the server name becomes _

Note. include fastcgi_params points to conf/fastcgi_params already

apply with systemctl restart nginx or /usr/local/nginx/sbin/nginx -s reload

Additional notes

robots.txt & favicon.ico

vi /etc/nginx/drop.conf

location = /robots.txt          { access_log off; log_not_found off; }
location = /favicon.ico         { access_log off; log_not_found off; }
location ~ /apple-touch-icon    { access_log off; log_not_found off; }
#location ~ /\.                  { access_log off; log_not_found off; deny all; }
#location ~ ~$                   { access_log off; log_not_found off; deny all; }

then onto the vhost’s server stanza

include drop.conf;

cache control

into the http stanza and before the Virtual Host Configs server stanzas

vi nginx.conf

# Expires map
map $sent_http_content_type $expires {
    default                    off;
    text/html                  epoch;
    text/css                   max;
    application/javascript     max;
    ~image/                    max;

as docker container

to run as Docker container on foreground,

nginx -g 'daemon off;'



Nginx proxy_redirect: Change response-header Location and Refresh in the response of the server

Moodle behind ssl reverse proxy: “Reverse proxy enabled, server can not be accessed directly, sorry.”

favicon and robots ignore



How to Implement Browser Caching with Nginx’s header Module on CentOS 7



phases and why not use variables everywhere

Nginx directive execution order (01)

HTTP request processing phases in Nginx


Module ngx_http_ssi_module


Configuring Logging


nginx listen on specific interface [closed]

NGINX bind to a specific network interface, regardless of IP address