背景

因为系统重装后,重装nginx,因为想用其他用户启动、不想改文件权限、想自定义配置文件地址。就研究一下其他安装方式。

nginx官方仓库安装

可以完全参考这篇官方文档:http://nginx.org/en/linux_packages.html

简单来说:
因为centos stream 8自带的仓库比较保守,没有最新版本软件,所以需要自己添加仓库。这个和之前安装mariadb是一样的。

文档提供了两个版本:stable,mainline。直接修改仓库配置enable,或者使用yum命令行可以控制开启与否。

Building nginx from Sources

从下载页面:http://nginx.org/en/download.html,下载压缩包。我选择的是stable 1.24.0。

使用Sources安装意味着需要自己安装依赖包、自己配置nginx启动配置、自己安装nginx、自己卸载nginx。好处在于自定义:自定义各类文件位置;自定义启动的用户等。

解压缩

把压缩包内自带一个文件夹nginx-1.24.0,就不用指定路径了。另外,这个在那里解压都行,因为这个只是个安装程序文件夹,真正安装会有新的指定文件夹。

tar -xzvf nginx-1.24.0.tar.gz
mv nginx-1.24.0 nginx-1.24.0-install

./configure

进入到目录后,发现有./configure文件,使用这个来配置nginx编译安装的参数(写在一行里就行了)。这里下面是我的启动参数:

./configure --prefix=/home/appadmin/nginx-1.24.0 --sbin-path=/usr/sbin/nginx-1.24.0 --modules-path=/home/appadmin/nginx-1.24.0/modules --conf-path=/home/appadmin/nginx-1.24.0/conf/nginx.conf --http-log-path=/home/appadmin/nginx-1.24.0/log/access.log --error-log-path=/home/appadmin/nginx-1.24.0/log/error.log --lock-path=/var/lock/nginx.lock --pid-path=/home/appadmin/nginx-1.24.0/run/nginx.pid --http-client-body-temp-path=/home/appadmin/nginx-1.24.0/temp/client_temp --http-proxy-temp-path=/home/appadmin/nginx-1.24.0/temp/proxy_temp --http-fastcgi-temp-path=/home/appadmin/nginx-1.24.0/temp/fastcgi_temp --http-uwsgi-temp-path=/home/appadmin/nginx-1.24.0/temp/uwsgi_temp --http-scgi-temp-path=/home/appadmin/nginx-1.24.0/temp/scgi_temp --with-http_ssl_module --with-http_image_filter_module=dynamic --with-http_v2_module --with-stream=dynamic --with-http_addition_module --with-http_mp4_module --with-compat --with-file-aio --with-threads
./configure --prefix=/home/appadmin/nginx-1.24.0 \#安装在哪个文件夹
            --sbin-path=/usr/sbin/nginx-1.24.0 \#可执行文件所在位置
            --modules-path=/home/appadmin/nginx-1.24.0/modules \#动态模块安装位置
            --conf-path=/home/appadmin/nginx-1.24.0/conf/nginx.conf \#nginx主配置文件所在位置
            --http-log-path=/home/appadmin/nginx-1.24.0/log/access.log \#定义request日志位置
            --error-log-path=/home/appadmin/nginx-1.24.0/log/error.log \#定义error日志位置
            --lock-path=/var/lock/nginx.lock \#进程锁位置
            --pid-path=/home/appadmin/nginx-1.24.0/run/nginx.pid \#进程号位置,用来执行stop,reload,restart等操作可以用到
            # 以下开始配置临时文件存储的文件夹
            --http-client-body-temp-path=/home/appadmin/nginx-1.24.0/temp/client_temp \
            --http-proxy-temp-path=/home/appadmin/nginx-1.24.0/temp/proxy_temp \
            --http-fastcgi-temp-path=/home/appadmin/nginx-1.24.0/temp/fastcgi_temp \
            --http-uwsgi-temp-path=/home/appadmin/nginx-1.24.0/temp/uwsgi_temp \
            --http-scgi-temp-path=/home/appadmin/nginx-1.24.0/temp/scgi_temp \
            # 以下开始定义nginx编译的时候需要加载的模块
            --with-http_ssl_module \
            --with-http_image_filter_module=dynamic \
            --with-http_v2_module \
            --with-stream=dynamic \
            --with-http_addition_module \
            --with-http_mp4_module \
            --with-compat \
            --with-file-aio \
            --with-threads \

