In some special cases, such as offline conditions, we cannot use the package manager and have to install a specific software manually, so it is recommended to compile and install it from the source code itself, usually in two steps configure + make install.

If we can only get a compiled program or do not have a compiled environment, we will have to perform the installation steps manually. This article will document how to install a compiled Nginx binary on a Linux system.

prefix configuration

The most important thing to note about installing nginx is the prefix path configuration, which defaults to /usr/local/nginx and is the base path for the nginx runtime.

  • nginx will look for the configuration file nginx.conf from this path.
  • The default values for other paths used by nginx are also based on this path, such as {prefix}/logs/error.log.
  • The relative paths in the configuration files read by nginx are all relative to this base path.

Since this configuration is written into the program at compile time, it cannot be changed at this point, but you can still specify the path to the configuration file when running nginx with the -c option. If you are not sure of the value of prefix, you can execute the binary and add the -V option to see it.

1
2
3
4
5
6
nginx -V

nginx version: nginx/1.21.1
built by gcc 8.3.0 (Debian 8.3.0-6) 
built with OpenSSL 1.1.1d  10 Sep 2019
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf

Copy the program to an executable path

We first need to move the binary file to the host, at this point it is recommended to place it under an executable path such as /usr/sbin/, after which you do not need to specify a specific path but directly execute the program via the nginx command.

1
2
chmod 0755 nginx
mv nginx /usr/sbin/nginx

Adding Systemd Unit files

For long-running server programs such as nginx, we need to host them for bootup, automatic restart, and so on. The most recommended way to do this is to use systemd as the hosting application, which is the default initialization system for most Linux distributions today.

Specifically, we need to create a unit file named nginx.service and place it in the /usr/lib/systemd/system directory.

1
touch /usr/lib/systemd/system/nginx.service

The contents of nginx.service are as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

In the Unit file, we define this service resource for nginx, and set the startup command and the path to the configuration file to use.

nginx.conf configuration file

We control the specific behavior of nginx through the nginx.conf configuration file. We have defined the configuration file path as /etc/nginx/nginx.conf in the Unit file, so the configuration will be read from that path whenever we start nginx with the systemctl utility. Now create the file.

1
2
mkdir /etc/nginx
touch /etc/nginx/nginx.conf

The contents of nginx.conf can be defined according to our needs, but we need to pay attention to the following points.

  1. the value of the pid directive must be consistent with the Unit file, i.e. pid /run/nginx.pid; .
  2. All directories for path-type directives must exist in advance, such as error_log, access_log and include. nginx will automatically create log files but not directories for them.

It is recommended to keep access and exception logs in the /var/log/nginx directory, and to place sub-configurations of the http configuration section in the /etc/nginx/ directory.

Creating the directory you need to run

The paths you specify in nginx.conf need to be created in advance, otherwise you will get an error when starting nginx. Suppose we specify the following path-like configuration in nginx.conf (only part of it is shown).

1
2
3
4
5
6
7
8
9
error_log  /var/log/nginx/error.log;
pid        /run/nginx.pid;

http {
    access_log  /var/log/nginx/access.log  main;

    include             /etc/nginx/mime.types;
    include             /etc/nginx/conf.d/*.conf;
}

Then you need to prepare the /etc/nginx/mime.types file in advance and create the following directory.

1
2
3
mkdir -p /var/log/nginx
mkdir -p /run
mkdir -p /etc/nginx/conf.d

If we use relative paths in nginx.conf, we need to create the corresponding directory based on the prefix path.

That’s all we need to do.

Starting or restarting nginx

You can now start nginx via systemd.

1
systemctl start nginx && systemctl enable nginx

Note that in the results of systemctl status nginx, we may see the following warning in the initial startup log.

1
[alert]: could not open error log file: open() "/usr/local/nginx/logs/error.log" failed (13: Permission denied)

This is because nginx opens the error log file before it reads nginx.conf, which uses the error-log-path path specified at compile time, which defaults to {prefix}/logs/error.log. After nginx.conf is read, the path specified by error_log in the configuration file is used. Therefore, this error is only a warning and will not affect the start of nginx.

When restarting nginx via reload, you should also be careful to add the -c option to specify the path to the configuration file.

1
nginx -s reload -c /etc/nginx/nginx.conf