{"id":32926,"date":"2019-09-17T00:53:24","date_gmt":"2019-09-16T15:53:24","guid":{"rendered":"https:\/\/jirak.net\/wp\/nginx-unit-1-10-0-is-now-available\/"},"modified":"2019-09-17T02:34:20","modified_gmt":"2019-09-16T17:34:20","slug":"nginx-unit-1-10-0-is-now-available","status":"publish","type":"post","link":"https:\/\/jirak.net\/wp\/nginx-unit-1-10-0-is-now-available\/","title":{"rendered":"NGINX Unit 1.10.0 Is Now Available"},"content":{"rendered":"<p>NGINX Unit 1.10.0 Is Now Available<\/p>\n<p>Summer&#8217;s gone, so it&#8217;s time to forfeit the halcyon tranquility and get some working attitude on. The NGINX&nbsp;Unit team has recently presented our first two&#8209;digit version, <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\" rel=\"noopener noreferrer\"><span>NGINX Unit 1.10.0<\/span><\/a>; let&#8217;s page through the recent developments and shed some light on our plans for the future.<\/p>\n<h2>Routing Advancements<\/h2>\n<p>In our two latest releases, some major effort went into extending the request routing capabilities that were initially <a href=\"https:\/\/www.nginx.com\/blog\/nginx-unit-1-8-0-now-available\/\">introduced in <span>NGINX Unit 1.8.0<\/span><\/a>. Version&nbsp;1.9.0 included essential support for arguments, headers, and cookies in matching clauses, whereas <span>NGINX Unit 1.10.0<\/span> added <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/configuration\/#condition-matching\" rel=\"noopener noreferrer\">scheme&#8209;based routing<\/a> to the mix. A few examples:<\/p>\n<pre><code class=\"config\">\"match\": {\r\n    \"host\": \"www.example.com\",\r\n    \"arguments\": {\r\n        \"mode\": [\"mobile\", \"desktop\"],\r\n        \"ui\": \"!full\"\r\n    }\r\n}<\/code><\/pre>\n<p>This condition matches queries like <strong>www.example.com\/?mode=mobile<\/strong> and <strong>www.example.com\/?mode=desktop&#038;ui=compact<\/strong>, but not <strong>www.example\/com\/?mode=desktop&#038;ui=full<\/strong>.<\/p>\n<pre><code class=\"config\">\"match\": {\r\n    \"headers\": [\r\n        {\r\n            \"Accept-Encoding\": \"*gzip*\",\r\n            \"User-Agent\": \"Mozilla\/5.0*\"\r\n        },\r\n\r\n        {\r\n            \"User-Agent\": \"curl*\"\r\n        }\r\n    ]\r\n}<\/code><\/pre>\n<p>This clause matches only requests where the <span><code>User-Agent<\/code><\/span> header is either <code>Mozilla\/5.0<\/code> (and <code>gzip<\/code> compression is also applied) or <code>curl<\/code>.<\/p>\n<pre><code class=\"config\">\"match\": {\r\n    \"host\": \"example.com\",\r\n    \"scheme\": \"https\"\r\n}<\/code><\/pre>\n<p>This condition matches <strong>https:\/\/example.com<\/strong>, but not <strong>http:\/\/example.com<\/strong>.<\/p>\n<p>Pattern matching was also extended to allow wildcards in the middle of the match string: <\/p>\n<pre><code class=\"config\">\"match\": {\r\n    \"host\": [\"eu-*.example.com\", \"!eu-5.example.com\"]\r\n}<\/code><\/pre>\n<p>This clause happily matches all <strong>eu-<\/strong> subdomains of <strong>example.com<\/strong> except <span style=\"font-weight:bold\">eu-5.example.com<\/span>.<\/p>\n<h2>Configuration Updates<\/h2>\n<p>The <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/configuration\/#configuration-management\" rel=\"noopener noreferrer\">config API<\/a> received some polishing as well. Most importantly, it now supports non&#8209;idempotent <code>POST<\/code> semantics. In less fancy terms, this means you can append new items to arrays, which do occur in NGINX&nbsp;Unit configuration. For instance, consider this sample output from a <code>curl<\/code> query to NGINX&nbsp;Unit&#8217;s control socket:<\/p>\n<pre><code class=\"terminal\"># <span style=\"color:#66ff99;font-weight: bold\">curl --unix-socket \/path\/to\/control.unit.sock http:\/\/localhost\/config\/<\/span>\r\n\r\n{\r\n    \"listeners\": {\r\n        \"*:8000\": {\r\n            \"pass\": \"routes\"\r\n        }\r\n    },\r\n\r\n    \"applications\": {\r\n        \"blogs\": {\r\n            \"type\": \"python\",\r\n            \"module\": \"wsgi\",\r\n            \"path\": \"\/www\/blogs\/\"\r\n        }\r\n    },\r\n\r\n    \"routes\": [\t\r\n        {\r\n            \"match\": {\r\n                \"host\": [\r\n                    \"dev1.example.com\",\r\n                    \"dev2.example.com\"\r\n                ]\r\n            },\r\n\r\n            \"action\": {\r\n                \"pass\": \"applications\/blogs\"\r\n            }\r\n        }\r\n    ]\r\n}<\/code><\/pre>\n<p>Let&#8217;s decipher the JSON: the configuration includes an application called <code>blogs<\/code>, a <code>routes<\/code> section that allows access to the app via two hostnames, and a listener that passes incoming requests through the routing engine. Using the <code>POST<\/code> method, we append a new hostname to the <code>host<\/code> array:<\/p>\n<pre><code class=\"terminal\"># <span style=\"color:#66ff99;font-weight: bold\">curl -X POST -d '\"dev3.example.com\"' --unix-socket=\/path\/to\/control.unit.sock \r\n       http:\/\/localhost\/config\/routes\/0\/match\/host\/<\/span>\r\n{\r\n    \"success\": \"Reconfiguration done.\"\r\n}<\/code><\/pre>\n<p>Note that all responses from NGINX&nbsp;Unit are also encoded in JSON. Next, I make a <code>curl<\/code> query to display just the <code>routes<\/code> section:<\/p>\n<pre><code class=\"terminal\"># <span style=\"color:#66ff99;font-weight: bold\">curl --unix-socket \/path\/to\/control.unit.sock http:\/\/localhost\/config\/routes\/<\/span>\r\n\r\n[\t\r\n    {\r\n        \"match\": {\r\n            \"host\": [\r\n                \"dev1.example.com\",\r\n                \"dev2.example.com\",\r\n                \"dev3.example.com\"\r\n            ]\r\n        },\r\n\r\n        \"action\": {\r\n            \"pass\": \"applications\/blogs\"\r\n        }\r\n    }\r\n]<\/code><\/pre>\n<p>As you can see, the <code>POST<\/code> operation appended its payload to the end of the <code>host<\/code> array. It&#8217;s worth mentioning here that NGINX&nbsp;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!<\/p>\n<p>In other news, we&#8217;ve also done away with a few nasty bugs, making config manipulation more reliable.<\/p>\n<h2>Application Languages<\/h2>\n<p>Most of the latest changes in language support are for Node.js, including a new built&#8209;in WebSocket server implementation in <span>NGINX Unit 1.10.0<\/span>. To use it, just specify our module as the parameter to the <code>require<\/code> function instead of the native <code>websocket<\/code> module:<\/p>\n<pre><code class=\"config\">var webSocketServer = require('unit-http\/websocket').server;<\/code><\/pre>\n<p>In addition, <span>NGINX Unit 1.10.0<\/span> adds some axle grease to improve integration with the latest Node.js versions; a few compatibility bugs were fixed as well.<\/p>\n<p>Another significant update to language support is the PHP module&#8217;s new ability to parse request URIs into the <code>PATH_INFO<\/code> environment variable&nbsp;&ndash; something many PHP developers <a target=\"_blank\" href=\"https:\/\/www.php.net\/manual\/en\/reserved.variables.server.php\" rel=\"noopener noreferrer\">have come to rely on<\/a>. The change might appear tiny, but it makes it easier to run some major apps like NextCloud, as detailed in the shiny new <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/howto\/nextcloud\/\" rel=\"noopener noreferrer\">how&#8209;to<\/a> we&#8217;ve provided for your convenience. Oh, and speaking of&#8230;<\/p>\n<h2>Documentation<\/h2>\n<p>Our <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\" rel=\"noopener noreferrer\">documentation<\/a> has been extended significantly in the last few months with various guides and how&#8209;tos in response to your insightful queries, friendly GitHub rants, and reasonable&nbsp;&ndash; but misplaced&nbsp;&ndash; assumptions about how some features work.<\/p>\n<p>Some of the major updates include a <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/howto\/docker\/\" rel=\"noopener noreferrer\">guide<\/a> to running NGINX&nbsp;Unit in Docker that is accompanied by a sample Dockerfile for each of the supported languages, an <span>end-to-end<\/span> <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/howto\/modules\/\" rel=\"noopener noreferrer\">guide<\/a> on language module manipulation, and how&#8209;tos for popular apps and frameworks like <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/howto\/catalyst\/\" rel=\"noopener noreferrer\">Catalyst<\/a> and <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/howto\/redmine\/\" rel=\"noopener noreferrer\">Redmine<\/a> (along with the aforementioned <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/howto\/nextcloud\/\" rel=\"noopener noreferrer\">NextCloud<\/a>). There&#8217;s more to come&nbsp;&ndash; please check the docs once in a while or post your &#8220;gotta see this app run on NGINX&nbsp;Unit&#8221; ideas on GitHub.<\/p>\n<h2>Conclusion<\/h2>\n<p>The journey continues, and NGINX&nbsp;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 <a target=\"_blank\" href=\"https:\/\/unit.nginx.org\/CHANGES.txt\" rel=\"noopener noreferrer\">changelog<\/a> or monitor our <a target=\"_blank\" href=\"https:\/\/github.com\/nginx\/unit\/\" rel=\"noopener noreferrer\">GitHub repository<\/a> to join the discussions and development.<\/p>\n<p>Finally, a few words about future updates. At this moment, we are working hard to bring to life such long&#8209;promised features as WebSocket support for Java, serving static assets, and proxying. Our team is quite serious about making NGINX&nbsp;Unit a really busy little web engine. Stay tuned!<\/p>\n<p>Interested in becoming a full\u2011time engineer for NGINX? Check our <a target=\"_blank\" href=\"https:\/\/ffive.wd5.myworkdayjobs.com\/NGINX\" rel=\"noopener noreferrer\">job board<\/a>.<\/p>\n<p>NGINX&nbsp;Plus subscribers get support for NGINX&nbsp;Unit at no additional charge. <a href=\"https:\/\/www.nginx.com\/free-trial-request\/\">Start a free 30&#8209;day trial<\/a> of NGINX&nbsp;Plus today.<\/p>\n<p>The post <a rel=\"nofollow\" href=\"https:\/\/www.nginx.com\/blog\/nginx-unit-1-10-0-now-available\/\">NGINX Unit 1.10.0 Is Now Available<\/a> appeared first on <a rel=\"nofollow\" href=\"https:\/\/www.nginx.com\">NGINX<\/a>.<\/p>\n<p>Source: <a href=\"https:\/\/www.nginx.com\/blog\/nginx-unit-1-10-0-now-available\/\" target=\"_blank\" rel=\"noopener noreferrer\">NGINX Unit 1.10.0 Is Now Available<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>NGINX Unit 1.10.0 Is Now Available Summer&#8217;s gone, so it&#8217;s time to forfeit the halcyon tranquility and get some working attitude on. The NGINX&nbsp;Unit team has recently presented our first two&#8209;digit version, NGINX Unit 1.10.0; let&#8217;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&nbsp;1.9.0 included essential support for arguments, headers, and cookies in matching clauses, whereas NGINX Unit 1.10.0 added scheme&#8209;based routing to the mix. A few examples: &#8220;match&#8221;: { &#8220;host&#8221;: &#8220;www.example.com&#8221;, &#8220;arguments&#8221;: { &#8220;mode&#8221;: [&#8220;mobile&#8221;, &#8220;desktop&#8221;], &#8220;ui&#8221;: &#8220;!full&#8221; } } This condition matches queries like www.example.com\/?mode=mobile and www.example.com\/?mode=desktop&#038;ui=compact, but not www.example\/com\/?mode=desktop&#038;ui=full. &#8220;match&#8221;: { &#8220;headers&#8221;: [ { &#8220;Accept-Encoding&#8221;: &#8220;*gzip*&#8221;, &#8220;User-Agent&#8221;: &#8220;Mozilla\/5.0*&#8221; }, { &#8220;User-Agent&#8221;: &#8220;curl*&#8221; } ] <a class=\"mh-excerpt-more\" href=\"https:\/\/jirak.net\/wp\/nginx-unit-1-10-0-is-now-available\/\" title=\"NGINX Unit 1.10.0 Is Now Available\">[ more&#8230; ]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[169],"tags":[652],"class_list":["post-32926","post","type-post","status-publish","format-standard","hentry","category-news","tag-nginx"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/posts\/32926","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/comments?post=32926"}],"version-history":[{"count":1,"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/posts\/32926\/revisions"}],"predecessor-version":[{"id":32927,"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/posts\/32926\/revisions\/32927"}],"wp:attachment":[{"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/media?parent=32926"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/categories?post=32926"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jirak.net\/wp\/wp-json\/wp\/v2\/tags?post=32926"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}