权威参数指南看这里:http://nginx.org/en/docs/configure.html
中文翻译可以参考这里:https://www.jianshu.com/p/f463d92b57b7

报错

checking for struct tm.tm_gmtoff ... found
checking for struct dirent.d_namlen ... not found
checking for struct dirent.d_type ... found
checking for sysconf(_SC_NPROCESSORS_ONLN) ... found
checking for sysconf(_SC_LEVEL1_DCACHE_LINESIZE) ... found
checking for openat(), fstatat() ... found
checking for getaddrinfo() ... found
checking for PCRE2 library ... not found
checking for PCRE library ... not found
checking for PCRE library in /usr/local/ ... not found
checking for PCRE library in /usr/include/pcre/ ... not found
checking for PCRE library in /usr/pkg/ ... not found
checking for PCRE library in /opt/local/ ... not found

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.

报错通常是因为nginx的依赖包没有安装完全。通常需要安装的是-devel的那个。像上面需要安装的是:yum install pcre-devel

./configure成功

checking for zlib library ... found
checking for GD library ... found
checking for GD WebP support ... found
creating objs/Makefile

Configuration summary
  + using threads
  + using system PCRE2 library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/home/appadmin/nginx-1.24.0"
  nginx binary file: "/usr/sbin/nginx-1.24.0"
  nginx modules path: "/home/appadmin/nginx-1.24.0/modules"
  nginx configuration prefix: "/home/appadmin/nginx-1.24.0/conf"
  nginx configuration file: "/home/appadmin/nginx-1.24.0/conf/nginx.conf"
  nginx pid file: "/home/appadmin/nginx-1.24.0/run/nginx.pid"
  nginx error log file: "/home/appadmin/nginx-1.24.0/log/error.log"
  nginx http access log file: "/home/appadmin/nginx-1.24.0/log/access.log"
  nginx http client request body temporary files: "/home/appadmin/nginx-1.24.0/temp/client_temp"
  nginx http proxy temporary files: "/home/appadmin/nginx-1.24.0/temp/proxy_temp"
  nginx http fastcgi temporary files: "/home/appadmin/nginx-1.24.0/temp/fastcgi_temp"
  nginx http uwsgi temporary files: "/home/appadmin/nginx-1.24.0/temp/uwsgi_temp"
  nginx http scgi temporary files: "/home/appadmin/nginx-1.24.0/temp/scgi_temp"

./configure完成后会在本目录下生成【objs】文件夹。

make

使用make命令编译nginx可执行文件。

  1. 没有make命令需要先安装
  2. 需要在安装程序文件夹下执行
yum install make
make

编译完成后,重要的是在【objs】文件夹下会生成可执行文件:【nginx

objs/src/stream/ngx_stream_upstream_random_module.o \
objs/src/stream/ngx_stream_upstream_zone_module.o \
objs/ngx_stream_module_modules.o \
-shared
sed -e "s|%%PREFIX%%|/home/appadmin/nginx-1.24.0|" \
        -e "s|%%PID_PATH%%|/home/appadmin/nginx-1.24.0/run/nginx.pid|" \
        -e "s|%%CONF_PATH%%|/home/appadmin/nginx-1.24.0/conf/nginx.conf|" \
        -e "s|%%ERROR_LOG_PATH%%|/home/appadmin/nginx-1.24.0/log/error.log|" \
        < man/nginx.8 > objs/nginx.8
make[1]: 离开目录“/home/appadmin/nginx-1.24.0-install”
[appadmin@localhost nginx-1.24.0-install]$ ls -l objs/
总用量 8120
-rw-rw-r-- 1 appadmin appadmin   20332 10月 25 17:18 autoconf.err
-rw-rw-r-- 1 appadmin appadmin   55600 10月 25 17:18 Makefile
-rwxrwxr-x 1 appadmin appadmin 6971824 10月 25 17:22 nginx
-rw-rw-r-- 1 appadmin appadmin    5579 10月 25 17:22 nginx.8
-rw-rw-r-- 1 appadmin appadmin    9419 10月 25 17:18 ngx_auto_config.h
-rw-rw-r-- 1 appadmin appadmin     657 10月 25 17:18 ngx_auto_headers.h
-rw-rw-r-- 1 appadmin appadmin    1294 10月 25 17:18 ngx_http_image_filter_module_modules.c
-rw-rw-r-- 1 appadmin appadmin   44832 10月 25 17:22 ngx_http_image_filter_module_modules.o
-rwxrwxr-x 1 appadmin appadmin  131424 10月 25 17:22 ngx_http_image_filter_module.so
-rw-rw-r-- 1 appadmin appadmin    6676 10月 25 17:18 ngx_modules.c
-rw-rw-r-- 1 appadmin appadmin   54104 10月 25 17:22 ngx_modules.o
-rw-rw-r-- 1 appadmin appadmin    2147 10月 25 17:18 ngx_stream_module_modules.c
-rw-rw-r-- 1 appadmin appadmin   46392 10月 25 17:22 ngx_stream_module_modules.o
-rwxrwxr-x 1 appadmin appadmin  930520 10月 25 17:22 ngx_stream_module.so
drwxrwxr-x 9 appadmin appadmin      91 10月 25 17:18 src

