Nginx Unit

Nginx Unit

NGINX Unit is a dynamic application server, capable of running beside NGINX Plus and NGINX Open Source or standalone. Unit supports a RESTful JSON API, deploys configuration changes without service disruptions, and runs apps built with multiple languages and frameworks. Designed from scratch around the needs of your distributed applications, it lays the foundation for your service mesh.

Install nginx unit

CentOS
Unit repository:

[unit]
name=unit repo
baseurl=https://packages.nginx.org/unit/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

Install (complete)

yum install unit
yum install unit-devel unit-go unit-jsc8 unit-perl unit-php unit-python

More installations/compilations @ https://unit.nginx.org/installation/

Enable Autostart

systemctl enable unit

Architecture

Configuration

Hierarchy - Overview

{
    "certificates":{},
    "config":{
        "settings":{},
	"listeners":{},
	"routes":{},
	"applications":{},
	"access_log":{}
    }
}

Certificates

Import

curl -X PUT –data-binary @/opt/tls/bundle.pem –unix-socket /path/to/control.unit.sock http://localhost/certificates/hugo.example.com

Config

Settings

"settings":{
    "http":{
    	"header_read_timeout": 10,
        "body_read_timeout": 10,
        "send_timeout": 10,
        "idle_timeout": 120,
        "max_body_size": 6291456
    }
}

Listeners

Listeners are forwarding incoming requests to a defined pass.

TLS
"listeners":{
    "*:443"{
	"pass": "routes"
        "tls": {
            "certificate": "blogs-cert"
        }
    }
}
Non-TLS
"listeners":{
    "*:80"{
	"pass": "routes"
    },
    "127.0.0.1:8001"{
	"pass": "applications/wiki"
    }
}

Routes

Routes are like an if/elseif/else construct to match an application pass. If no match was successful, a 404 resposnse will returned

Option Description Case-Sensitive
arguments Parameter arguments supplied in the request URI. Yes
cookies Cookies supplied with the request. Yes
headers Header fields supplied with the request. No
host Host from the Host header field without port number, normalized by removing the trailing period (if any). No
method Method from the request line. No
scheme URI scheme. Currently, http and https are supported. No
uri URI path without arguments, normalized by decoding the “%XX” sequences, resolving relative path references (“.” and “..”), and compressing adjacent slashes into one. Yes
By Domain
"routes":{
    "match": {
    	"host": "hugo.example.com"
    },
    "action": {
        "pass": "applications/hugo"
    }
}
By Multidomain
"routes":{
    "match": {
    	"host": ["hugo.example.com","hugo2.example.com"]
    },
    "action": {
        "pass": "applications/hugo"
    }
}
By URI
"routes":{
    "match": {
	"uri": "/admin/*",
   },
   "action": {
        "pass": "applications/admin"
   }
}
By Domain and URI
"routes":{
    "match": {
    	"host": "hugo.example.com"
	"uri": "/admin/*",
   },
   "action": {
        "pass": "applications/admin"
   }
}
By Method
"routes":{
    "match": {
    	"method": ["!HEAD, "GET", "POST"]
   }
}
By Header

Matched if gzip and Mozilla or curl

"routes":{
    "match": {
        "headers": [
            {
                "Accept-Encoding": "*gzip*",
                "User-Agent": "Mozilla/5.0*"
            },
            {
                "User-Agent": "curl*"
            }
        ]
   },
   "action": {
        "pass": "applications/admin"
   }
}
By Argument

Query has to bee mode “strict"i and access other than “full”

"routes":{
    "match": {
        "arguments": {
            "mode": "strict",
            "access": "!full"
        }
   },
   "action": {
        "pass": "applications/admin"
   }
}
"routes":{
    "match": {
	"cookie":{
	    "user_role": "admin"
	}
   },
   "action": {
        "pass": "applications/admin"
   }
}
By Scheme
"routes":{
   "match": {
	"scheme": "https"
   },
   "action": {
        "pass": "applications/admin"
   }
}

Applications

PHP
"applications": {
    "hugo": {
    	"type": "php",
        "root": "/www/hugo/public/",
	"index": "index.php",
	"script": "index.php",
	"user": "nobody",
	"group": "nobody",
        "processes": {
            "max": 10,
	    "spare": 5,
            "idle_timeout": 30
	},
        "environment":{
	    "DB_BASE", "localhost"
	},
        "limits": {
            "timeout": 10,
            "requests": 1000
        },
        "options": {
            "file": "/etc/php.ini",
            "admin": {
	        "memory_limit": "256M",
            },
            "user": {
                "display_errors": "0"
            }
        },
   }
}
Type

For example, if you have only one PHP module, 7.3.1, it matches “php”, “php 7”, “php 7.3”, and “php 7.3.1”. Type “7.3” match the heighest version of installed PHP 7.3.x

Root

Docroot of application

Index

Set default file

Script

Route every call to the following file

User

Define user context of PHP environment

Group

Defines group context of PHP environment

Process

Set static number of processes. Optional processes are configurable as “max”, “spare” and “idle_timeout” Notice from PHP.net: “Since superglobals are only registered when they are used by the code (JIT), there should not really be a performance penalty…”

Environment

Define variables, but need an E in the variable_order (php.ini)

Limits

Define PHP limits

Options

Values must be strings and boolean flag is are “0” or “1”!!
“file” = Path to php.ini
“admin” = php_admin_values or flags - not changeable at runtime
“user” = php_values or flags - changable at runtime

Java
"applications":{
    "hugo": {
    	"type": "java",
        "webapp": "/www/hugo/hugo.war",
        "classpath": ["/www/hugo/lib/hugo-2.0.0.jar"],
        "options": ["-Dlog_path=/var/log/hugo.log"]
    }
}
Ruby
"applications":{
    "hugo": {
    	"type": "ruby",
        "script": "/www/hugo/main.ru",
        "working_directory": "/www/hugo/"
    }
}
Perl
"applications":{
    "hugo": {
    	"type": "perl",
        "script": "app.psgi",
        "processes": {
            "max": 10,
            "spare": 5,
            "idle_timeout": 20
    	},
        "working_directory": "/www/drive/"
     }
}
Phyton
"applications":{
    "hugo": {
    	"type": "phyton",
        "module": "wsgi",
        "environment": {
            "DJANGO_SETTINGS_MODULE": "hugo.settings.prod",
            "DB_ENGINE": "django.db.backends.postgresql",
            "DB_NAME": "hugo",
            "DB_HOST": "127.0.0.1",
            "DB_PORT": "5432"
        },
        "path": "/www/hugo/",
        "processes": 10
    }
}
Perl
"applications":{
    "hugo": {
    	"type": "perl",
        "script": "app.psgi",
        "processes": {
            "max": 10,
            "spare": 5,
            "idle_timeout": 20
        }
    }
}
External
"applications": {
    "grafana": {
        "type": "external",
	"executable": "/path/to/grafana/build/dir/grafana-server",
        "user": "grafanauser",
        "working_directory": "/path/to/grafana/"
    }
}

Access-Log

"access_log": "/var/log/hugo.log"