Summer’s gone, so it’s time to forfeit the halcyon tranquility and get some working attitude on. The NGINX Unit team has recently presented our first two‑digit version,
NGINX Unit 1.10.0; let’s page through the recent developments and shed some light on our plans for the future.
Routing Advancements
In our two latest releases, some major effort went into extending the request routing capabilities that were initially
introduced in NGINX Unit 1.8.0. Version 1.9.0 included essential support for arguments, headers, and cookies in matching clauses, whereas
NGINX Unit 1.10.0 added
scheme‑based routing to the mix. A few examples:
“match”: {
“host”: “www.example.com”,
“arguments”: {
“mode”: [“mobile”, “desktop”],
“ui”: “!full”
}
}
This condition matches queries like
www.example.com/?mode=mobile and
www.example.com/?mode=desktop&ui=compact, but not
www.example/com/?mode=desktop&ui=full.
“match”: {
“headers”: [
{
“Accept-Encoding”: “*gzip*”,
“User-Agent”: “Mozilla/5.0*”
},
{
“User-Agent”: “curl*”
}
]
}
This clause matches only requests where the
User-Agent
header is either
Mozilla/5.0
(and
gzip
compression is also applied) or
curl
.
“match”: {
“host”: “example.com”,
“scheme”: “https”
}
This condition matches
https://example.com, but not
http://example.com.
Pattern matching was also extended to allow wildcards in the middle of the match string:
“match”: {
“host”: [“eu-*.example.com”, “!eu-5.example.com”]
}
This clause happily matches all
eu- subdomains of
example.com except
eu-5.example.com.
Configuration Updates
The
config API received some polishing as well. Most importantly, it now supports non‑idempotent
POST
semantics. In less fancy terms, this means you can append new items to arrays, which do occur in NGINX Unit configuration. For instance, consider this sample output from a
curl
query to NGINX Unit’s control socket:
# curl –unix-socket /path/to/control.unit.sock http://localhost/config/
{
“listeners”: {
“*:8000”: {
“pass”: “routes”
}
},
“applications”: {
“blogs”: {
“type”: “python”,
“module”: “wsgi”,
“path”: “/www/blogs/”
}
},
“routes”: [
{
“match”: {
“host”: [
“dev1.example.com”,
“dev2.example.com”
]
},
“action”: {
“pass”: “applications/blogs”
}
}
]
}
Let’s decipher the JSON: the configuration includes an application called
blogs
, a
routes
section that allows access to the app via two hostnames, and a listener that passes incoming requests through the routing engine. Using the
POST
method, we append a new hostname to the
host
array:
# curl -X POST -d ‘”dev3.example.com”‘ –unix-socket=/path/to/control.unit.sock \
http://localhost/config/routes/0/match/host/
{
“success”: “Reconfiguration done.”
}
Note that all responses from NGINX Unit are also encoded in JSON. Next, I make a
curl
query to display just the
routes
section:
# curl –unix-socket /path/to/control.unit.sock http://localhost/config/routes/
[
{
“match”: {
“host”: [
“dev1.example.com”,
“dev2.example.com”,
“dev3.example.com”
]
},
“action”: {
“pass”: “applications/blogs”
}
}
]
As you can see, the
POST
operation appended its payload to the end of the
host
array. It’s worth mentioning here that NGINX Unit changes only the sections of the configuration that are affected by the update, calculating the difference between the old config and the new on the fly to minimize overhead. Handy!
In other news, we’ve also done away with a few nasty bugs, making config manipulation more reliable.
Application Languages
Most of the latest changes in language support are for Node.js, including a new built‑in WebSocket server implementation in
NGINX Unit 1.10.0. To use it, just specify our module as the parameter to the
require
function instead of the native
websocket
module:
var webSocketServer = require(‘unit-http/websocket’).server;
In addition,
NGINX Unit 1.10.0 adds some axle grease to improve integration with the latest Node.js versions; a few compatibility bugs were fixed as well.
Another significant update to language support is the PHP module’s new ability to parse request URIs into the
PATH_INFO
environment variable – something many PHP developers
have come to rely on. The change might appear tiny, but it makes it easier to run some major apps like NextCloud, as detailed in the shiny new
how‑to we’ve provided for your convenience. Oh, and speaking of…
Documentation
Our
documentation has been extended significantly in the last few months with various guides and how‑tos in response to your insightful queries, friendly GitHub rants, and reasonable – but misplaced – assumptions about how some features work.
Some of the major updates include a
guide to running NGINX Unit in Docker that is accompanied by a sample Dockerfile for each of the supported languages, an
end-to-end guide on language module manipulation, and how‑tos for popular apps and frameworks like
Catalyst and
Redmine (along with the aforementioned
NextCloud). There’s more to come – please check the docs once in a while or post your “gotta see this app run on NGINX Unit” ideas on GitHub.
Conclusion
The journey continues, and NGINX Unit is gaining momentum. Our team is steadily growing with new people bringing new ideas, so follow us for more exciting news (which we already have in the works): see the recent updates in the
changelog or monitor our
GitHub repository to join the discussions and development.
Finally, a few words about future updates. At this moment, we are working hard to bring to life such long‑promised features as WebSocket support for Java, serving static assets, and proxying. Our team is quite serious about making NGINX Unit a really busy little web engine. Stay tuned!
Interested in becoming a full‑time engineer for NGINX? Check our
job board.