make install

真正的安装命令,该命令一般来说会检查各种路径是否存在、复制各种文件到./configure指定的--perfix路径下

  1. 该命令需要root权限,或者sudo
  2. 需要在安装程序文件夹下执行
[root@localhost nginx-1.24.0-install]# make install
make -f objs/Makefile install
make[1]: 进入目录“/home/appadmin/nginx-1.24.0-install”
test -d '/home/appadmin/nginx-1.24.0' || mkdir -p '/home/appadmin/nginx-1.24.0'
test -d '/usr/sbin' \
        || mkdir -p '/usr/sbin'
test ! -f '/usr/sbin/nginx-1.24.0' \
        || mv '/usr/sbin/nginx-1.24.0' \
                '/usr/sbin/nginx-1.24.0.old'
cp objs/nginx '/usr/sbin/nginx-1.24.0'
test -d '/home/appadmin/nginx-1.24.0/conf' \
        || mkdir -p '/home/appadmin/nginx-1.24.0/conf'
cp conf/koi-win '/home/appadmin/nginx-1.24.0/conf'
cp conf/koi-utf '/home/appadmin/nginx-1.24.0/conf'
cp conf/win-utf '/home/appadmin/nginx-1.24.0/conf'
test -f '/home/appadmin/nginx-1.24.0/conf/mime.types' \
        || cp conf/mime.types '/home/appadmin/nginx-1.24.0/conf'
cp conf/mime.types '/home/appadmin/nginx-1.24.0/conf/mime.types.default'
test -f '/home/appadmin/nginx-1.24.0/conf/fastcgi_params' \
        || cp conf/fastcgi_params '/home/appadmin/nginx-1.24.0/conf'
cp conf/fastcgi_params \
        '/home/appadmin/nginx-1.24.0/conf/fastcgi_params.default'
test -f '/home/appadmin/nginx-1.24.0/conf/fastcgi.conf' \
        || cp conf/fastcgi.conf '/home/appadmin/nginx-1.24.0/conf'
cp conf/fastcgi.conf '/home/appadmin/nginx-1.24.0/conf/fastcgi.conf.default'
test -f '/home/appadmin/nginx-1.24.0/conf/uwsgi_params' \
        || cp conf/uwsgi_params '/home/appadmin/nginx-1.24.0/conf'
cp conf/uwsgi_params \
        '/home/appadmin/nginx-1.24.0/conf/uwsgi_params.default'
test -f '/home/appadmin/nginx-1.24.0/conf/scgi_params' \
        || cp conf/scgi_params '/home/appadmin/nginx-1.24.0/conf'
cp conf/scgi_params \
        '/home/appadmin/nginx-1.24.0/conf/scgi_params.default'
test -f '/home/appadmin/nginx-1.24.0/conf/nginx.conf' \
        || cp conf/nginx.conf '/home/appadmin/nginx-1.24.0/conf/nginx.conf'
cp conf/nginx.conf '/home/appadmin/nginx-1.24.0/conf/nginx.conf.default'
test -d '/home/appadmin/nginx-1.24.0/run' \
        || mkdir -p '/home/appadmin/nginx-1.24.0/run'
test -d '/home/appadmin/nginx-1.24.0/log' \
        || mkdir -p '/home/appadmin/nginx-1.24.0/log'
test -d '/home/appadmin/nginx-1.24.0/html' \
        || cp -R html '/home/appadmin/nginx-1.24.0'
test -d '/home/appadmin/nginx-1.24.0/log' \
        || mkdir -p '/home/appadmin/nginx-1.24.0/log'
