Try running Nginx Unit on CentOS7
table of contents
Hello.
I'm Mandai, in charge of Wild on the development team.
Everyone's favorite new family of Nginx, "Nginx Unit", was introduced a while ago.
I did some research on how to use Nginx Unit.
table of contents
- What is Nginx Unit?
- Installation method
- Start the service for now
- Check Nginx Unit settings
- Change Nginx Unit settings
- Delete Nginx Unit settings
- summary
What is Nginx Unit?
Nginx Unit, like Nginx, is middleware that acts as a web application server.
Here are the features of Nginx Unit:
- Configuration files can be modified dynamically (no restart required)
- A single Nginx can run services for multiple programming languages
It is said that there is a point.
This time, I would like to actually install it and get a feel for it.
Installation method
In the case of CentOS, installation is possible via yum, so it is very easy.
just followed the steps in the official documentation
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
The preliminary preparations are now complete.
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 --> Performing transaction confirmation. ---> Installing package unit.x86_64 0:0.1-1.el7.ngx --> Processing dependencies: package for libphp5-5.4.so()(64bit): unit-0.1-1. el7.ngx.x86_64 --> Performing transaction confirmation. ---> Installing package php-embedded.x86_64 0:5.4.16-42.el7 --> Processing dependency: php-common(x86-64) = 5.4.16-42.el7 Package: php-embedded-5.4.16-42.el7.x86_64 --> Performing transaction confirmation. ---> Installing package php-common.x86_64 0:5.4.16-42.el7 --> Processing dependencies: Package for libzip.so.2()(64bit): php-common- 5.4.16-42.el7.x86_64 --> Performing transaction confirmation. ---> Installed package libzip.x86_64 0:0.10.1-8.el7 --> Finished dependency resolution. Dependency 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/ ------------- -------------------------------------------------- ------- Verifying: php-embedded-5.4.16-42.el7.x86_64 1/4 Verifying: libzip-0.10.1-8.el7.x86_64 2/4 Verifying: php-common- 5.4.16-42.el7.x86_64 3/4 Verifying: unit-0.1-1.el7.ngx.x86_64 4/4 Installing: 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 that PHP (and Ver. 5!) comes up in the dependency check (probably because it also provides the execution environment, it is pulled from the base repository).
If you already have PHP installed, or if you want to use it in a PHP7 environment, the source installation seems better.
In the case of source installation, it is necessary to prepare and compile a library according to the execution environment.
Especially when using PHP7, it may be difficult to install using yum, so please try following these
Start the service for now
At the end of the previous yum installation screen, there was a command to start the service, so let's try running this first.
Although CentOS7 is required, it is written using the service command, so I will show you the systemctl command that I recently learned!
# First, start the service sudo systemctl start unitd # Restoring 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 rewrite it to the systemctl command, so I simply used the service command.
By the way, if you run the first command as the service command, it will look like this:
sudo service unitd start Redirecting to /bin/systemctl start unitd.service
It runs properly, but it keeps telling me that it was executed with the systemctl command.
However, when I executed it with restoreconfig attached, there were no such notes at all, so I wonder if the service command is the correct method? I feel like that.
If you have done this so far, it has started normally, so you can check the operation with the curl command... But here is the point, in the case of Nginx, the above commands are executed in the reverse order. .
Nginx always requires a restart when the configuration file is updated, so there will inevitably be situations where it is difficult to change settings during operation.
It might be easy to ignore it, but this is the moment when you can get a glimpse of the benefits of Nginx Unit.
Now let's 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 operating as a normal web server, and phpinfo() is being executed.
I'm not sure about port 8400 at this point, but it looks like it's displaying the execution environment settings.
The mystery of this port will be explained later.
It looks like the installation was successful, so let's check the settings next.
Check Nginx Unit settings
For now, the only Nginx Unit configuration file that appears is /usr/share/doc/unit/examples/example.config, so let's take a look at it.
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, it was a JSON file.
If it is a JSON file, the configuration structure is easy to understand.
The true identity of "http://localhost:8400" that appeared earlier seems to be the standby URL for the python program.
If you read the documentation, you will be able to check the settings via socket communication.
It's like this.
curl --unix-socket /path/to/socket http://localhost/
However, in order to do that, we need to know the location of the socket file, so I would like to follow this area from the process side.
First, identify the Nginx Unit process using the ps command.
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 in three processes: daemon, controller, and router.
It may increase or decrease depending on the settings, but for now it is set up like this.
Next, use the lsof command to check the file held by process 5821.
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 25 3, 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
Apparently "/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" } } }
I feel like checking the web server settings with the curl command is quite new, but the content returned is the same as "/usr/share/doc/unit/examples/example.config" .
This means that the test configuration file has been successfully loaded.
Next, I would like to change the settings.
Change Nginx Unit settings
Looking at
the official documentation Quoting from the documentation,
# 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
When applying the first JSON file, I was able to understand it easily, but the second setting method is difficult.
You can only apply JSON to a part, but you can specify which part to apply using the URL...! !
I would also like to try a test that reads a JSON file that I created myself.
I simply prepared a JSON file like the one below.
{
"type": "php",
"user": "nobody",
"workers": 4,
"root": "/var/www/html",
"index": "index.php"
}
This is a simple setting to make the document root under "/var/www/html", but will it work?
Save this file as "/home/hogehoge/test-php.json".
Let's send this to 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 seems that the registration was successful.
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, I would like to check whether the curl command works properly... By the way, if the Listener is not registered, it will not be routed, so I will also add a JSON file for routing.
{
"application": "test"
}
Register the above JSON using curl 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 normally not possible, but strictly speaking it is not a URL, so don't worry about it too much.
If 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" } } }
It seems that the settings are reflected properly.
When I checked
"http://localhost:8301" using the curl command or browser (There was content developed with fuelPHP under this document root, but there was no problem).
Delete Nginx Unit settings
For changes, the curl HTTP method is sent using PUT, so for deletion, of course, the DELETE method is used.
Even if you don't look at the official documentation, it seems like you'll get the hang of it, but let's check this just to be sure.
The curl command for deletion using curl is as follows.
curl -X DELETE --unix-socket ./control.unit.sock \ 'http://localhost/listeners/*:8400'
I would like to delete the Listener settings that I added earlier.
curl -X DELETE --unix-socket /var/run/control.unit.sock http://localhost/listeners/*:8301 { "success": "Reconfiguration done." }
Yes, it looks like you were able to delete it successfully.
This part is very easy.
By the way, since both input and output are JSON, saving settings is also very easy.
# Write the curl result to a file curl --unix-socket /var/run/control.unit.sock http://localhost/ > /path/to/unitd.conf.json # Check if it can be written 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 # When you check the settings, there is nothing in them curl --unix-socket /var/ run/control.unit.sock http://localhost/ { "listeners": {}, "applications": {} } # Insert 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 also describes the combination of performing a reverse proxy with Nginx and sending requests to Nginx Unit via socket communication, and that it is too easy to rewrite settings to use alone, and that settings are not reflected at startup. However, I think it is a good complement to the inflexibility of Nginx.
The version is 0.1.
Beta version of course.
I'm looking forward to seeing how it will be refined in the future.
That's it.