NGINX Unit

Building From Source§

After you’ve obtained Unit’s source code, configure and compile it to fine-tune and run a custom Unit build.

Installing Required Software§

Before configuring and compiling Unit, install the required build tools and the library files for the required languages and all other features you want in your Unit, such as TLS or regular expressions.

The commands below assume you are configuring Unit with all supported languages and features (X, Y, and Z denote major, minor, and revision numbers, respectively); omit the packages you won’t use.

# apt install build-essential
# apt install golang
# apt install curl && \
      curl -sL https://deb.nodesource.com/setup_VERSION.x | bash - && \
      apt install nodejs
# npm install -g node-gyp
# apt install php-dev libphp-embed
# apt install libperl-dev
# apt install pythonX-dev
# apt install ruby-dev ruby-rack
# apt install openjdk-X-jdk
# apt install libssl-dev
# apt install libpcre2-dev
# yum install gcc make
# yum install golang
# yum install curl && \
      curl -sL https://rpm.nodesource.com/setup_VERSION.x | bash - && \
      yum install nodejs
# npm install -g node-gyp
# yum install php-devel php-embedded
# yum install perl-devel perl-libs
# yum install pythonX-devel
# yum install ruby-devel rubygem-rack
# yum install java-X.Y.Z-openjdk-devel
# yum install openssl-devel
# yum install pcre2-devel

Ports:

# cd /usr/ports/lang/go/ && make install clean
# cd /usr/ports/www/node/ && make install clean
# cd /usr/ports/www/npm/ && make install clean && npm i -g node-gyp
# cd /usr/ports/lang/phpXY/ && make install clean
# cd /usr/ports/lang/perlX.Y/ && make install clean
# cd /usr/ports/lang/python/ && make install clean
# cd /usr/ports/lang/rubyXY/ && make install clean
# cd /usr/ports/java/openjdkX/ && make install clean
# cd /usr/ports/security/openssl/ && make install clean
# cd /usr/ports/devel/pcre2/ && make install clean

Packages:

# pkg install go
# pkg install node && pkg install npm && npm i -g node-gyp
# pkg install phpXY
# pkg install perlX
# pkg install python
# pkg install rubyXY
# pkg install openjdkX
# pkg install openssl
# pkg install pcre2
# pkg install gcc
# pkg install golang
# pkg install php-XY
# pkg install ruby
# pkg install jdk-X
# pkg install openssl
# pkg install pcre

Also, use gmake instead of make when building and installing Unit on Solaris.

Enabling njs

To build Unit with njs support, download the njs code to the same parent directory as the Unit code.

0.8.2 is the latest version of njs that Unit supports. Make sure you are in the correct branch before configuring the binaries.

$ git clone https://github.com/nginx/njs.git
$ cd njs
$ git checkout -b 0.8.2 0.8.2

Next, configure and build the njs binaries. Make sure to use the --no-zlib and --no-libxml2 options to avoid conflicts with Unit’s dependencies:

$ ./configure --no-zlib --no-libxml2 && make

Point to the resulting source and build directories when configuring the Unit code.

Enabling WebAssembly

To build Unit with support for the WebAssembly Component Model, you need rust version 1.76.0+, cargo and the developer package for clang as mentioned in the Required Software Section.

Next please refer to Configuring Modules - WebAssembly for further instructions.

Warning

The unit-wasm module is deprecated. We recommend using wasm-wasi-component instead, available in Unit 1.32.0 and later, which supports WebAssembly Components using standard WASI 0.2 interfaces.

To build Unit with the WebAssembly language module, you need the Wasmtime runtime. Download the C API files suitable for your OS and architecture to the same parent directory as the Unit code, for example:

$ cd ..
$ wget -O- https://github.com/bytecodealliance/wasmtime/releases/download/v12.0.0/wasmtime-v12.0.0-x86_64-linux-c-api.tar.xz \
      | tar Jxf -  # Unpacks to the current directory

Point to the resulting include and lib directories when configuring the Unit code.

To build WebAssembly apps that run on Unit, you need the wasi-sysroot SDK:

$ wget -O- https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sysroot-20.0.tar.gz | tar zxf -

When building the apps, add the following environment variable:

WASI_SYSROOT=/path/to/wasi-sysroot-dir/

Configuring Sources§

To run system compatibility checks and generate a Makefile with core build instructions for Unit:

$ ./configure COMPILE-TIME OPTIONS

Finalize the resulting Makefile by configuring the language modules you need before proceeding further.

General options and settings that control compilation, runtime privileges, or support for certain features:

--help

Displays a summary of common ./configure options.