test -d '/home/appadmin/nginx-1.24.0/modules' \
        || mkdir -p '/home/appadmin/nginx-1.24.0/modules'
test ! -f '/home/appadmin/nginx-1.24.0/modules/ngx_http_image_filter_module.so' \
        || mv '/home/appadmin/nginx-1.24.0/modules/ngx_http_image_filter_module.so' \
                '/home/appadmin/nginx-1.24.0/modules/ngx_http_image_filter_module.so.old'
cp objs/ngx_http_image_filter_module.so '/home/appadmin/nginx-1.24.0/modules/ngx_http_image_filter_module.so'
test ! -f '/home/appadmin/nginx-1.24.0/modules/ngx_stream_module.so' \
        || mv '/home/appadmin/nginx-1.24.0/modules/ngx_stream_module.so' \
                '/home/appadmin/nginx-1.24.0/modules/ngx_stream_module.so.old'
cp objs/ngx_stream_module.so '/home/appadmin/nginx-1.24.0/modules/ngx_stream_module.so'
make[1]: 离开目录“/home/appadmin/nginx-1.24.0-install”

可以看到,nginx的安装如上就是检查路径、创造文件夹、复制文件到指定的地方。

检查

这个可执行文件的名字是在./configure里自定义的

[appadmin@localhost nginx-1.24.0-install]$ nginx-1.24.0 -v
nginx version: nginx/1.24.0
[appadmin@localhost nginx-1.24.0-install]$ ps -ef |grep nginx
appadmin    5414    2027  0 17:29 pts/0    00:00:00 grep --color=auto nginx
[appadmin@localhost nginx-1.24.0-install]$ nginx-1.24.0
[appadmin@localhost nginx-1.24.0-install]$ ps -ef |grep nginx
appadmin    5416       1  0 17:29 ?        00:00:00 nginx: master process nginx-1.24.0
appadmin    5417    5416  0 17:29 ?        00:00:00 nginx: worker process
appadmin    5418    5416  0 17:29 ?        00:00:00 nginx: worker process
appadmin    5419    5416  0 17:29 ?        00:00:00 nginx: worker process
appadmin    5420    5416  0 17:29 ?        00:00:00 nginx: worker process
appadmin    5422    2027  0 17:29 pts/0    00:00:00 grep --color=auto nginx

optional:添加man

需要用root或者sudo

cp /home/appadmin/nginx-1.24.0/man/nginx.8 /usr/share/man/man8
gzip /usr/share/man/man8/nginx.8
ls /usr/share/man/man8/ | grep nginx.8.gz
# Check that Man page for Nginx is working:
man nginx

optional:添加开机自启动

在systemd中添加nginx。/etc/systemd/system/nginx.service没有就自己新建一个。

[appadmin@localhost ~]$ cat /etc/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/home/appadmin/nginx-1.24.0/run/nginx.pid
ExecStartPre=/usr/sbin/nginx-1.24.0 -t -c /home/appadmin/nginx-1.24.0/conf/nginx.conf
ExecStart=/usr/sbin/nginx-1.24.0 -c /home/appadmin/nginx-1.24.0/conf/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /home/appadmin/nginx-1.24.0/run/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /home/appadmin/nginx-1.24.0/run/nginx.pid)"
User=appadmin
Group=appzone

[Install]
WantedBy=multi-user.target

添加开机自启动

[root@localhost ~]# systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /etc/systemd/system/nginx.service.

这个是systemctl start nginx的输出。报错是没有证书,是因为我在systemd中为nginx配置了ExecStartPre,命令是去执行nginx -t。所以看到【configuration file /home/appadmin/nginx-1.24.0/conf/nginx.conf test failed】。

