There are three main types of configuration objects used by NGINX Unit. All are defined with JSON. The application object defines characteristics of the application being run by Unit, such as the language, the process controls, and the location on the filesystem. The listener object defines the Unit configuration that directs incoming requests on a defined IP address and port to a specified application. The route objects provide routing capabilities. The routing capabilities include routing to Unit applications, serving static files, proxying to external services, and load balancing over a pool of servers. This chapter will build a foundational understanding of these objects.
You need to understand the application object for a fundamental understanding of NGINX Unit.
Define an application object that describes an application on the system. Each application type has different attributes and options that can be applied. The following is a basic example of a PHP application object:
{
"applications"
:
{
"my-app"
:
{
"type"
:
"php"
,
"processes"
:
2
,
"root"
:
"/var/www/app/"
,
"index"
:
"index.php"
,
"user"
:
"app_user"
,
"group"
:
"app_group"
}
}
}
Every application deployed on NGINX Unit is defined by an application object. The application object, defined in JSON, specifies the application’s attributes. Each application type has its own required and optional attributes. A number of different application attributes control Unit process management and limitation. The type
attribute is the only process management attribute that is common and required across all applications; it defines the application language, such as PHP, Python, Golang, Ruby, or Perl. Other attributes include application process count limits; time limits; user, group, and environment variables; and working directory.
In the example, some of the attributes that can be applied to a PHP process are used, such as root
and index
. The application-specific attributes are focused on the entry point of the application, such as the directory of the project or the main executable file.
The processes
option shown in the example is set to a static number of 2
application processes. Optional attributes max
, spare
, and idle_timeout
are also valid for process control. The max
and spare
attributes represent an integer of the maximum number of processes and number of spare processes to keep on hand, respectively. The idle_timeout
attribute represents the number in seconds a process can stay idle before being killed if there is an excess of the number of spare processes.
You will learn how to apply application objects to the Unit configuration in the section Recipe 4.2.
Define a listener object to instruct Unit to listen for incoming requests on a provided IP and port:
{
"listeners"
:
{
"*:8080"
:
{
"pass"
:
"applications/my-app"
}
}
}
To instruct NGINX Unit to listen for incoming requests, a listener object must be defined. The listener object defines the application to which Unit will direct incoming requests. The listener object is the value, specified to a key that defines the IP and port. In the example, the *
is used for the IP address, thus instructing Unit to listen on all IP addresses assigned to the server. The listener object has two attributes: pass
and optionally tls
. The pass
attribute takes a string value that specifies the application, application target, route, or upstream to which requests will be directed. The example sends requests directly to an application named my-app
.
You will learn how to apply listener objects to the Unit configuration in the section Recipe 4.2.
The routes
attribute of the Unit configuration can be configured as an array of route steps or an object of named route arrays.
When an array of route steps is used as the value of the routes
attribute, the value provided to the pass
attribute is simply routes
, as in the following example:
{
"listeners"
:
{
"*:8080"
:
{
"pass"
:
"routes"
}
},
"routes"
:
[
{
"match"
:
{
"host"
:
"blog.example.com"
},
"action"
:
{
"pass"
:
"applications/blog"
}
},
{
"action"
:
{
"pass"
:
"applications/my-app"
}
}
]
}
Figure 3-1 depicts this simple routing example. Route steps are evaluated in the order of their appearance.
When an object of named route arrays is used as the value of the routes
attribute, the value provided to the pass
attribute must be routes/
followed by the named route, as in the following example:
{
"listeners"
:
{
"*:8080"
:
{
"pass"
:
"routes/main"
}
},
"routes"
:
{
"main"
:
[
{
"match"
:
{
"host"
:
[
"example.com"
,
"www.example.com"
]
},
"action"
:
{
"pass"
:
"applications/website"
}
},
{
"match"
:
{
"uri"
:
"/admin/*"
,
"scheme"
:
"https"
},
"action"
:
{
"pass"
:
"applications/admin"
}
}
]
}
}
Figure 3-2 depicts the routing of a scenario that merges these two route configuration examples, naming the first example route blog
.
This recipe demonstrates a couple of basic routes. A route step has two attributes: match
and action
. Both attributes have their own respective object types that have a number of configurable attributes.
The match
object has the following options: arguments
, cookies
, destination
, headers
, host
, method
, scheme
, source
, and uri
. With these options, you can identify a web request and direct it to the correct action. The only valid values for scheme
are http
or https
.
There are two types of match options: simple and compounding. The following are simple match options: destination
, host
, method
, source
, and uri
. These options match against a string pattern or an array of patterns. When specifying multiple options together in a single match object, they work as a logical AND. When an array of strings is used for one of these options, the match at the option level is evaluated as a logical OR.
A pattern can use wildcards, negations, or ranges. Wildcards (*
) prefixing, suffixing, and splitting the string are valid with the host
, method
, and uri
match options, as well as the IP portion of source
and destination
. Negations (!
) are also supported, but they must come at the beginning of an option value. Ranges, in the format {start_port}-{end_port}
, are supported for the IP and Port portions of the source
and destination
options. The option values patterns must be an exact match to the request for the action to take effect.
Compounding match options use an object of key-value pair attributes to define a match. The following options use the compounding match: arguments
, cookies
, and headers
. To match a request for a compounding match option, the request must match all of the attributes of the option. The key attribute names the particular argument, cookie, or header your request is trying to match. The value of the attribute behaves exactly like a simple type match option, accepting a string pattern or an array of string patterns.
The action
object takes the following options: pass
, share
, fallback
, proxy
, return
, and location
. The pass
action type routes the request to a given route, upstream, or application, where the share
serves static content from a given file path. The fallback
action is used in conjunction with a share
to reroute the request in the event a file requested is not found or cannot be accessed. Routes can be chained for more complex logic. The proxy
type will proxy the request to another HTTP server. The return attribute alone will return a status code. To redirect a request, the return
and location
attributes can be used together to return an HTTP status code and a redirect location.
The route steps in a given array are evaluated in order, and the first match takes action. If only the action
attribute, but no match
condition, is specified in a route, requests are unconditionally directed to the pass
, share
, or return
value. If no route is matched, an HTTP 404 is served.
Use the routes
attribute of the Unit configuration to specify a route object that uses a proxy
action type:
{
"listeners"
:
{
"*:8080"
:
{
"pass"
:
"routes"
}
},
"routes"
:
[
{
"match"
:
{
"uri"
:
"/wiki/*"
},
"action"
:
{
"proxy"
:
"http://172.17.0.1:80"
}
},
{
"action"
:
{
"pass"
:
"applications/my-app"
}
}
]
}
This example routes any request with a prefixed URI of /wiki/
to an external HTTP service hosted at http://172.17.0.1:80
, and all other requests to an application hosted by Unit.
The proxy
action type will relay the request to an external HTTP service. The capabilities of this action are that of a basic reverse proxy. You can use Unix, IPv4, and IPv6 socket addresses as targets. This Unit feature will fit many use cases. For more advanced features, you may look to the NGINX reverse proxy and load balancer server.
Use the routes
attribute of the Unit configuration to specify a route object that uses a share
action type:
{
"listeners"
:
{
"*:8080"
:
{
"pass"
:
"routes"
}
},
"routes"
:
[
{
"action"
:
{
"share"
:
"/var/www/static/"
,
"fallback"
:
{
"share"
:
"/var/app/static"
}
}
}
]
}
This example serves all requests out of a local file directory, /var/www/static/. If the file is not found, Unit will fall back to an alternate location, /var/app/static. When serving static content, a user
attribute is not specified as it is with applications. The files are accessed with the access rights of the user Unit runs as, usually root.
The share
action type will serve static content from a local directory. It can be used in conjunction with the fallback
action, which will tell Unit how to direct the request if the requested file is not found or if Unit has insufficient privileges to access it. The fallback
action can route requests to a pass
, proxy
, or share
action. When fallback
directs requests to another share
action, the fallback
actions can be nested.
Use the upstreams
attribute of the Unit configuration to define a pool of servers to load balance over:
{
"listeners"
:
{
"*:8080"
:
{
"pass"
:
"upstreams/pool-0"
}
},
"upstreams"
:
{
"pool-0"
:
{
"servers"
:
{
"10.0.0.2:8080"
:
{
},
"10.0.1.2:8080"
:
{
"weight"
:
2.0
}
}
}
}
}
This example will load balance between servers 10.0.0.2
and 10.0.1.2
, both of which listen on port 8080
. These two servers are defined as an upstream named pool-0
. The server at 10.0.1.2
will receive twice as many requests as 10.0.0.2
because of the weight
attribute.
The upstreams
attribute of the Unit configuration defines a number of named upstream objects. Each upstream object defines a servers
object. The servers
object uses keys to define the destination and uses the value to specify an optional weight
. The upstream uses a weighted round-robin load balancing algorithm. The maximum weight
value is 1000000
, the minimum is 0
(such servers receive no requests), and the default is 1
.
The load balancing capabilities of Unit are pretty basic but fit many use cases. For more advanced load balancing features, you should use the NGINX reverse proxy and load balancing server, which is described in Chapter 7.
Use the application attribute target
to provide a separate context within the same application:
{
"listeners"
:
{
"*:8080"
:
{
"pass"
:
"routes"
}
},
"routes"
:
[
{
"match"
:
{
"host"
:
"admin.example.com"
},
"action"
:
{
"pass"
:
"applications/my-app/admin"
}
},
{
"action"
:
{
"pass"
:
"applications/my-app/website"
}
}
],
"applications"
:
{
"my-app"
:
{
"type"
:
"php"
,
"targets"
:
{
"admin"
:
{
"index"
:
"admin.php"
,
"root"
:
"/var/www/admin"
},
"website"
:
{
"script"
:
"index.php"
,
"root"
:
"/var/www/"
}
}
}
}
}
This section took the route and application configurations to a deeper level. The application configuration has an attribute, targets
, that defines another layer of application context. A PHP application must have a root
and script
or index
attribute defined at either the application level or a target level. In the example, the admin
target has a different root directory than the website
target. The admin
target also allows all PHP files within the directory structure to be called, with admin.php
being the index. The website
target contains the admin
root directory; however, it only allows for the index.php script to be called. Up to 254 targets can be configured for an application. Routing to a target is done by simply appending to the application namespace with the name of the target.
3.21.76.0