1. 编译安装 Nginx
1.1. 安装步骤
- 下载源码包: http://nginx.org/en/download.html,
wget http://nginx.org/download/nginx-1.24.0.tar.gz
- 解压下载包:
tar -zxf ./nginx-1.24.0.tar.gz
- 安装配置:
./configure ...
- 编译安装:
make && make install
- 做过软连:
ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
- 查看信息:
nginx -t
1.2. 编译参数信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| # 编译安装
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_stub_status_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_auth_request_module \
--with-http_secure_link_module \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-file-aio \
--with-http_v2_module
...
Configuration summary
+ using threads
+ using system PCRE2 library
+ using system OpenSSL library
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
|
2. Nginx Systemd 配置
参考: https://www.nginx.com/resources/wiki/start/topics/examples/systemd/
2.1. 配置步骤
- 创建
nginx.service
: vim /lib/systemd/system/nginx.service
,将下述 service 内容补充上 - 如果安装后之前有启动 nginx 服务,先通过 root 停止下:
nginx -s stop
,或者killall nginx
- 配置开机启动:
systemctl enable nginx.service
- 启动服务:
systemctl start nginx.service
- 查看服务:
systemctl status nginx.service
- 查看日志:
journalctl -xe -u nginx
2.2. nginx.service 内容
注意 PIDFile
是否和自己匹配,查看 ./configure
结尾信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| [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
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
|
3.1. 部署流程
- Hugo 皮肤调试(Fork 到了自己的 Github)
- archstat.com - content 的内容规划,聚焦后端程序员学习与成长
- 项目 git 仓库准备(都存储到 Github、submodule 皮肤使用)
- Website 腾讯云服务器初始
- hugo 安装,依赖 Git、Go(1.18+)、Hugo Extend 版本(依赖 g++安装)
- 远程
depoly_website.sh
脚本编写(支持 build 目录清理,避免磁盘滚动过大) - 本地配置
archstat_publish.sh
(支持远程 ssh 执行部署)
- 域名备案与解析,因为之前已经备案过
archstat.com
域名,(做了阿里云 → 迁移腾讯云备案工作) - Nginx Web 配置(80 端口)
- Let’s Encrypt 的配置(自动签发域名配置、acme.sh、dns 验证、阿里云 Key+Secret)
- Nginx Web 升级到 H2(443、TLS、HTTP2.0 协议)
3.2. Let’s Encrypt 证书签发
参考: 通过 Acme.sh 自动签发阿里云证书
4. 自动化部署&发布
4.1. 本地 depoly_website.sh
1
| ssh deployer@archstat.com -p 36000 'sh /home/deployer/sh/archstat_publish.sh'
|
4.2. 远程 archstat_publish.sh
拿之前写的脚本简单修改下,仍然很好用,哈哈
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
| #!/bin/bash
#
# hugo打包部署website 脚本
#
# Date: 2018-05-11
#
# 相关初始化
projectGitPath="/home/deployer/projects/archstat_docs"
projectGitBranch="main"
buildProjectPath="/data/www/archstat.com"
buildSavePath="${buildProjectPath}/build"
websitePublicLink="${buildProjectPath}/public"
deployer="deployer"
# 本次构建
buildPublicPath="$buildSavePath/$(date +%Y%m%d_%H%M%S)"
# 磁盘最多保存部署次数
limitNum=10
# 1. 检测发布用户
echo "[deploy start... 🚀🚀🚀 ]"
currentUser=$(whoami)
echo "[deploy user account checking... ]"
if [ "$currentUser" != $deployer ]; then
echo "[Error]: current user[$currentUser] isn't match the deploy user: ${deployer}, reset an try again..."
exit 1
fi
# 检测构建目录(包含日期)
echo "[deploy user account checking... ]"
if [ ! -d "$(dirname ${buildPublicPath})" ]; then
mkdir -p "$(dirname ${buildPublicPath})" || echo "[Error]: buildPublicPath($(dirname $buildPublicPath)) not exist, please check again... "
exit 1
fi
# 2. git仓库代码更新
echo "[✅ git deploy check ok. now begin update the git repository... 🚀🚀🚀 ]"
unset GIT_DIR && "unset GIT_DIR ok."
# 2.1) git 更新website项目
cd ${projectGitPath} || exit
git checkout $projectGitBranch
git reset --hard
git pull --ff-only origin $projectGitBranch || exit 1
echo "[✅ git pull website repository done. ]"
# 2.2) git 更新submodule内容
echo "[update the submodule repository... ]"
git submodule update || exit 1
echo "[✅ git submodule update done. ]"
# 3. 开始hugo构建
echo "[hugo build project... 🚀🚀🚀]"
hugo -v --minify --cleanDestinationDir || exit 1
echo "[✅ hugo build done. ]"
# 4. 将构建内容同步到指定目录
echo "[rsync website public files to build path ... 🚀🚀🚀]"
[ ! -d "$buildPublicPath" ] && mkdir -p "$buildPublicPath"
rsync -az --exclude=.git public/ $buildPublicPath || exit 1
echo "[✅ rsync public to $buildPublicPath ok. ]"
# 5. 重做public软链
echo "[unlink and relink the website public dir ... 🚀🚀🚀]"
if [ -L "$websitePublicLink" ]; then
unlink $websitePublicLink && ln -s "$buildPublicPath" $websitePublicLink || exit 9
else
ln -s $buildPublicPath $websitePublicLink || exit 9
fi
echo "[✅ relink website to public path ok. ]"
# 6. 部署完成,定期清理内容,最多保存10个
echo "[clean build path, keep only ($limitNum) build records ... 🚀🚀🚀]"
cleanPath=($(ls -dt $buildSavePath/* | sort))
curNum=${#cleanPath[@]}
if [[ $curNum -gt 2*$limitNum ]]; then
for i in $(seq 1 $limitNum); do
toDeletePath="${cleanPath[$i]}"
# 需要做下检查,避免误删了其他系统文件
if [[ $toDeletePath == *${buildSavePath}* ]]; then
echo "try delete index dir:$i , path:${cleanPath[$i]}..."
echo "rm -rf $toDeletePath || exit 1"
fi
done
echo "[✅ clean website build path ok. ]"
else
echo "[needn't clean records curNum=($curNum), limitNum=($limitNum)]"
fi
echo "[👏👏👏deploy success]...."
|
5. 其他
5.1. XFF
X-Forwarded-For(XFF)
是用来识别通过 HTTP 代理或负载均衡方式连接到 Web 服务器的客户端最原始的 IP 地址的 HTTP
请求头字段。代理服务器是透明代理,用户甚至不知道自己正在使用代理上网。
XFF 的有效性依赖于代理服务器提供的连接原始 IP 地址的真实性,因此,XFF 的有效使用应该保证代理服务器是可信的,比如可以通过创建可信服务器白名单的方式。非连接发起的原始
IP
地址通过代理服务器可以做行为匿名服务处理,原始 IP 地址不可得,恶意访问的检测与预防的难度将大大增加。
模式:X-Forwarded-For: client1, proxy1, proxy2
逗号+空格 把多个 IP 地址区分开, 最左边(client1)是最原始客户端的 IP 地址, 代理服务器每成功收到一个请求,就把请求来源 IP 地址添加到右边。
伪造这一字段非常容易,应该谨慎使用 X-Forwarded-For 字段。
正常情况下 XFF 中最后一个 IP 地址是最后一个代理服务器的 IP 地址, 这通常是一个比较可靠的信息来源。
5.2. Nginx Proxy 设置
参见:http://nginx.org/en/docs/http/ngx_http_realip_module.html
--with-http_realip_module
模块,默认未构建- real_ip_header field | X-Real-IP | X-Forwarded-For | proxy_protocol;
- real_ip_recursive off; (禁用递归搜索,匹配其中一个可信地址的原始客户端地址将替换为 real_ip_header
指令定义的请求头字段中发送的最后一个地址 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // 参见
location /uri {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60s; # nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90s; # 后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90s; # 连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; # 设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; # proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; # 高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; # 设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_buffering off;
proxy_ignore_client_abort on;
proxy_pass http://xx.xx.xx.xx;
}
|
6. 推荐地址
- 详细的官方文档案例: https://www.nginx.com/resources/wiki/start/topics/examples/systemd/