编辑
2023-11-14
学习笔记
00
请注意,本文编写于 171 天前,最后修改于 171 天前,其中某些信息可能已经过时。

目录

导语
编译安装 Nginx
更新系统
安装编译依赖
前置准备
下载源代码
configure
编译!
安装!
运行!
配置 systemd 持久化
配置文件调优
扫尾
运行!!!
结语

原文地址:https://www.nodeseek.com/post-37224-1

导语

如何安装 Nginx? 方法很多, 最简单的一键脚本安装, 或者宝塔面板之流一键安装, 等等, 高级一点就 apt install nginx. 今天我们不屑于当个小白, 我们来学学最基础的 Nginx 安装方式: 编译安装. 一键脚本, 抑或宝塔面板之流的一键安装, 大抵是替我们我们干了编译安装的各个过程的活罢了. 知其然仍需知其所以然!

虽然是小白参阅系列, 但是仍然要求有基本的 Linux 命令行基础, 你得知道以下命令: rm, mv, cp, wget, 等等. 想知道它们怎么用的吗? 尝试在命令行输入 命令 --help, 如 rm --help, Debian 会告诉你的.

本教程仍然基于并验证于 Debian 12, 故 Debian 系, 含 Ubuntu, 逐步操作大概率没问题. 什么? 还在用 CentOS? 那没救了, 自求多福吧

编译安装 Nginx

更新系统

永远记住, 凡是要用 apt 安装点什么东西, 先更新一下.

apt update -y && apt upgrade -y && apt autoremove -y

安装编译依赖

apt install -y build-essential cmake libpcre3 libpcre3-dev libpcre2-dev zlib1g-dev openssl libssl-dev libxml2-dev libxslt1-dev libgd-dev libgeoip-dev libgoogle-perftools-dev libperl-dev perl-base perl

所谓依赖, 就是编译过程中需要的东西.

前置准备

# 我习惯建立专门用于编译东西的文件夹, 当然, 你想放哪都可以 # 此处示例为 /home/compile, nginx 用的则在 /home/compile/nginx mkdir /home/compile mkdir /home/compile/nginx # 可以理解为这么干, 后续你敲命令 $COMPILE_PATH 就等同于 /home/compile/nginx # 只是为了方便~ # 属于 sh 脚本的内容, 按下不表 export COMPILE_PATH="/home/compile/nginx" cd $COMPILE_PATH

下载源代码

export NGINX_VERSION="1.25.3" # 从 Nginx 官网下载官方压缩打包好的源代码 # 不要告诉我 command not found, 总不能系统 wget 都没有吧, 没有就装一下: apt install wget wget https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz # 解压压缩包, 我们会得到一个名为 nginx-1.25.3 的文件夹(当然, 版本号不一样文件夹名字也不一样咯) # 课后习题: -zxvf 是什么意思? tar -zxvf nginx-$NGINX_VERSION.tar.gz # 解压完就可以删掉压缩包了 rm nginx-$NGINX_VERSION.tar.gz # 为了方便后续敲命令, 我们重命名一下 mv nginx-$NGINX_VERSION nginx_src # 下载 Brotli 压缩的源代码, 此处使用 git 拉取源代码仓库的内容 # Git 是什么, 自行搜索哦 # 不要告诉我 command not found, 我不会告诉你输入 apt install git 就能装上的 # 此步可能执行比较久, 耐心等待~ git clone https://github.com/google/ngx_brotli && cd ngx_brotli && git submodule update --init # 刚才我们 cd, 也就是进入了 ngx_brotli 文件夹, 现在返回上一层文件夹~ cd -

P.S. 截至写下此贴, Nginx 最新版本为 1.25.3. 请前往 https://nginx.org/en/download.html 查看最新版本, 然后照葫芦画瓢替换一下命令里面的版本号.

configure

# 进入 Nginx 的源代码文件夹 cd nginx_src # 配置编译参数, 执行时耐心等待 ./configure \ --prefix=/etc/nginx \ --sbin-path=/usr/sbin/nginx \ --modules-path=/usr/lib/nginx/modules \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/var/run/nginx.pid \ --lock-path=/var/run/nginx.lock \ --http-client-body-temp-path=/var/cache/nginx/client_temp \ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \ --user=nginx \ --group=nginx \ --with-threads \ --with-file-aio \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_v3_module \ --with-http_realip_module \ --with-http_addition_module \ --with-http_xslt_module \ --with-http_image_filter_module \ --with-http_geoip_module \ --with-http_sub_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_auth_request_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_degradation_module \ --with-http_slice_module \ --with-http_stub_status_module \ --with-http_perl_module \ --with-mail \ --with-mail_ssl_module \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ --with-stream_geoip_module \ --with-stream_ssl_preread_module \ --add-module=$COMPILE_PATH/ngx_brotli \ --with-compat \ --with-cc-opt='-g0 -O3 -fstack-reuse=all -fdwarf2-cfi-asm -fplt -fno-trapv -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-stack-check -fno-stack-clash-protection -fno-stack-protector -fcf-protection=none -fno-split-stack -fno-sanitize=all -fno-instrument-functions'