10月 26 10:39:27 localhost.localdomain systemd[1]: Reloading.
10月 26 10:40:44 localhost.localdomain systemd[1]: Starting nginx - high performance web server...
-- Subject: nginx.service 单元已开始启动
-- Defined-By: systemd
-- Support: https://access.redhat.com/support
--
-- nginx.service 单元已开始启动。
10月 26 10:40:44 localhost.localdomain nginx-1.24.0[1996]: nginx: [emerg] cannot load certificate "/home/appadmin/nginx/cert/server.crt": BIO_new_file() failed (SSL: error:0200100>
10月 26 10:40:44 localhost.localdomain nginx-1.24.0[1996]: nginx: configuration file /home/appadmin/nginx-1.24.0/conf/nginx.conf test failed
10月 26 10:40:44 localhost.localdomain systemd[1]: nginx.service: Control process exited, code=exited status=1
10月 26 10:40:44 localhost.localdomain systemd[1]: nginx.service: Failed with result 'exit-code'.
-- Subject: Unit failed
-- Defined-By: systemd
-- Support: https://access.redhat.com/support
--
-- The unit nginx.service has entered the 'failed' state with result 'exit-code'.
10月 26 10:40:44 localhost.localdomain systemd[1]: Failed to start nginx - high performance web server.
-- Subject: nginx.service 单元已失败
-- Defined-By: systemd
-- Support: https://access.redhat.com/support
--
-- nginx.service 单元已失败。
--
-- 结果为“failed”。

按照报错修改成功后就能启动成功了。注意到用户名是我们想要的,nginx可执行文件也可以正常使用。

[root@localhost nginx-1.24.0]# ps -ef |grep nginx
appadmin    2139       1  0 11:13 ?        00:00:00 nginx: master process /usr/sbin/nginx-1.24.0 -c /home/appadmin/nginx-1.24.0/conf/nginx.conf
appadmin    2140    2139  0 11:13 ?        00:00:00 nginx: worker process
appadmin    2141    2139  0 11:13 ?        00:00:00 nginx: worker process
appadmin    2142    2139  0 11:13 ?        00:00:00 nginx: worker process
appadmin    2143    2139  0 11:13 ?        00:00:00 nginx: worker process
root        2147    2080  0 11:13 pts/1    00:00:00 grep --color=auto nginx

卸载

因为没有包管理软件,所以得手动回滚。回滚的步骤就是上面make install的步骤倒着做一遍🙄
如果没有保存安装步骤,可以使用make -n install-n的意思就是打印步骤但不实际执行。(-s的意思就是不打印步骤但实际执行)

optional:清理安装文件夹

rm -rf nginx-1.24.0-install

总结

本来使用yum包管理工具挺好的,把/etc/nginx的权限开给appadmin,把/var/log/nginx的权限开给用户。开机后,使用appadmin执行nginx -c {nginx配置路径}

后面重装系统后不想改各种文件的权限、手动启动太麻烦了。开机直接启动不好吗?那么加入systemctl enable nginx。从这里开始我的问题就出现了。自启动用的root用户,给nginx添加override设置会导致nginx的master是root用户,worker是appadmin。而且,appadmin还是没有办法直接使用nginx可执行文件!!

  1. 不想修改文件、文件夹的所有人和权限

    [appadmin@localhost root]$ nginx -s reload
    nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
    2023/10/19 16:10:51 [warn] 7218#7218: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
    2023/10/19 16:10:51 [notice] 7218#7218: signal process started
    2023/10/19 16:10:51 [alert] 7218#7218: kill(7189, 1) failed (1: Operation not permitted)
  2. 给nginx添加的override设置

    systemctl edit nginx

    注意修改ExecStart前需要给他先赋空值ExecStart=

    [root@localhost nginx]# systemctl cat nginx
    # /usr/lib/systemd/system/nginx.service
    [Unit]
    Description=nginx - high performance web server
    Documentation=http://nginx.org/en/docs/
    After=network-online.target remote-fs.target nss-lookup.target
    Wants=network-online.target
    
    [Service]
    Type=forking
    PIDFile=/var/run/nginx.pid
    ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
    ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)"
    ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)"
    
    [Install]
    WantedBy=multi-user.target
    
    # /etc/systemd/system/nginx.service.d/override.conf
    [Service]
    Type=forking
    PIDFile=/var/run/nginx.pid
    ExecStart=
    ExecStart=/usr/sbin/nginx -c /home/appadmin/nginx/nginx.conf
    ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /home/appadmin/nginx/nginx.pid)"
    ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /home/appadmin/nginx/nginx.pid)"
    User=appadmin
    Group=appzone

研究了非常多的时间后,使用包管理器安装真的没有办法修改目录。非root用户使用nginx可执行文件会去默认检查默认路径下的文件。那就只能从Sources编译安装了,通过./configure配置各种参数。

需要注意的是,nginx的各类依赖要安装好。各种*.devel包
这三篇参考非常好,从source安装:
https://www.tecmint.com/install-nginx-from-source/
https://www.howtoforge.com/how-to-build-nginx-from-source-on-...
https://tylersguides.com/guides/installing-nginx-from-source-...


BreezingSummer
45 声望0 粉丝