Chapter 4. Usage and Operations

Understanding how to start and stop the NGINX Unit server, and the applications it runs, is essential. In this chapter, you will learn how to start and stop the Unit service on init.d and systemd service managers, as well as how to start the Unit server in the foreground. This chapter also details how to submit the configuration objects to the Unit control API in order to start serving the application.

4.1 Startup and Shutdown

Problem

You need to start or stop the NGINX Unit server.

Solution

When Unit is installed through a repository, a startup file for a service manager such as init.d or systemd is also installed and configured. These service managers will start Unit as a daemon.

Start Unit on an init.d system:

sudo /etc/init.d/unit start

Stop Unit on an init.d system:

sudo /etc/init.d/unit stop

Start Unit on a systemd system:

sudo systemctl start unit

Stop Unit on a systemd system:

sudo systemctl stop unit

Start Unit in the foreground. The following assumes that the Unit binary is installed into a directory defined in your PATH:

sudo unitd --no-daemon

Discussion

The service manager used to start the Unit daemon depends on the type of system it’s running on. Each service manager has its own syntax for starting and stopping services. The service managers will start Unit as a daemon. An example of starting Unit in the foreground is also shown. This can be useful for testing or when running Unit in a Docker container.

4.2 Applying Configuration

Problem

You need to alter the NGINX Unit configuration through the control interface.

Solution

For this section, it’s important to understand that the Unit configuration is represented as a single JSON object. Portions of the object can be interacted with in a RESTful manner. The following are examples of working with specific application and listener objects, and then with the Unit config as a whole.

Locate the Unit control socket; example output is provided. The default value found in this example, /var/run/control.unit.sock, will be used throughout the book. As the control socket is owned by root by default, all curl commands will be run with sudo:

unitd -h

unit options:

  --version            print unit version and configure options

  --no-daemon          run unit in non-daemon mode

  --control ADDRESS    set address of control API socket
                       default: "unix:/var/run/control.unit.sock"
  ...
  ...

Create an application by submitting an application object to the control socket:

sudo curl -X PUT -d @/path/to/application-object.json \
       --unix-socket /var/run/control.unit.socket \
       http://localhost/config/applications/my-app
Warning

In accordance to REST standard, a PUT request overwrites prior configurations that might have been previously defined for a given entity.

Configure a listener to send requests to the application:

sudo curl -X PUT \
       -d '{"*:8080":{"pass":"applications/my-app"}}' \
       --unix-socket /var/run/control.unit.socket \
       http://localhost/config/listeners

Figure 4-1 depicts the routing at this point.

Figure 4-1. Simple NGINX Unit configuration

Configure a route object named main to match /wiki/* and serve static files from /var/www/static/:

sudo curl -X PUT \
       -d '{
         "main":[
           {
             "match":{"uri":"/wiki/*"},
             "action":{"share":"/var/www/static/"}
           }
         ]
       }' \
       --unix-socket /var/run/control.unit.socket \
       http://localhost/config/routes

Append specifically to the route array named main, with a POST method to the routes/main entity, that will direct all other traffic to the application:

sudo curl -X POST \
       -d '{"action":{"pass":"applications/my-app"}}' \
       --unix-socket /var/run/control.unit.socket \
       http://localhost/config/routes/main

Set the listener object to direct traffic at the route, rather than the application:

sudo curl -X PUT \
       -d '"routes/main"' \
       --unix-socket /var/run/control.unit.socket \
       'http://localhost/config/listeners/*:8080/pass'

Figure 4-2 depicts the routing at this point.

Figure 4-2. Simple NGINX Unit configuration

Use the GET method to retrieve and save the entire configuration to a file named config.json:

sudo curl \
       --unix-socket /var/run/control.unit.socket \
       http://localhost/config/ \
       -o config.json

Your config.json file should look similar to the following:

{
    "listeners": {
        "*:8080": {
            "pass": "routes/main"
        }
    },
    "routes": {
        "main": [
            {
                "match": {
                    "uri": "/wiki/*"
                },
                "action": {
                    "share": "/var/www/static/"
                }
            },
            {
                "action": {
                    "pass": "applications/my-app"
                }
            }
        ]
    },
    "applications": {
        "my-app": {
            "type": "php",
            "processes": 5,
            "root": "/var/www/app/",
            "index": "index.php"
        }
    }
}

Alternatively, you can create all of these objects at once by applying the entire configuration file with a PUT method:

sudo curl -X PUT -d @config.json  \
       --unix-socket /var/run/control.unit.sock \
       http://localhost/config/
Warning

This command removes all other listeners, apps, and routes that might have been defined previously.

Test your application:

curl localhost:8080
curl localhost:8080/wiki/somefile

Discussion

All interactions with Unit are done through the control interface. The API is RESTful; applications and configurations are created, altered, or deleted through the API. In the examples for this solution, we build on the examples from Chapter 3 by submitting them to the Unit control interface. Throughout the example, you created an application, a listener, and a route. You then updated the route and the listener. By using a GET method, you retrieved the entire configuration of the running NGINX Unit server and saved it to a configuration file. Finally, you used the returned configuration file to set all configurations at once with a single HTTP request to the control interface.

It is important to note what each HTTP method will do to a given entity targeted by the API RESTful endpoint. A GET will return the configuration or value for a targeted entity. A PUT will set the configuration or value for a given entity, overwriting what was previously configured. A POST will append to a configuration array. A DELETE will delete the entity and return a status message.

4.3 Limits

Problem

You need to limit the number of requests an application will process before being respawned as well as the amount of time it has to respond before timing out.

Solution

Use the limits option of an application object:

{
    "listeners": {
        "*:8080": {
            "pass": "applications/app-name"
        }
    },
    "applications": {
        "app-name": {
            "type": "php",
            "processes": 5,
            "root": "/var/www/app/",
            "index": "index.php",
            "limits": {
                "timeout": 10,
                "requests": 10000
            }
        }
    }
}

Discussion

The limits option takes an object that is comprised of one or two options. The timeout option configures how long in seconds NGINX Unit will wait for a request before timing out and returning an error to the user. The requests option defines how many requests an application process can serve before being restarted. Restarting a process after a certain number of requests is helpful for applications that have memory leaks.

Get NGINX Unit Cookbook now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.