Nethence Newdoc Olddoc Lab Your IP BBDock  

Setting up NGINX


I am considering two kinds of platform (system) setup. The package provided NGINX (being RHEL or Debian systems) or NGINX from scratch. So to avoid conflicts between those two kinds of setup, I am using variables for the configuration folder and alike,

For RHEL and Debian provided NGINX,


For NGINX from scratch,


Do not to clean up your UNIX™ env variables when you have finished,

unset confdir logdir


On Debian systems,

    apt install nginx
    netstat -antupe --inet --inet6 | grep LISTEN | grep 80
systemctl status nginx

    cp -pi /etc/nginx/sites-available/default /etc/nginx/sites-available/default.dist
    cp -pi /etc/nginx/nginx.conf /etc/nginx/nginx.conf.dist
    ls -lhF /var/www/html/index.nginx-debian.html
    rm -f /var/www/html/index.nginx-debian.html
echo "<p>nothing here" > /var/www/html/index.html

On RHEL systems, make sure the EPEL repo is available and proceed,

    yum install nginx
    netstat -antupe --inet --inet6 | grep LISTEN | grep 80
systemctl start nginx
systemctl enable nginx

    cp -pi /etc/nginx/nginx.conf /etc/nginx/nginx.conf.dist
ls -alhF /usr/share/nginx/html/


For starters

Define the default index file(s) and eventually enable directory listing nginx-wide into the http stanza, also eventually define a compression log format into server or http,

vi /etc/nginx/nginx.conf

index index.html;
autoindex on;

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

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

Virtual Hosts

Setup a virtual host serving the same content on ports 80 and 443,

echo $confdir
echo $logdir

cd $confdir/
cat > $vhost.conf <<-EOF
server {
    listen 80;
    listen [::]:80;
    server_name $vhost;
    return 301 https://\$host\$request_uri;
    access_log $logdir/$vhost.access.log compression;
    error_log  $logdir/$vhost.error.log warn;

server {
    listen 443 ssl;
    listen [::]:443 ssl;
        ssl on;
    include snippets/snakeoil.conf;
    server_name $vhost;

    root /data/www/\$server_name;

    access_log $logdir/$vhost.access.log compression;
    error_log  $logdir/$vhost.error.log warn;

    location / {
        try_files $uri $uri/ =404;

vi $vhost.conf

# directory listing is enabled
mkdir -p /data/www/$vhost/

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

Note. You cannot use $server_name for access_log and error_log unless it’s fine with you to change the log folder perms accordingly (www-data needs to write in it).

Note. Redirecting HTTP to HTTPS.

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,

            proxy_pass http://localhost:4567;
            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;


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-?
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.

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;


Fancy Directory Listing

See Setting up fancy directory listing for NGINX.


If you get a 301 Moved Permanently instaed of the actual content,

curl $vhost



Home | GitHub | Donate | Contact