Running Nginx Unit on CentOS 7

table of contents
Hello,
I'm Mandai, the Wild Team member of the development team.
Everyone loves the new Nginx family, "Nginx Unit," which was released a while ago
I did some research to find out how to use Nginx Unit
table of contents
- What is Nginx Unit?
- How to install
- First, start the service
- Check Nginx Unit configuration
- Change Nginx Unit settings
- Delete Nginx Unit Configuration
- summary
What is Nginx Unit?
Nginx Unit is a middleware that acts as a web application server, just like Nginx
The features of Nginx Unit are as follows:
- Dynamically modify the configuration file (no restart required)
- A single Nginx can run services in multiple programming languages
It is said that there is a place like this
This time, I'd like to actually install it and get a feel for what it's like
How to install
In the case of CentOS, it can be installed via yum, which is very easy
pretty much the official documentation , but let's install it anyway.
First, register the Nginx Unit repository
sudo vi /etc/yum.repos.d/unit.repo # Paste the following content [unit] name=unit repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=1
This completes the preparation.
Next, run the yum command.
yum install unit Loaded plugins:fastestmirror, langpacks Loading mirror speeds from cached hostfile * base: ftp.riken.jp * epel: mirror.dmmlabs.jp * extras: ftp.riken.jp * nux-dextop: li.nux.ro * remi-safe: mirror.bebout.net * updates: ftp.riken.jp Resolving dependencies --> Running transaction check ---> Installing package unit.x86_64 0:0.1-1.el7.ngx --> Processing dependencies: libphp5-5.4.so()(64bit) for package: unit-0.1-1.el7.ngx.x86_64 --> Running transaction check ---> Installing package php-embedded.x86_64 0:5.4.16-42.el7 --> Processing dependencies: php-common(x86-64) = 5.4.16-42.el7 for package: php-embedded-5.4.16-42.el7.x86_64 --> Running transaction check ---> Installing package php-common.x86_64 0:5.4.16-42.el7 --> Processing dependencies: libzip.so.2()(64bit) for package: php-common-5.4.16-42.el7.x86_64 --> Running transaction check ---> Installing package libzip.x86_64 0:0.10.1-8.el7 --> Dependency resolution finished. Dependencies resolved ~ Omitted ~ Thank you for installing NGINX Unit! You may want to load demo configuration and check a couple of apps: # service unitd start # service unitd restoreconfig /usr/share/doc/unit/examples/example.config # curl http://localhost:8300/ # curl http://localhost:8400/ Online documentation is available at http://unit.nginx.org/ ---------------------------------------------------------------------- Testing: php-embedded-5.4.16-42.el7.x86_64 1/4 Testing: libzip-0.10.1-8.el7.x86_64 2/4 Testing: php-common-5.4.16-42.el7.x86_64 3/4 Testing: unit-0.1-1.el7.ngx.x86_64 4/4 Installed: unit.x86_64 0:0.1-1.el7.ngx Installed dependencies: libzip.x86_64 0:0.10.1-8.el7 php-common.x86_64 0:5.4.16-42.el7 php-embedded.x86_64 0:5.4.16-42.el7 Done!
It's a mystery why PHP (Version 5, at that!) shows up in the dependency check (probably because it's being pulled from the base repository to provide the runtime environment as well).
If you already have PHP installed or want to use it in a PHP7 environment, a source install seems like a better option.
In the case of a source installation, you will need to prepare and compile libraries that match your environment.
Installing with yum seems particularly difficult when using PHP7, so please try following these
First, start the service
At the end of the yum installation screen, there was a command to start the service, so I'll try that first.
Even though it requires CentOS 7, it's written as the service command, so I'll show you the systemctl command, which I recently learned!
# First, start the service sudo systemctl start unitd # Restore the configuration file $ service unitd restoreconfig /usr/share/doc/unit/examples/example.config Restoring configuration from /usr/share/doc/unit/examples/example.config... { "success": "Reconfiguration done." }
For the second command, I had no idea how to convert it to a systemctl command, so I simply used the service command
By the way, if you run the first command as a service command, the result will be as follows
sudo service unitd start Redirecting to /bin/systemctl start unitd.service
It runs fine, but it keeps telling me that it was run with the systemctl command.
However, when I ran it with restoreconfig, there were no warning messages like this, so I'm wondering if the service command is the correct way to go.
If you've done this much, it should start up normally, so you might want to check it works with the curl command... but here's the key point: in Nginx, the execution order of the above commands is reversed.
When you update the configuration file in Nginx, a restart is always required, so there are inevitably situations where it's difficult to change the configuration during operation. This
is something that you might just brush over, but it's a moment when you can get a glimpse of the benefits of Nginx Unit.
Now try accessing the web server again
$ curl http://localhost:8300/phpinfo() [email protected] .
$ curl http://localhost:8400/ 2017-10-17 02:11:15 AM ENV Variables: LANG ja_JP.utf8 PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin UNITD_OPTIONS --log /var/log/unitd.log --pid /run/unitd.pid
Port 8300 seems to be running as a normal web server, with phpinfo() being executed.
Port 8400 is unclear at this point, but it appears to be displaying the runtime environment settings.
The mystery of this port will be explained later.
The installation seems to have gone well, so next we'll check the settings
Check Nginx Unit configuration
For now, the only thing that looks like an Nginx Unit configuration file is /usr/share/doc/unit/examples/example.config, so let's take a look at that
less /usr/share/doc/unit/examples/example.config { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }
When I opened the file, I found that it was a JSON file.
JSON files make it easy to understand the configuration structure.
It seems that the "http://localhost:8400" mentioned earlier is actually a standby URL for the Python program
After reading the documentation,
it seems
curl --unix-socket /path/to/socket http://localhost/
However, to do this, we need to know the location of the socket file, so we will look at this from the perspective of process activity
First, use the ps command to identify the Nginx Unit process
ps auxwwwf | grep [u]nit root 5821 0.0 0.0 18256 636 ? Ss 00:21 0:00 unit: main [/usr/sbin/unitd --log /var/log/unitd.log --pid /run/unitd.pid] nobody 5824 0.0 0.0 18256 680 ? S 00:21 0:00 \_ unit: controller nobody 5825 0.0 0.0 18256 680 ? S 00:21 0:00 \_ unit: router
Nginx Unit seems to be running with three processes: daemon, controller, and router.
Depending on the configuration, this may increase or decrease, but for now it is set up like this.
Next, use the lsof command to check the files that process 5821 is holding
lsof -p 5821 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME unitd 5821 root cwd DIR 253,0 4096 2 / unitd 5821 root rtd DIR 253,0 4096 2 / unitd 5821 root txt REG 253,0 397232 806046 /usr/sbin/unitd unitd 5821 root mem REG 253,0 37352 805753 /usr/lib64/libnss_sss.so.2 unitd 5821 root mem REG 253,0 62184 787847 /usr/lib64/libnss_files-2.17.so unitd 5821 root mem REG 253,0 2118128 787829 /usr/lib64/libc-2.17.so unitd 5821 root mem REG 253,0 143944 787855 /usr/lib64/libpthread-2.17.so unitd 5821 root mem REG 253,0 19776 787835 /usr/lib64/libdl-2.17.so unitd 5821 root mem REG 253,0 44448 787859 /usr/lib64/librt-2.17.so unitd 5821 root mem REG 253,0 1141928 787837 /usr/lib64/libm-2.17.so unitd 5821 root mem REG 253,0 155464 806682 /usr/lib64/ld-2.17.so unitd 5821 root 0u CHR 1,3 0t0 1028 /dev/null unitd 5821 root 1u CHR 1,3 0t0 1028 /dev/null unitd 5821 root 2w REG 253,0 258231 136119 /var/log/unitd.log unitd 5821 root 3u a_inode 0,9 0 5832 [eventpoll] unitd 5821 root 4u a_inode 0,9 0 5832 [signalfd] unitd 5821 root 5u a_inode 0,9 0 5832 [eventfd] unitd 5821 root 6u unix 0xffff8800783ba400 0t0 48362 /var/run/control.unit.sock # <- this unitd 5821 root 7w REG 253,0 258231 136119 /var/log/unitd.log unitd 5821 root 8u unix 0xffff880023ebb400 0t0 49423 socket unitd 5821 root 9u unix 0xffff880023ebb800 0t0 49424 socket unitd 5821 root 12u unix 0xffff8800b1954800 0t0 49428 socket unitd 5821 root 13u unix 0xffff880023eb9c00 0t0 49430 socket
It seems that "/var/run/control.unit.sock" is the socket file, so the command to check the settings is as follows
curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }
Checking the web server configuration with the curl command feels quite new to me, but the contents returned were the same as "/usr/share/doc/unit/examples/example.config".
This means that the test configuration file was successfully loaded.
Next, I'd like to change the settings
Change Nginx Unit settings
Looking at
the official documentation using
# Example: Create a Full Configuration curl -X PUT -d @/path/to/start.json \ --unix-socket ./control.unit.sock http://localhost/ # Example: Create an Application Object curl -X PUT -d @/path/to/wiki.json \ --unix-socket ./control.unit.sock http://localhost/applications/wiki
The first method of applying a JSON file was easy to understand, but the second method of setting it up is tricky.
You can apply only a part of the JSON, but you have to specify which part to apply using a URL...!!
I would also like to test reading a JSON file I created myself.
To make it simple, I prepared the following JSON file:
{
"type": "php",
"user": "nobody",
"workers": 4,
"root": "/var/www/html",
"index": "index.php"
}
This is a simple configuration that sets the document root to the common "/var/www/html" directory, but will it work?
Save this file as "/home/hogehoge/test-php.json".
Let's send this to the Nginx Unit using the curl command!
Add it directly under applications.
curl -X PUT -d @/home/hogehoge/test-php.json --unix-socket /var/run/control.unit.sock http://localhost/applications/test { "success": "Reconfiguration done." }
It looks like the registration was successful.
Let's also check the current settings.
curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }
It looks like it was added successfully.
Now, let's check if it works properly with the curl command... but since routing won't work unless the Listener is registered, we'll also add a JSON file for routing.
{
"application": "test"
}
We will register the above JSON using curl in the same way as before
curl -X PUT -d @/home/hogehoge/test-php-listener.json --unix-socket /var/run/control.unit.sock http://localhost/listeners/*:8301 { "success": "Reconfiguration done." }
The last URL is unlikely to be the case, but it's not a URL, so don't worry too much about it.
Once success is returned, check the entire configuration.
curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" }, "*:8301": { "application": "test" } } }
The settings seem to have been applied successfully.
" http://localhost:8301" using the curl command or in a browser, the page is displayed correctly.
(The content I had developed with fuelPHP remained under this document root, and there were no problems.)
Delete Nginx Unit Configuration
When making changes, you send the curl HTTP method PUT, so when deleting, you naturally use the DELETE method
You can probably figure it out without looking at the official documentation, but let's double-check.
The curl command to use to delete is as follows:
curl -X DELETE --unix-socket ./control.unit.sock \ 'http://localhost/listeners/*:8400'
Let's try deleting the Listener settings we added earlier
curl -X DELETE --unix-socket /var/run/control.unit.sock http://localhost/listeners/*:8301 { "success": "Reconfiguration done." }
Yes, it seems to have been successfully deleted
This part is very easy
By the way, since both the input and output are JSON, saving the settings is very easy
# Write the results of curl to a file curl --unix-socket /var/run/control.unit.sock http://localhost/ > /path/to/unitd.conf.json # Check that writing is possible cat /path/to/unitd.conf.json { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } } # Restart Nginx Unit systemctl restart unitd # Check the configuration, there is nothing entered curl --unix-socket /var/run/control.unit.sock http://localhost/ { "listeners": {}, "applications": {} } # Input the JSON data output to the file earlier curl -X PUT -d @/root/unitd.conf.json --unix-socket /var/run/control.unit.sock http://localhost { "success": "Reconfiguration done." } # Check if the settings are reflected curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }
It worked!
summary
What do you think of the promising newcomer, Nginx Unit?
The official documentation describes a combination where Nginx acts as a reverse proxy and sends requests to Nginx Unit via socket communication. The settings are too easy to rewrite and there are some quirks with the settings being reflected at startup to use it on its own, but I think it complements well the inflexible aspects of Nginx.
The version is 0.1.
Of course, it's still a beta version.
I'm looking forward to seeing how it will be refined in the future.
That's all
1