如何手动安装 Nginx 二进制文件

在一些特殊场景如离线条件下,我们无法使用包管理器而只能用手动方式来安装特定软件,这时推荐的做法是从源码自行编译安装,通常来说 configure + make install 两步即可完成。

假如我们只能获取已编译好的程序或者没有编译环境,就只能手动执行安装步骤了。本文将记录如何将一个已编译好的 Nginx 二进制文件安装到 Linux 系统中。

prefix 配置

对安装 nginx 来说,最需要注意的是 prefix 路径配置,默认值为 /usr/local/nginx,它是 nginx 运行时的基础路径:

  • nginx 将从该路径寻找配置文件 nginx.conf
  • nginx 使用的其他路径的默认值也均基于该路径,如 {prefix}/logs/error.log
  • nginx 所读取配置文件中的相对路径均相对于该基础路径。

由于该配置在编译时已写入程序中,此时无法再更改,但仍然可以通过 -c 选项在运行 nginx 时指定配置文件的路径。在不确定 prefix 的值时,我们可以执行二进制文件并添加 -V 选项查看:

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

拷贝程序到可执行路径

我们首先需要将二进制文件移动到宿主机,此时建议将其放在可执行路径如 /usr/sbin/ 下,之后就不需要再指定具体的路径而是直接通过 nginx 命令即可执行程序。

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

添加 Systemd Unit 文件

对于 nginx 这类长时间运行服务器程序,我们需要对其进行托管,以实现开机启动、自动重启等功能。最推荐的做法是使用 systemd 作为托管程序,它也是目前大部分 Linux 发行版的默认初始化系统。

具体来说,我们需要创建一个名称为 nginx.service 的 Unit 文件,并置于 /usr/lib/systemd/system 目录下:

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

nginx.service 的内容如下:

 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

在 Unit 文件中,我们定义了 nginx 这一 service 资源,并设置了启动命令和使用的配置文件路径。

nginx.conf 配置文件

我们通过 nginx.conf 配置文件来控制 nginx 的具体行为,在 Unit 文件中我们已将配置文件路径定义为 /etc/nginx/nginx.conf,因此通过 systemctl 工具启动 nginx 时都会从该路径读取配置,现在创建该文件:

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

nginx.conf 的内容可根据我们的需要自行定义,但需要注意一下几点:

  1. pid 指令的值必须和 Unit 文件保持一致,即 pid /run/nginx.pid;
  2. 所有路径类指令的目录必须提前存在,如 error_logaccess_loginclude,nginx 会自动创建 log 文件但并不会创建其目录。

推荐将访问日志和异常日志保存于 /var/log/nginx 目录,将 http 配置部分的子配置置于 /etc/nginx/ 目录下。

创建运行所需目录

nginx.conf 中指定的配置路径,都需要提前将路径目录创建好,否则启动 nginx 时将会报错,假设我们在 nginx.conf 中指定了如下路径类配置(仅展示部分):

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;
}

则需要提前准备好 /etc/nginx/mime.types 文件,并创建以下目录:

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

如果我们在 nginx.conf 中使用了相对路径,则需要基于 prefix 路径创建相应的目录。

到此我们就完成了所有的准备工作。

启动或重启 nginx

现在可以通过 systemd 来启动 nginx 了:

1
systemctl start nginx && systemctl enable nginx

注意在 systemctl status nginx 的结果中,我们可能会在初始的启动日志中看到如下警告:

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

这是因为 nginx 在读取 nginx.conf 之前就会先打开错误日志文件,此时将使用编译时指定的 error-log-path 路径,默认值为 {prefix}/logs/error.log,在读取了 nginx.conf 之后就会使用配置文件中通过 error_log 指定的路径,因此该错误只是一个警告,不会影响 nginx 的启动。

在通过 reload 重启 nginx 时,也需要注意添加 -c 选项指定配置文件路径:

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

参考链接

updatedupdated2021-09-162021-09-16