For language-specific details, run ./configure <language> --help or see below.

--cc=pathname

Custom C compiler pathname.

The default is cc.

--cc-opt=options, --ld-opt=options Extra options for the C compiler and linker.
--group=name, --user=name

Group name and username to run Unit’s non-privileged processes.

The defaults are --user’s primary group and nobody, respectively.

--debug Turns on the debug log.
--no-ipv6 Turns off IPv6 support.
--no-unix-sockets Turns off UNIX domain sockets support for control and routing.
--openssl

Turns on OpenSSL support. Make sure OpenSSL (1.0.1+) header files and libraries are in your compiler’s path; it can be set with the --cc-opt and --ld-opt options or the CFLAGS and LDFLAGS environment variables when running ./configure.

For details of TLS configuration in Unit, see SSL/TLS certificates.

By default, Unit relies on the locally installed version of the PCRE library to support regular expressions in routes; if both major versions are present, Unit selects PCRE2. Two additional options alter this behavior:

--no-regex Turns off regex support; any attempts to use a regex in Unit configuration cause an error.
--no-pcre2 Ignores PCRE2; the older PCRE 8.x library is used instead.

Unit also supports the use of njs scripts in configuration; to enable this feature, use the respective option:

--njs Turns on njs support; requires --openssl.

When --njs is enabled, the --cc-opt and --ld-opt option values should point to the src/ and build/ subdirectories of the njs source code. For example, if you cloned the njs repo beside the Unit repo:

$ ./configure --njs --openssl \
              --cc-opt="-I../njs/src/ -I../njs/build/"  \
              --ld-opt="-L../njs/build/"  \
              ...

The next option group customizes Unit’s runtime directory structure:

--prefix=PREFIX

Destination directory prefix for path options: --bindir, --sbindir, --includedir, --libdir, --modulesdir, --datarootdir, --mandir, --localstatedir, --libstatedir, --runstatedir, --logdir, --tmpdir, --control, --pid, --log.

The default is /usr/local.

--exec-prefix=EXEC_PREFIX

Destination directory prefix for the executable directories only.

The default is the PREFIX value.

--bindir=BINDIR, --sbindir=SBINDIR

Directory paths for client and server executables.

The defaults are EXEC_PREFIX/bin and EXEC_PREFIX/sbin.

--includedir=INCLUDEDIR, --libdir=LIBDIR

Directory paths for libunit header files and libraries.

The defaults are PREFIX/include and EXEC_PREFIX/lib.

--modulesdir=MODULESDIR

Directory path for Unit’s language modules.

The default is LIBDIR/unit/modules.

--datarootdir=DATAROOTDIR, --mandir=MANDIR

Directory path for unitd(8) data storage and its subdirectory where the man page is installed.

The defaults are PREFIX/share and DATAROOTDIR/man.

--localstatedir=LOCALSTATEDIR

Directory path where Unit stores its runtime state, PID file, control socket, and logs.

The default is PREFIX/var.

--libstatedir=LIBSTATEDIR

Directory path where Unit’s runtime state (configuration, certificates, other resources) is stored between runs. If you migrate your installation, copy the entire directory.

Warning

The directory is sensitive and must be owned by root with 700 permissions. Don’t change its contents externally; use the config API to ensure integrity.

The default is LOCALSTATEDIR/run/unit.

--logdir=LOGDIR, --log=LOGFILE

Directory path and filename for Unit’s log.

The defaults are LOCALSTATEDIR/log/unit and LOGDIR/unit.log.

--runstatedir=RUNSTATEDIR

Directory path where Unit stores its PID file and control socket.

The default is LOCALSTATEDIR/run/unit.

--pid=pathname

Pathname for the PID file of Unit’s main process.

The default is RUNSTATEDIR/unit.pid.

--control=SOCKET

Control API socket address in IPv4, IPv6, or UNIX domain format:

$ ./configure --control=127.0.0.1:8080
$ ./configure --control=[::1]:8080
$ ./configure --control=unix:/path/to/control.unit.sock  # Note the unix: prefix

Warning

Avoid exposing an unprotected control socket in public networks. Use NGINX or a different solution such as SSH for security and authentication.

The default is unix:RUNSTATEDIR/control.unit.sock, created as root with 600 permissions.

--tmpdir=TMPDIR

Defines the temporary file storage location (used to dump large request bodies).

The default value is /tmp.

Directory Structure§

By default, make install installs Unit at the following pathnames:

Directory Default Path
bin directory /usr/local/bin/
sbin directory /usr/local/sbin/
lib directory /usr/local/lib/
include directory /usr/local/include/
tmp directory /tmp/
Man pages /usr/local/share/man/
Language modules /usr/local/lib/unit/modules/
Runtime state /usr/local/var/lib/unit/
PID file /usr/local/var/run/unit/unit.pid
Log file /usr/local/var/log/unit/unit.log
Control API socket unix:/usr/local/var/run/unit/control.unit.sock

The defaults are designed to work for most cases; to customize this layout, set the --prefix and its related options during configuration, defining the resulting file structure.

Configuring Modules§

Next, configure a module for each language you want to use with Unit. The ./configure <language> commands set up individual language modules and place module-specific instructions in the Makefile.

Note

To run apps in several versions of a language, build and install a module for each version. To package custom modules, see the module howto.

When you run ./configure go, Unit sets up the Go package that lets your applications run on Unit. To use the package, install it in your Go environment. Available configuration options:

--go=pathname

Specific Go executable pathname, also used in make targets.

The default is go.

--go-path=directory

Custom directory path for Go package installation.

The default is $GOPATH.

Note

Running ./configure go doesn’t alter the GOPATH environment variable, so configure-time --go-path and compile-time $GOPATH must be coherent for Go to find the resulting package.

$ GOPATH=<Go package installation path> GO111MODULE=auto go build -o app app.go

When you run ./configure java, the script configures a module to support running Java Web Applications on Unit. Available command options:

--home=directory

Directory path for Java utilities and header files to build the module.

The default is the java.home setting.

--jars=directory

Directory path for Unit’s custom .jar files.

The default is the Java module path.

--lib-path=directory

Directory path for the libjvm.so library.

The default is based on JDK settings.

--local-repo=directory

Directory path for the local .jar repository.

The default is $HOME/.m2/repository/.

--repo=directory

URL path for the remote Maven repository.

The default is http://central.maven.org/maven2/.

--module=basename

Resulting module’s name (<basename>.unit.so), also used in make targets.

The default is java.

To configure a module called java11.unit.so with OpenJDK 11.0.1:

$ ./configure java --module=java11  \
                   --home=/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home

When you run ./configure nodejs, Unit sets up the unit-http module that lets your applications run on Unit. Available configuration options:

--local=directory

Local directory path where the resulting module is installed.

By default, the module is installed globally (recommended).

--node=pathname

Specific Node.js executable pathname, also used in make targets.

The default is node.

--npm=pathname

Specific npm executable pathname.

The default is npm.

--node-gyp=pathname

Specific node-gyp executable pathname.

The default is node-gyp.

When you run ./configure perl, the script configures a module to support running Perl scripts as applications on Unit. Available command options:

--perl=pathname

Specific Perl executable pathname.

The default is perl.

--module=basename

Resulting module’s name (<basename>.unit.so), also used in make targets.

The default is the filename of the --perl executable.

To configure a module called perl-5.20.unit.so for Perl 5.20.2:

$ ./configure perl --module=perl-5.20  \
                   --perl=perl5.20.2

When you run ./configure php, the script configures a custom SAPI module linked with the libphp library to support running PHP applications on Unit. Available command options:

--config=pathname

Pathname of the php-config script used to set up the resulting module.

The default is php-config.

--lib-path=directory

Directory path of the libphp library file (libphp*.so or libphp*.a), usually available with an --enable-embed PHP build:

$ php-config --php-sapis

      ... embed ...
--lib-static Links the static libphp library (libphp*.a) instead of the dynamic one (libphp*.so); requires --lib-path.
--module=basename

Resulting module’s name (<basename>.unit.so), also used in make targets.

The default is --config’s filename minus the -config suffix; thus, --config=/path/php7-config yields php7.unit.so.

To configure a module called php70.unit.so for PHP 7.0:

$ ./configure php --module=php70  \
                  --config=/usr/lib64/php7.0/bin/php-config  \
                  --lib-path=/usr/lib64/php7.0/lib64

When you run ./configure python, the script configures a module to support running Python scripts as applications on Unit. Available command options:

--config=pathname

Pathname of the python-config script used to set up the resulting module.

The default is python-config.

--lib-path=directory Custom directory path of the Python runtime library to use with Unit.
--module=basename

Resulting module’s name (<basename>.unit.so), also used in make targets.

The default is --config’s filename minus the -config suffix; thus, /path/python3-config turns into python3.

Note

The Python interpreter set by python-config must be compiled with the --enable-shared option.

To configure a module called py33.unit.so for Python 3.3:

$ ./configure python --module=py33  \
                     --config=python-config-3.3

When you run ./configure ruby, the script configures a module to support running Ruby scripts as applications on Unit. Available command options:

--module=basename

Resulting module’s name (<basename>.unit.so), also used in make targets.

The default is the filename of the --ruby executable.

--ruby=pathname

Specific Ruby executable pathname.

The default is ruby.

To configure a module called ru23.unit.so for Ruby 2.3:

$ ./configure ruby --module=ru23  \
                   --ruby=ruby23

When you run ./configure wasm-wasi-component, the script configures a module to support running WebAssembly components on Unit.

The module doesn’t accept any extra configuration parameters. The module’s basename is wasm-wasi-component.

Warning

Unit 1.32.0 and later support the WebAssembly Component Model and WASI 0.2 APIs. We recommend using the new implementation.

When you run ./configure wasm, the script configures a module to support running WebAssembly applications on Unit. Available command options:

--module=basename Resulting module’s name (<basename>.unit.so), also used in make targets.
--runtime=basename

The WebAssembly runtime to use.

The default is wasmtime.

--include-path=path The directory path to the runtime’s header files.
--lib-path=path The directory path to the runtime’s library files.
--rpath=<path>

The directory path that designates the run-time library search path.

If specified without a value, assumes the --lib-path value.

To configure a module called wasm.unit.so:

$ ./configure wasm --include-path=/path/to/wasmtime/include  \
                   --lib-path=/path/to/wasmtime/lib \
                   --rpath

Building and Installing Unit§

To build and install Unit’s executables and language modules that you have ./configure’d earlier:

$ make
# make install

Mind that make install requires setting up Unit’s directory structure with ./configure first.

To run Unit from the build directory tree without installing:

$ ./configure --prefix=./build
$ make
$ ./build/sbin/unitd

You can also build and install language modules individually; the specific method depends on whether the language module is embedded in Unit (Java, Perl, PHP, Python, Ruby) or packaged externally (Go, Node.js).

Note

For further details about Unit’s language modules, see Working With Language Modules.

Embedded Language Modules§

To build and install the modules for Java, PHP, Perl, Python, or Ruby after configuration, run make <module basename> and make <module basename>-install, for example:

$ make perl-5.20
# make perl-5.20-install

External Language Modules§

To build and install the modules for Go and Node.js globally after configuration, run make <go>-install and make <node>-install, for example:

# make go-install
# make node-install

Note

To install the Node.js module locally, run make <node>-local-install:

# make node-local-install

If you haven’t specified the --local directory with ./configure nodejs earlier, provide it here:

# DESTDIR=/your/project/directory/ make node-local-install

If both options are specified, DESTDIR prefixes the --local value set by ./configure nodejs.

Finally, mind that global installation is preferable for the Node.js module.

If you customized the executable pathname with --go or --node, use the following pattern:

$ ./configure nodejs --node=/usr/local/bin/node8.12
# make /usr/local/bin/node8.12-install
$ ./configure go --go=/usr/local/bin/go1.7
# make /usr/local/bin/go1.7-install

Startup and Shutdown§

Warning

We advise installing Unit from precompiled packages; in this case, startup is configured automatically.

Even if you install Unit otherwise, avoid manual startup. Instead, configure a service manager (OpenRC, systemd, and so on) or create an rc.d script to launch the Unit daemon using the options below.

The startup command depends on the directories you set with ./configure, but their default values place the unitd binary in a well-known place, so:

# unitd RUNTIME OPTIONS

Run unitd -h or unitd --version to list Unit’s compile-time settings. Usually, the defaults don’t require overrides; still, the following runtime options are available. For their compile-time counterparts, see here.

--help, -h Displays a summary of the command-line options and their defaults.
--version Displays Unit’s version and the ./configure settings it was built with.
--no-daemon Runs Unit in non-daemon mode.
--control socket

Control API socket address in IPv4, IPv6, or UNIX domain format:

# unitd --control 127.0.0.1:8080
# unitd --control [::1]:8080
# unitd --control unix:/path/to/control.unit.sock
--control-mode Sets the permission of the UNIX domain control socket. Default: 0600
--control-user Sets the owner of the UNIX domain control socket.
--control-group Sets the group of the UNIX domain control socket.
--group name, --user name Group name and user name used to run Unit’s non-privileged processes.
--log pathname Pathname for Unit’s log.
--modules directory Directory path for Unit’s language modules (*.unit.so files).
--pid pathname Pathname for the PID file of Unit’s main process.
--state directory Directory path for Unit’s state storage.
--tmp directory Directory path for Unit’s temporary file storage.

Finally, to stop a running Unit:

# pkill unitd

This command signals all Unit’s processes to terminate in a graceful manner.