Well done @ Nginx Unit

Ibrahim Sha
Analytics Vidhya
Published in
4 min readMay 26, 2021

--

Photo by Tyler Nix on Unsplash

Hello <coders>,

On my programming journey, I always felt that server configuration for an application was taking more time than expected. Sometimes, I would be entering into a recursive mode of executing a single command and updating the .conf file (when the configuration server goes wrong) 😿,.

while server.conf != right:   vim edit server.conf   sudo services server_name restart

A few days back, I got the chance to explore nginx unit and its features. I felt very excited that the configuration of the webserver can be handled in a single JSON file, supporting dynamic web applications elegantly, and restarting the server not needed πŸ‘πŸ‘. Config file added below for quick insights,

Nginx unit, is to reduce the operational complexity by providing single middleware to supporting multiple applications and update on fly without dropping connection.

Architecture:

Nginx-unit, architecture broken into three layers,

  1. Controller process
  2. Router Process
  3. Application Process

Controller process:

  • manages the configuration of the application(`config.json`) and router process.
  • the process can be interacted/reconfiguration of application and router process via an API interface.
  • reference: link
sudo curl --unix-socket /path/to/control.unit.sock http://localhost/config/{
"listeners": {
"127.0.0.1:8300": {
"pass": "applications/blogs"
}
},

"applications": {
"blogs": {
"type": "php",
"root": "/www/blogs/scripts/"
}
}
}

Router process:

  • router process, will accept the incoming requests from the client, transfer to the application process and send back the application response to the client.
  • if the configuration is updated, the router process will start a new worker with the latest configuration and handle new request connection(s).
  • though configuration changed, router worker threads can serve the request without reloading the server.

Application process:

  • each application is served by Unit is run by an isolated process or set of process.
  • the application process will be started by demand, create a new fork.
  • the router and application process will communicate via socket pairs and shared memory segments.

Installation:

brew install nginx/unit/unit# To install the Java, Perl, Python, and Ruby language modulesbrew install unit-java unit-perl unit-python unit-python3 unit-ruby

I have provided installation steps for mac environment, for other environments and languages follow the Nginx unit official docs.

Configuration (link)

Listener

  • To start accepting requests, add a listener object in the config/listeners API section.
  • Unit dispatches the requests it receives to destinations referenced by listeners.
  • Listener's pattern will be host_addr:port_no and map with applications object.
"listeners": {      "*:8080": {          "pass": "applications/flask"      },
"*:8090": {
"pass": "applications/django"
},
}

Route object

  • Route object is to filter/process the internal request between listener and applications.
  • the array of route steps is used as the value of the routes attribute,
{
"listeners": {
"*:8080": {
"pass": "routes"
},
"routes": [
{
"
match": {
"uri": [
"!pattern1",
"!pattern2",
"pattern3"
]
},
"
action": {
"pass": "..."
}
}

]
}
}
  • If a request matches all conditions of the route step, the action section with pass identical to pass in a listener.

Proxying

  • proxy a request handled by the Unit to another HTTP service.
{
"routes": [
{
"match": {
"uri": "/ipv4/*"
},
"action": {
"proxy": "http://127.0.0.1:5000"
}
}
]
}

Static files

  • Unit is capable of acting as a standalone web server, serving requests for static assets from directories you configure; to use the feature, supply the directory path in the share option of a route step.
{
"listeners": {
"127.0.0.1:8300": {
"pass": "routes"
}
},
"routes": [
{
"action": {
"share": "/www/data/static/",
"fallback": {
"pass": "/var/app/static/"
}
}
}
]
}
  • Unit has fallback the attribute will help to serve the file from an alternate location (if the static file is not found in the location referred to in share).

Mentioned configurations are often used in all applications and other configurations such as Limits, User, and Group permissions please refer to this doc.

Startup and shutdown command

sudo /etc/init.d/unitd startsudo /etc/init.d/unitd stop

Sample Code

I have created the sample repo with Nginx unit configurations and flask applications. Using the apache bench tool, loaded the performance report of Nginx unit + flask (VS) uwsgi + flask applications.

Link: https://github.com/ibrahimsha23/nginx_performance

Thanks for reading!

Please share your suggestions in the comments. Feedbacks and claps are really appreciated.

To reach out to me, connect with me on LinkedIn.

--

--