这些编译参数啥意思呢? 说白了就是指定配置文件存哪, 程序本体存哪, 要什么模块等等等等. 这里给出相对标准的参数, 即配置文件相关保存在 /etc/nginx, 附加模块在 /usr/lib/nginx/modules, 程序本体在 /usr/sbin/nginx, 日志在 /var/log/nginx, 各种缓存在 /var/cache/nginx, 添加了最常用的一些模块.

我们也能看到添加了刚刚下载的 ngx_brotli 这个 module(模块)哦.

至于模块是什么, 自己搜啦.

编译!

make

简简单单输入个 make, 等它编译完就可以啦~

机器性能差的可能得挺久. 内存小于 512M 的注意设置虚拟内存, 否则 OOM(Out of memory. 内存用完了), 系统就崩啦.

如果机器有多个 CPU 核心, make -j{CPU 核心数} 多线程编译会更快, 如: 你的 VPS 是 16 核的, 就 make -j16.

安装!

make install

执行完毕后, Nginx 就按照 configure 的内容安装到指定位置啦!

注意: 如果目标目录有东西, 会直接替换掉, 所以如果是升级, 记得提前备份一下原来的配置, 推荐:

cd /opt zip nginx.zip /etc/nginx -r

存在 /etc/nginx 的配置文件等东西就给打包好放到 /opt 目录下面的 nginx.zip 压缩包里面了. 什么? command not found? apt install zip unzip 啦!!!

安装后, mv /opt/nginx.zip /etc && cd /etc && unzip nginx.zip 就还原回去啦.

原则上, /etc/nginx 下就是存各种配置文件之类的东西, 包括 SSL 证书等我也推荐放里面.

运行!

装好了, 就得运行啦! 全新系统还得进行下面的操作:

配置 systemd 持久化

