编辑模式 · 点击文字即可修改 · Ctrl+S 导出 再次按 E 或点击左上角退出
模块 7.2 · 全栈部署

常驻与同源

systemd 进程守护与 Nginx 反向代理

上一节

留下了三个尾巴

1后端靠 nohup 跑着管理起来麻烦;挂了不能自动重启,很脆弱
28000 端口直接对外没有安全控制;以后上 HTTPS 也费劲
3前后端靠 IP 互相认地址写在配置里;以后换域名不方便
1234
nohup .venv/bin/fastapi run > backend.log 2>&1 &
怎么停掉它?
ps aux | grep fastapi # 先捞出进程号
kill 进程号
怎么看它还在不在跑?
ps aux | grep fastapi # 捞得出来,就还活着
1
服务器重启,自动拉起 进程崩了,自动重启
systemd = system daemon守护进程
管家进程守护
zero-to-tech 后端
fastapi run
一条命令查状态 替我们收着日志
12345
sudo systemctl status nginx
systemctlsystemd 的命令行工具
status下给 systemd 的指令
nginx被委托出去的那个程序
123
程序自带的命令
sudo nginx
sudo nginx -s reload
sudo nginx -s stop
委托给 systemd
sudo systemctl start nginx
sudo systemctl reload nginx
sudo systemctl stop nginx
systemd
Nginx
nginx.service
zero-to-tech 后端
.service还没写
一份 service 文件,都是这三段
[Unit]这是个什么服务,叫什么名字
[Service]怎么跑它:用哪条命令、用谁的身份、挂了怎么办
[Install]什么时候把它带起来:开机自启就写在这儿
12345
四条命令

委托正式生效

sudo systemctl daemon-reload # 新增了 service 文件,让 systemd 重读一遍sudo systemctl start zero-backend # 启动 sudo systemctl status zero-backend # 查状态 sudo systemctl enable zero-backend # 开机自启(WantedBy 那行生效)
委托之后

日常管理全用 systemctl

想干什么
命令
看它活着没有
sudo systemctl status zero-backend
改完代码,重启
sudo systemctl restart zero-backend
停掉它
sudo systemctl stop zero-backend
再起来
sudo systemctl start zero-backend
开机自启 / 取消
sudo systemctl enable / disable zero-backend
看日志
journalctl -u zero-backend -f
stop 是真的停,不会自愈——除非我们再 start。这和 kill 掉进程不一样
后端程序日志

三种不同的日志形式

1实时显示fastapi dev 占住一个终端,请求、print、traceback 全在眼前滚

窗口一关,全没了
2写进文件> backend.log 2>&1 把输出接进一个文件,能留存

写到哪儿、什么时候清理,全得自己记着
3交给 systemd委托出去的时候,日志也一并委托了

自动记录,有容量上限,旧的会被自动清理
123
journal = 日志,ctl = 控制

用 journalctl 看日志

journalctl -u zero-backend # 从头看 journalctl -u zero-backend -n 50 # 只看最后 50 行 journalctl -u zero-backend -f # 实时跟随
-u = unit
后面跟服务的名字,只看 zero-backend 的日志。这个参数必须写
-n 50
只看最后 50 行。不加的话,日志一多就很难找
-f = follow
实时跟随。敲完回车停住不动——不是卡住了,是在等后端下一次输出日志。Ctrl + C 退出
123
第二笔

现在的运行方式

用户的浏览器
拿到了页面
页面里的 JS
互联网
服务器
systemd
① 要页面
HTML · CSS · JS
✓访客日志记得又全又细
✓HTTPS一条命令
✓压缩缓存开一下就有
:80
Nginx
把 out/ 里的静态文件送出去
② 要数据
JSON
✗访客日志没有单独的一份
△HTTPS自己管证书
✗压缩缓存没有
:8000
Uvicorn
跑 FastAPI,落库到 SQLite
123456
换一下分工

Nginx 站到最前面

用户的浏览器
拿到了页面
页面里的 JS
互联网
服务器
① 要页面
HTML · CSS · JS
② 要数据
JSON
:80
Nginx
门房:对外的事全归它
找文件
文件
转交
结果
out/
静态文件
Nginx 自己就送了
屋里 · 只对接 Nginx
:8000
Uvicorn
只管跑 Python
123
不是再开一个端口

同一个 80 端口,按路径分工

用户的浏览器
互联网
服务器
//text-lab
/docs
/api/profile/api/analyze/api/history
:80
Nginx
/api/ 开头 → 转交 其他 → 找文件
找文件
✕
转交
out/
静态文件
屋里 · 只对接 Nginx
:8000
Uvicorn
12345
reverse proxy

反向代理

正向代理
访问者
正向代理替访问者转发
互联网
网站
访问者这一侧 网站这一侧
反向代理
访问者
互联网
反向代理替网站接收
网站
访问者这一侧 网站这一侧
123
8000 没有关,只是不对外

让 8000 不再对外

服务器 · 屋里
用户的浏览器
:80
:8000
✕ 安全组 · 屋外
0.0.0.0:8000✕
:80
Nginx
转交 127.0.0.1:8000
:8000
Uvicorn
第一刀 · 在屋里fastapi run --host 127.0.0.1后端只接受本机来的请求,外面直接来的进不了门
第二刀 · 在屋外安全组删掉 8000 的放行规则只留 22 和 80,8000 在墙外就被挡住
纵深防御:两道防线各自独立,哪怕一道失守,另一道还挡着
12
1同源了页面和接口同一个源,没有 OPTIONS 了
28000 对外关了从外面连 服务器IP:8000,连不上
3它自己会重启kill 掉、重启服务器,都会自己起来
浏览器
http://服务器IP
同一个源 · 没有 OPTIONS
互联网
服务器
http://服务器IP/text-lab
http://服务器IP/api/analyze
服务器IP:8000✕从外面进不来:安全组没放行,Uvicorn 也只听 127.0.0.1
:80
Nginx
systemd 守护
找文件
转交
out/
静态文件
:8000
Uvicorn
只听 127.0.0.1systemd 守护
systemd 守着 Nginx 和 Uvicorn:开机自启 · 崩了自动重启 · 收着日志
123
https://example.com

下一节见

模块 7.3 · 域名与 HTTPS