本地项目云服务器部署
本地项目上线:云服务器部署流程
1. 文档目标
本文记录一个本地项目部署到云服务器并最终完成正式网站上线的流程。
部署目标包括:
将本地开发完成的项目运行到阿里云服务器
使项目能够通过公网访问
使用 Docker 作为运行环境
使用 Nginx 作为反向代理
后续接入域名解析与 HTTPS
本文不展开项目业务本身,只聚焦部署流程与部署过程中涉及的关键知识点。
2. 服务器登录与初始化
2.1 登录方式
在实际操作中,可以通过两种方式进入服务器:
阿里云 Workbench
本地终端通过 SSH 登录
补充说明:
Workbench 是阿里云提供的网页版远程终端
SSH 是一种远程登录协议,可以从本地终端直接连接服务器
Workbench 和 SSH 都能进入服务器,但入口不同
2.2 初始化服务器
服务器登录成功后,需要进行基础初始化:
更新软件包索引
安装基础工具
安装 Docker
验证 Docker 是否安装成功
创建项目部署目录
我的部署目录统一使用:
/opt/resume-assistant
这样做的好处是:
路径清晰
便于统一管理项目文件、配置文件和数据目录
符合 Linux 服务器上的项目部署习惯
3. 项目文件准备与上传
3.1 从 GitHub 拉取代码
服务器上的项目代码通过 GitHub 获取,而不是直接把整个开发目录复制到服务器。
这样做的好处是:
代码来源清晰
版本管理方便
后续更新代码有统一入口
3.2 配置运行环境变量
项目运行需要.env文件,服务器上需要单独创建和配置。
.env中主要包括:
模型提供商类型
API Key
服务监听地址
端口
超时配置
CORS 配置
collection 名称等
3.3 创建数据目录
项目运行过程中需要独立的数据目录,例如:
data/self_resume data/uploads data/chroma/self_resume data/chroma/uploaded_docs
这些目录用于保存:
私有 PDF 文件
上传文件
向量知识库数据
3.4 上传私密文件
一些内容不适合放进 GitHub,例如:
.env个人简历 PDF
本地生成的向量库
因此这些文件需要单独上传到服务器。
补充说明:
本地文件上传到服务器通常使用
scpscp基于 SSH 协议工作上传本地文件时,命令必须在本地终端执行,而不是在服务器终端执行
4. Docker 部署基础认知
Docker 在当前部署中的作用是:
为项目提供统一运行环境
避免服务器环境与本地环境不一致
方便项目迁移和重启
4.1 镜像与容器
部署过程中需要区分三个概念:
Docker:容器化工具
镜像:应用运行模板
容器:镜像运行后的实例
可以理解为:
镜像是“打包好的运行环境”
容器是“真正跑起来的实例”
4.2 镜像与容器的关系
镜像构建完成后,可以用镜像创建容器。
需要特别理解的是:
容器创建后就固定绑定到创建时的镜像
后续即使重新构建了同名镜像,旧容器也不会自动更新
发布新版本时,应删除旧容器,再基于新镜像启动新容器
4.3 tag 与 image ID
Docker 镜像有两个重要标识:
image ID:镜像真实身份tag:镜像标签,例如latest
同名重新构建镜像时,本质上不是原地修改旧镜像,而是:
创建新的镜像对象
让相同的 tag 指向新镜像
4.4 镜像大小相关字段
docker images中常见两个字段:
CONTENT SIZE:镜像内容本身大小DISK USAGE:镜像当前实际占用的磁盘空间估算
由于 Docker 镜像层可以共享,因此二者不一定相同。
5. 当前项目的 Docker 部署方案
5.1 原计划
最初的理想部署流程是:
服务器拉取最新代码
服务器直接执行
docker build服务器本地构建镜像
启动容器
5.2 实际问题
实际部署时发现:
阿里云服务器访问 Docker Hub 不稳定
Dockerfile 中的基础镜像
python:3.11-slim无法稳定拉取因此服务器本地
docker build失败
5.3 最终采用的方案
针对上述问题,最终采用以下部署策略:
在本地电脑构建最新镜像
在本地导出镜像为 tar 文件
使用
scp将镜像文件上传到服务器在服务器执行
docker load删除旧容器
使用新镜像重新启动容器
该方案的本质是:
本地 build,服务器 run
这是当前环境下更稳定的发布方式。
6. 项目启动与服务验证
6.1 启动容器
容器启动时,需要:
指定环境变量文件
.env指定端口映射
将服务器本地
data/目录挂载到容器内
挂载数据目录的好处是:
向量库不会因为容器重启而丢失
上传文件和私有 PDF 可持久保存
容器只是运行环境,数据仍保留在服务器磁盘上
6.2 初始化知识库
个人网站项目中,仅上传 PDF 还不够,还需要执行灌库流程。
灌库过程通常包括:
读取 PDF
切分文本
调用 embedding 模型
写入 Chroma 向量库
完成灌库后,问答助手才能基于知识库检索并回答问题。
6.3 服务检查
部署完成后,通过以下接口验证服务状态:
/health/ready
其中:
/health用于检查服务是否正常启动/ready用于检查服务是否真正具备可用条件,例如:是否存在个人简历 PDF
模型配置是否正常
运行环境是否完整
6.4 公网访问
服务启动后,需要在阿里云控制台放行应用端口,例如:
8008
放行后即可通过公网 IP + 端口访问网站。
7. 部署过程中的问题排查
部署过程中遇到过多类问题,排查思路如下。
7.1 Docker Hub 拉取失败
现象:
docker build无法拉取基础镜像构建过程卡在
python:3.11-slim
原因:
服务器无法稳定访问 Docker Hub
解决方式:
改为本地构建镜像并上传服务器
7.2 API Key 认证失败
现象:
模型调用返回
401灌库失败
原因可能包括:
API Key 错误
key 中包含隐藏空格
.env修改后容器未重启新 key 未正确传入容器
解决方式:
更新
.env重启容器
再次执行灌库
7.3 公网无法访问
现象:
本机
curl可访问浏览器公网无法访问
原因:
云平台防火墙未放行端口
解决方式:
在阿里云控制台放行相应端口
7.4 前端Failed to fetch
现象:
网站页面能打开
问答助手请求失败
原因:
前端 API 请求地址写死为
127.0.0.1或者线上运行的容器仍是旧版本镜像
需要理解的是:
服务器上的源码不一定等于容器中实际运行的代码
本地修复代码后,如果没有重新 build 镜像并替换容器,线上仍然会运行旧逻辑
7.5 代码版本与容器版本不一致
这是部署中非常关键的认知:
服务器目录里的代码只是源码
容器运行的是镜像打包时的代码快照
如果镜像没更新,线上效果就不会更新
8. Nginx 反向代理认知
8.1 Nginx 的作用
Nginx 是一个 Web 服务器,也可以作为反向代理服务器。
在本次部署中,Nginx 的作用是:
接收公网标准端口请求
将请求转发给 Docker 容器中的应用服务
8.2 为什么需要反向代理
在 Docker 部署完成后,项目最初是通过以下方式访问的:
http://公网IP:8008/
这种方式虽然可用,但不够正式。
引入 Nginx 后,可以将访问入口改为:
http://公网IP/
即:
用户访问 80 端口
Nginx 转发到
127.0.0.1:8008
8.3 反向代理的访问链路
引入 Nginx 后,访问链路变为:
浏览器 → Nginx → FastAPI 容器 → 项目服务
这是一种更标准的线上部署方式,也为后续域名和 HTTPS 做好了准备。
9. Nginx 实操配置
9.1 安装 Nginx
在服务器上安装 Nginx 后,需要:
创建新的站点配置文件
配置反向代理规则
启用站点配置
删除默认站点
测试配置语法
重启或重载 Nginx
9.2 反向代理核心配置
核心思路是:
监听 80 端口
将
/请求转发到127.0.0.1:8008
9.3 默认页问题
部署过程中曾出现:
Welcome to nginx!
这说明:
Nginx 本身已安装成功
但默认站点配置仍在生效
自定义反向代理配置未真正接管请求
解决方式:
删除默认站点配置
启用自定义站点配置
reload Nginx
9.4 放行 80 端口
Nginx 配置完成后,还需要在阿里云控制台放行:
80/tcp
放行成功后,网站即可通过不带端口的公网 IP 访问。
10. 域名解析
10.1 域名的作用
公网 IP 可以访问网站,但不适合作为长期正式入口。
域名的作用是:
提供更易记的网址
让网站更专业
为 HTTPS 配置做准备
10.2 域名解析的意义
域名解析的本质是:
将域名指向服务器公网 IP
当域名解析完成后,访问入口将从:
http://公网IP/
变为:
http://你的域名/
10.3 接入域名后需要做的事
域名解析完成后,还需要:
修改 Nginx 的
server_name让 Nginx 对域名请求生效
11. HTTPS 配置
11.1 为什么需要 HTTPS
HTTPS 的意义包括:
提供加密传输
避免浏览器提示“不安全”
让网站更像正式线上服务
满足个人网站上线的完整体验
11.2 HTTPS 与域名的关系
通常情况下,正式 HTTPS 证书绑定的是域名,而不是裸公网 IP。
因此实际步骤通常是:
域名解析到服务器
配置 Nginx
server_name申请 SSL 证书
在 Nginx 中启用 HTTPS
将 HTTP 跳转到 HTTPS
11.3 当前阶段状态
当前部署已完成:
云服务器部署
Docker 运行
Nginx 反向代理
公网访问
后续待完成:
域名解析正式生效
配置 HTTPS
形成最终正式网站入口
12. 当前部署架构总结
当前网站架构可以概括为:
浏览器 → 公网 IP / 域名 → Nginx → Docker 容器 → FastAPI 项目 → 知识库 / 模型 API
当前项目的发布策略为:
本地修改代码 → 本地构建镜像 → 本地导出镜像 → 上传到服务器 → 服务器导入镜像 → 删除旧容器 → 启动新容器
这是一种适合当前网络环境的稳定发布方式。
13. 附录:常用命令清单
13.1 SSH 登录
ssh admin@服务器公网IP
13.2 SCP 上传文件
scp 本地文件 admin@服务器公网IP:服务器目录
13.3 Docker 常用命令
查看镜像:
sudo docker images
查看容器:
sudo docker ps
删除容器:
sudo docker rm -f 容器名
导入镜像:
sudo docker load -i 镜像文件.tar
启动容器:
sudo docker run ...
查看磁盘占用:
sudo docker system df
清理悬空镜像:
sudo docker image prune -f
13.4 服务检查
curl http://127.0.0.1:8008/health curl http://127.0.0.1:8008/ready
13.5 Nginx 常用命令
测试配置:
sudo nginx -t
重启:
sudo systemctl restart nginx
重载配置:
sudo systemctl reload nginx
查看状态:
sudo systemctl status nginx --no-pager
13.6 端口检查
sudo ss -ltnp | grep 8008