cat <<'TEXT' > /etc/systemd/system/nginx.service [Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking Restart=always RestartSec=15 StartLimitInterval=0 User=root ExecStartPre=/bin/rm -rf /dev/shm/nginx ExecStartPre=/bin/mkdir /dev/shm/nginx ExecStartPre=/bin/chmod 711 /dev/shm/nginx ExecStartPre=/bin/mkdir /dev/shm/nginx/tcmalloc ExecStartPre=/bin/chmod 0777 /dev/shm/nginx/tcmalloc ExecStart=/usr/sbin/nginx ExecReload=/usr/sbin/nginx -s reload ExecStop=/usr/sbin/nginx -s stop ExecStopPost=/bin/rm -rf /dev/shm/nginx PrivateTmp=true [Install] WantedBy=multi-user.target TEXT

配置文件调优

默认的 Nginx 配置文件不够好, 给出优化版本.

需要注意: 如 http2 on 是新版本 nginx 才有的语法, 旧版本不能那么写. 当然如果你是看了本教程全新安装那肯定没事. HTTP3(QUIC) 支持也是 1.25.2 才有的.

# 备份一下原来的 mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.b cat <<'TEXT' > /etc/nginx/nginx.conf user nginx nginx; worker_processes auto; worker_cpu_affinity auto; worker_priority -20; worker_rlimit_nofile 51200; events { use epoll; worker_connections 10240; multi_accept on; } http { include mime.types; # 用了 CDN 的, 去掉下面两行的注释 # set_real_ip_from 0.0.0.0/0; # real_ip_header X-Forwarded-For; default_type application/octet-stream; charset utf-8; # 设定默认启用 HTTP2 http2 on; # 设定日志格式 log_format details '[$time_local][$status]|[Client] "$remote_addr" |[Host] "$host" |[Refer] "$http_referer" |[UA] "$http_user_agent" |[REQ] "$request" |[CONNECT] "$connection_requests" |[TIME] "$request_time" |[LENGTH] "$bytes_sent" |[UPSTREAM] "$upstream_addr" |[U_HEAD_TIME] "$upstream_header_time" |[U_CON_TIME] "$upstream_connect_time" |[U_RSP_TIME] "$upstream_response_time" |[U_STATUS] "$upstream_status" |[U_LENGTH] "$upstream_response_length"'; server_names_hash_bucket_size 512; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 50m; # Perf access_log off; sendfile on; tcp_nopush on; tcp_nodelay on; reset_timedout_connection on; client_body_timeout 10; send_timeout 2; keepalive_timeout 60; # SSL ssl_protocols TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_ecdh_curve X25519:secp384r1; ssl_session_cache shared:SSL:30m; ssl_session_timeout 24h; ssl_session_tickets on; ssl_stapling on; ssl_stapling_verify on; resolver 223.5.5.5 223.6.6.6 valid=60s; resolver_timeout 5s; ssl_early_data on; ssl_buffer_size 8k; ## # Connection header for WebSocket reverse proxy ## map $http_upgrade $connection_upgrade { default upgrade; '' close; } # fastcgi fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on; # 压缩配置, 保持默认即可 gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 6; gzip_types # text/html text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml application/atom+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\."; brotli on; brotli_comp_level 6; brotli_types # text/html text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml application/atom+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; # Others limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; server_tokens off; ## QUIC / HTTP3 http3 on; http3_hq on; quic_retry on; add_header Alt-Svc 'h3=":443"; ma=86400'; # Default server # 此处配置了默认的 Server 块, 妈妈再也不用担心 SSL 证书泄露源站啦! server { listen 80 default_server; listen 443 ssl default_server; listen 443 quic reuseport; server_name _; ssl_reject_handshake on; location /connection-test { default_type application/json; return 200 '{"code":0, "message":""}'; } location / { return 444; } access_log /www/logs/nxdomain.com.log details; } # Include other conf include /etc/nginx/conf.d/*.conf; } TEXT

扫尾

这些文件夹的名字和路径还熟悉吗? 就是前面 configure 的时候设置的

# 创建缓存目录 mkdir /var/cache/nginx # 创建 Nginx 配置文件目录. 你的网站的配置文件就得存这里 mkdir /etc/nginx/conf.d # 创建证书目录, 记得把证书存这里别乱存 mkdir /etc/nginx/certs # 网站文件目录 mkdir /www # 网站日志目录 mkdir /www/logs chmod -R 777 /www # 创建专门的用户运行 nginx, 更安全! useradd -M -s /sbin/nologin nginx

运行!!!

重载 systemd, 立即启用并运行 Nginx!

systemctl daemon-reload && systemctl enable --now nginx

如果顺利, 执行 systemctl status nginx, 你就能看到 Active: active (running) 啦!

结语

恭喜, Nginx 安装完毕, 相当简单! 一键脚本只是帮你输命令而已!

既然都手搓安装 Nginx 了, 配置文件应该也会写了吧? 给份简单示例:

server { # 监听的 HTTP 端口, 默认 80/tcp listen 80; # 监听的 HTTPS 端口, 默认 443/tcp listen 443 ssl; # 监听的 HTTP3(QUIC) 端口, 默认 443/udp listen 443 quic; # 网站的 Host, 可以设置多个 server_name example.com www.example.com; # SSL 证书存在哪 ssl_certificate /etc/nginx/certs/example.com/fullchain.pem; # SSL 证书私钥存在哪 ssl_certificate_key /etc/nginx/certs/example.com/privkey.pem; # 主页, 也就是访问网站默认加载的文件 index index.html; # 网页文件存哪, 习惯上我们把 example.com 网站的内容存 /www/example.com root /www/example.com; # Location 块, 表示访问到匹配的 Path 就会加载对应内容 # 这里的示例是反向代理了你后端的 Alist # 课后作业: 自己查询含义! location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Range $http_range; proxy_set_header If-Range $http_if_range; proxy_redirect off; proxy_pass http://127.0.0.1:5244; # the max size of file to upload client_max_body_size 20000m; } # 访问日志, 习惯上我们把 example.com 网站的日志存到 /www/logs/example.com.log access_log /www/logs/example.com.log details; } 切记: 多思考多动手, 遇到问题善于搜索! 当然, 在评论区问我也行, 注意提问的方法哦~ 欢迎评论区批评指正! xhj020 Last Edit: 2023/11/14 04:19, Ver 1.0.1 附录 熟练后遇到新机器快速部署, 复制粘贴下面的内容即可 apt update && apt upgrade -y && apt dist-upgrade -y&& apt full-upgrade -y && apt autoremove -y apt install -y build-essential cmake libpcre3 libpcre3-dev libpcre2-dev zlib1g-dev openssl libssl-dev libxml2-dev libxslt1-dev libgd-dev libgeoip-dev libgoogle-perftools-dev libperl-dev perl-base perl mkdir /home/compile mkdir /home/compile/nginx export COMPILE_PATH="/home/compile/nginx" cd $COMPILE_PATH export NGINX_VERSION="1.25.3" wget https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz tar -zxvf nginx-$NGINX_VERSION.tar.gz rm nginx-$NGINX_VERSION.tar.gz mv nginx-$NGINX_VERSION nginx_src git clone https://github.com/google/ngx_brotli && cd ngx_brotli && git submodule update --init && cd - cd nginx_src ./configure \ --prefix=/etc/nginx \ --sbin-path=/usr/sbin/nginx \ --modules-path=/usr/lib/nginx/modules \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/var/run/nginx.pid \ --lock-path=/var/run/nginx.lock \ --http-client-body-temp-path=/var/cache/nginx/client_temp \ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \ --user=nginx \ --group=nginx \ --with-threads \ --with-file-aio \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_v3_module \ --with-http_realip_module \ --with-http_addition_module \ --with-http_xslt_module \ --with-http_image_filter_module \ --with-http_geoip_module \ --with-http_sub_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_auth_request_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_degradation_module \ --with-http_slice_module \ --with-http_stub_status_module \ --with-http_perl_module \ --with-mail \ --with-mail_ssl_module \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ --with-stream_geoip_module \ --with-stream_ssl_preread_module \ --add-module=$COMPILE_PATH/ngx_brotli \ --with-compat \ --with-cc-opt='-g0 -O3 -fstack-reuse=all -fdwarf2-cfi-asm -fplt -fno-trapv -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-stack-check -fno-stack-clash-protection -fno-stack-protector -fcf-protection=none -fno-split-stack -fno-sanitize=all -fno-instrument-functions' make make install cat <<'TEXT' > /etc/systemd/system/nginx.service [Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking Restart=always RestartSec=15 StartLimitInterval=0 User=root ExecStartPre=/bin/rm -rf /dev/shm/nginx ExecStartPre=/bin/mkdir /dev/shm/nginx ExecStartPre=/bin/chmod 711 /dev/shm/nginx ExecStartPre=/bin/mkdir /dev/shm/nginx/tcmalloc ExecStartPre=/bin/chmod 0777 /dev/shm/nginx/tcmalloc ExecStart=/usr/sbin/nginx ExecReload=/usr/sbin/nginx -s reload ExecStop=/usr/sbin/nginx -s stop ExecStopPost=/bin/rm -rf /dev/shm/nginx PrivateTmp=true [Install] WantedBy=multi-user.target TEXT mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.b cat <<'TEXT' > /etc/nginx/nginx.conf user nginx nginx; worker_processes auto; worker_cpu_affinity auto; worker_priority -20; worker_rlimit_nofile 51200; events { use epoll; worker_connections 10240; multi_accept on; } http { include mime.types; # set_real_ip_from 0.0.0.0/0; # real_ip_header CF-Connecting-IP; default_type application/octet-stream; charset utf-8; http2 on; log_format details '[$time_local][$status]|[Client] "$remote_addr" |[Host] "$host" |[Refer] "$http_referer" |[UA] "$http_user_agent" |[REQ] "$request" |[CONNECT] "$connection_requests" |[TIME] "$request_time" |[LENGTH] "$bytes_sent" |[UPSTREAM] "$upstream_addr" |[U_HEAD_TIME] "$upstream_header_time" |[U_CON_TIME] "$upstream_connect_time" |[U_RSP_TIME] "$upstream_response_time" |[U_STATUS] "$upstream_status" |[U_LENGTH] "$upstream_response_length"'; server_names_hash_bucket_size 512; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 50m; # Perf access_log off; sendfile on; tcp_nopush on; tcp_nodelay on; reset_timedout_connection on; client_body_timeout 10; send_timeout 2; keepalive_timeout 60; # SSL ssl_protocols TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_ecdh_curve X25519:secp384r1; ssl_session_cache shared:SSL:30m; ssl_session_timeout 24h; ssl_session_tickets on; ssl_stapling on; ssl_stapling_verify on; resolver 223.5.5.5 223.6.6.6 valid=60s; resolver_timeout 5s; ssl_early_data on; ssl_buffer_size 8k; ## # Connection header for WebSocket reverse proxy ## map $http_upgrade $connection_upgrade { default upgrade; '' close; } # fastcgi fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on; # compress gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 6; gzip_types # text/html text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml application/atom+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\."; brotli on; brotli_comp_level 6; brotli_types # text/html text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml application/atom+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; # Others limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; server_tokens off; ## QUIC http3 on; http3_hq on; quic_retry on; add_header Alt-Svc 'h3=":443"; ma=86400'; # Default server server { listen 80 default_server; listen 443 ssl default_server; listen 443 quic reuseport; server_name _; ssl_reject_handshake on; location /connection-test { default_type application/json; return 200 '{"code":0, "message":""}'; } location / { return 444; } access_log /www/logs/nxdomain.com.log details; } # Include other conf include /etc/nginx/conf.d/*.conf; } TEXT mkdir /var/cache/nginx mkdir /etc/nginx/conf.d mkdir /etc/nginx/certs mkdir /www mkdir /www/logs mkdir /www/default chmod -R 777 /www useradd -M -s /sbin/nologin nginx systemctl daemon-reload && systemctl enable --now nginx

本文作者:我本无罪

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!