Skip to content

005. 后端发版与网络安全边界

学习目标

这一节把后端项目部署到服务器,并补齐部署脚本、代码拉取、端口访问和安全边界的理解。

学完后,你应该能理解:

  • 服务器上拉代码为什么推荐使用 SSH Key;
  • 生产环境 .env 和本地 .env 为什么不一样;
  • 为什么生产数据库端口不应该一直对公网开放;
  • 容器内部端口、宿主机端口、防火墙端口分别是什么;
  • 后端发版脚本大概做了哪些事;
  • 前端、后端、静态资源为什么要统一访问入口。

后端发版脚本负责什么?

后端发版脚本不是神秘工具,本质上就是把一系列部署命令固定下来。

它通常会做这些事:

  • 进入后端项目目录;
  • 如果没有代码,就从仓库 clone;
  • 如果已有代码,就拉取最新代码;
  • 准备生产环境 .env
  • 激活 Python / Conda 环境;
  • 安装或更新依赖;
  • 重启后端服务;
  • 输出运行状态。

对只写过 JS 的同学来说,可以把它理解成把手动部署步骤写成一个脚本,类似把多个 pnpm installpnpm buildpm2 restart 组合起来。

用 SSH Key 拉代码

服务器要从代码仓库拉代码,有两种常见方式:

方式特点
HTTPS + 账号密码 / Token配置简单,但权限和凭据管理更麻烦
SSH Key更适合服务器部署,权限可单独控制

课程里更推荐用 SSH Key。

基本思路是:

  1. 在服务器上生成 SSH Key;
  2. 打印公钥内容;
  3. 把公钥添加到代码仓库的部署 Key 里;
  4. 服务器以后就能用 SSH 协议拉代码。

这样做的好处是:如果某台服务器以后不用了,只要删除对应部署 Key,这台服务器就不能再拉仓库代码。

~ 是什么?

Linux 里经常看到 ~

它表示当前用户的家目录。

如果当前登录用户是 root,那么:

bash
~

通常对应:

bash
/root

所以类似下面的路径:

bash
~/.ssh/id_rsa.pub

可以理解成当前用户家目录里的 SSH 公钥文件。

本地 .env 和生产 .env

本地开发环境和服务器生产环境的 .env 不一样。

本地开发时,你的后端代码跑在自己电脑上,但数据库、Redis、Milvus 可能连的是远程服务器:

txt
本地后端 -> 远程服务器数据库

生产环境里,后端代码也部署在服务器上,数据库服务也在同一台服务器上:

txt
服务器后端 -> 服务器本机数据库

所以生产 .env 里很多 Host 可以写成本机地址,例如 localhost 或容器网络里的服务名,而不是公网 IP。

生产环境不要暴露数据库端口

前面为了本地调试,可能把 MariaDB、PostgreSQL、Redis、Milvus 的端口放到了云服务器防火墙里。

但生产环境下,数据库端口不应该长期对公网开放。

原因很简单:

  • 数据库里有业务数据;
  • 端口暴露后会被扫描;
  • 密码弱或配置错误会有风险;
  • 真实企业里通常只允许内网访问数据库。

部署完成后,后端和数据库都在服务器内部,后端访问数据库不需要经过公网防火墙。公网只需要暴露 Web 入口即可。

容器端口、宿主机端口、防火墙端口

端口问题最容易混。

可以按三层理解:

层级例子说明
容器内部端口MariaDB 内部 3306数据库程序自己监听的端口
宿主机映射端口服务器 14148Docker 把外部请求转到容器内部
云防火墙端口是否放开 14148决定公网能不能访问这个端口

如果两个 MariaDB 容器内部都用 3306,没问题。只要宿主机映射端口不同即可,例如:

txt
服务器 14148 -> 容器 A 3306
服务器 14149 -> 容器 B 3306

外部连接时,关注的是服务器映射出来的端口,不是容器内部端口。

内部访问不走公网防火墙

当后端和数据库都在同一台服务器里时,后端访问数据库属于服务器内部通信。

这种访问不会从公网绕一圈,也不会被云服务器公网防火墙拦截。

这就是为什么生产环境可以关闭数据库公网端口:

  • 本地电脑不能直接连数据库;
  • 服务器内部后端仍然可以连数据库;
  • 外部用户只访问前端和后端 API。

前端为什么不在服务器上打包?

前端打包很吃内存。

课程里购买的学习服务器内存有限,同时已经部署了很多数据库和工具服务。如果再在服务器上跑前端构建,很容易把内存打满。

所以更合理的方式是:

  1. 在本地电脑打包前端;
  2. 生成静态资源;
  3. 上传到服务器;
  4. 由 Nginx / 宝塔站点托管这些静态文件。

这和很多公司里的 CI/CD 思路类似:构建和运行不一定发生在同一台机器上。

前端、后端、静态资源的访问入口

一个完整 Web 项目通常至少有三类资源:

  • 前端页面;
  • 后端 API;
  • 图片、文件、发票等静态资源。

如果它们分别用不同端口访问,例如:

txt
前端:http://IP:80
后端:http://IP:7003
静态资源:http://IP:8080

浏览器会遇到跨域问题,用户访问也不方便。

更理想的方式是只给外部一个统一入口:

txt
http://IP

然后由 Nginx 根据路径转发:

txt
/        -> 前端页面
/api     -> 后端服务
/upload  -> 静态资源

这样用户只需要记住一个 IP 或一个域名。

跨域不是靠“放开所有”解决

开发阶段为了方便,后端可能允许所有来源跨域访问。

但生产环境不应该随便允许所有网站请求你的后端接口。

更好的方向是:

  • 让前端、后端、静态资源尽量走同源入口;
  • 通过 Nginx 统一协议、域名或 IP、端口;
  • 后端生产配置里减少跨域放开范围;
  • 只允许自己的前端访问自己的后端。

跨域问题不是简单报错,而是浏览器安全模型的一部分。后面部署前端和 Nginx 时会继续处理它。

AI Agent 课程学习文档。