内外网 Web 信息系统技术栈与学习部署路线
1. 文档目的
本文用于指导一个已有 Vue 前端的网页系统,从本机开发开始,依次完成:
- Vue 与 FastAPI 联调;
- 表单数据保存与查询;
- 部署到公司内网服务器;
- 使用 Django 替换 FastAPI 测试后端;
- 支持多个页面或多个网站;
- 在公司 IT 与安全规范允许的前提下扩展到外网访问。
推荐的总体策略是:
先用 FastAPI 学会完整的数据流和部署方式,再用 Django + Django REST Framework 建设正式后端;前端、API 地址和数据格式尽量保持不变。
FastAPI 到 Django 不是直接升级,而是后端实现的替换。只要提前固定 API 契约,Vue 前端通常不需要重写。
2. 总体架构
2.1 本机开发阶段
text
浏览器
│
├─ 页面请求 ───────→ Vue 开发服务器(通常为 5173 端口)
│ │
│ │ /api/v1/* 开发代理
│ ▼
└─ 数据请求 ───────→ FastAPI(8000 端口)
│
▼
SQLite
这一阶段不需要 Nginx/OpenResty,也不需要 1Panel。
2.2 内网部署阶段
text
内网用户浏览器
│
▼
https://portal.company.example
│
▼
OpenResty / Nginx
├─ / → Vue 构建后的 dist 文件
└─ /api/v1/* → FastAPI 或 Django(127.0.0.1:8000)
│
▼
PostgreSQL
2.3 后续外网访问
如果外部访问者只是公司员工,优先使用:
text
外部员工 → 公司 VPN/零信任平台 → 内网 OpenResty → Django → PostgreSQL
如果网站需要真正公开到互联网,应由公司 IT 规划:
text
互联网
↓
公共 DNS
↓
公司防火墙 / WAF / 应用发布网关
↓
OpenResty / Nginx
↓
Django
↓
PostgreSQL(不对互联网开放)
不建议个人自行在公司路由器上配置端口映射。
3. 推荐技术栈
| 层级 | 学习/测试阶段 | 正式阶段 | 主要作用 |
|---|---|---|---|
| 前端 | 现有 Vue 项目 | 现有 Vue 项目 | 页面、表单、数据展示和用户交互 |
| 前端工具 | Node.js、npm、现有 Vite 或 Vue CLI | 构建时使用 | 安装依赖、启动开发环境、构建 dist |
| HTTP 请求 | fetch 或项目已有的 Axios |
同左 | 调用 /api/v1/* 接口 |
| 测试后端 | FastAPI | 完成学习后替换 | 快速建立 API,理解请求、校验和响应 |
| 正式后端 | 暂不使用 | Django + Django REST Framework | 数据模型、权限、管理后台和正式 API |
| 测试数据库 | SQLite | 不建议长期多人使用 | 本机快速验证数据持久化 |
| 正式数据库 | 可提前学习 PostgreSQL | PostgreSQL | 多用户业务数据存储 |
| Web 入口 | 开发阶段暂不需要 | OpenResty/Nginx | 提供 Vue 文件、HTTPS、反向代理和访问日志 |
| 运维界面 | 可选 | 1Panel(须经公司 IT 同意) | 图形化管理网站、证书、容器、数据库和备份 |
| 操作系统 | Windows 开发机 | 公司支持的 Linux 服务器 | 稳定运行 Web 服务 |
| 进程管理 | 手动启动 | systemd、容器或公司部署平台 | 开机启动、异常重启和运行状态管理 |
| 外部入口 | 无 | VPN、零信任平台或公司应用网关 | 安全地提供外部访问 |
3.1 Node.js 的定位
Node.js 主要用于 Vue 的开发和构建,不一定需要在正式服务器上持续运行。
powershell
npm install
npm run dev
npm run build
最终通常产生:
text
frontend/dist/
OpenResty/Nginx负责把 dist 中的文件返回给浏览器。
3.2 1Panel 的定位
1Panel 是安装在 Linux 服务器上的图形化运维面板,可以管理:
- OpenResty网站和反向代理;
- 域名与HTTPS证书;
- Python等运行环境;
- Docker容器;
- PostgreSQL等数据库;
- 防火墙、日志、计划任务和备份。
1Panel不负责开发Vue页面,也不负责生成FastAPI/Django业务代码。普通用户访问业务网站,不访问1Panel管理页面。
4. 必须提前固定的设计约定
这些约定决定以后从内网扩展到外网、从FastAPI切换到Django时是否需要修改前端。
4.1 Vue只访问相对API地址
推荐:
javascript
fetch('/api/v1/submissions')
不推荐:
javascript
fetch('http://192.168.1.50:8000/api/submissions')
原因:内网IP、端口或后端技术变化时,相对地址通常不需要修改。
4.2 固定API前缀和版本
text
/api/v1/health
/api/v1/submissions
/api/v1/users
/api/v1/reports
4.3 固定请求和响应格式
示例请求:
json
{
"applicant_name": "张三",
"department": "质量部",
"content": "提交内容"
}
示例成功响应:
json
{
"success": true,
"data": {
"id": 123
},
"message": "提交成功"
}
示例错误响应:
json
{
"success": false,
"data": null,
"message": "部门不能为空",
"errors": {
"department": ["该字段不能为空"]
}
}
4.4 前端环境变量不能保存秘密
Vue/Vite中的变量会进入浏览器端代码。数据库密码、Django密钥、第三方服务密钥等只能保存在服务器端环境变量或公司密钥系统中。
4.5 同一个域名提供前端和API
推荐:
text
https://portal.company.example/
https://portal.company.example/api/v1/*
相比"前端和后端使用不同域名",这种方式更容易处理登录Cookie、CSRF和CORS。
5. 分阶段开发与部署路线
阶段0:检查现有Vue项目
要做的事
- 找到项目根目录下的
package.json; - 查看
scripts中实际存在的命令; - 确认使用Vite还是较早的Vue CLI;
- 找出项目中所有
fetch、Axios和后端地址; - 确认是否使用Vue Router;
- 确认是否有文件上传、登录和权限相关代码。
查看可用命令:
powershell
npm run
常见启动方式:
powershell
npm install
npm run dev
或者:
powershell
npm install
npm run serve
学习目标
- 认识
package.json; - 理解npm依赖、开发服务器和生产构建;
- 能区分Vue源代码与构建后的
dist; - 能在浏览器开发者工具中查看网络请求和错误。
验收标准
- Vue项目可以稳定启动;
- 知道正确的构建命令;
- 能列出当前页面需要提交的全部字段;
- 能指出前端当前请求后端的位置。
阶段1:建立最小FastAPI后端
建议目录:
text
information-system/
├─ frontend/ 现有Vue项目
└─ backend-fastapi/
├─ app/
│ └─ main.py
├─ data/
└─ requirements.txt
Windows开发环境:
powershell
cd backend-fastapi
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install "fastapi[standard]"
fastapi dev app/main.py
第一批接口:
text
GET /api/v1/health
POST /api/v1/submissions
GET /api/v1/submissions
学习目标
- HTTP的GET、POST和状态码;
- JSON请求和响应;
- 路径参数、查询参数和请求体;
- Pydantic数据校验;
- FastAPI自动生成的
/docs接口页面; - 如何查看后端日志和错误。
验收标准
/api/v1/health返回正常状态;- 可以在
/docs中提交一条测试数据; - 缺少必填字段时能够返回明确错误;
- 数据暂时不落库也可以,先跑通请求链路。
阶段2:Vue与FastAPI联调
如果现有项目使用Vite,可在 vite.config.js 或 vite.config.ts 中配置开发代理:
javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true
}
}
}
})
调用示例:
javascript
const response = await fetch('/api/v1/submissions', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
const result = await response.json()
学习目标
- 浏览器同源、跨域和CORS;
- Vite开发代理;
- 异步请求、加载状态和错误提示;
- 前端表单校验与后端校验的区别;
- 不在前端写死IP和端口。
验收标准
- 用户可以在Vue页面填写并提交;
- 提交时有加载状态,成功和失败有明确提示;
- FastAPI能够收到正确数据;
- 浏览器控制台没有未处理错误;
- Vue代码只使用
/api/v1/*相对地址。
阶段3:加入SQLite数据持久化
建议学习:
- 数据表、主键和字段类型;
- 唯一约束和非空约束;
- 创建、查询、修改和删除;
- 分页、筛选和排序;
- 创建时间、更新时间和操作用户;
- 数据库事务;
- SQLAlchemy基础;
- 可选:Alembic数据库迁移。
第一版建议数据字段至少包括:
text
id
applicant_name
department
content
status
created_at
updated_at
注意
FastAPI + SQLAlchemy的数据模型不会自动变成Django模型。此阶段的数据应当视为测试数据,或者提前准备CSV/JSON导入导出方案。
验收标准
- 后端重启后数据仍然存在;
- 可以查看提交列表和单条记录;
- 可以按字段查询或筛选;
- 数据库错误不会直接显示给普通用户;
- 能导出测试数据,便于后续迁移。
阶段4:申请服务器并完成内网试部署
推荐向公司申请
优先申请公司现有虚拟化平台中的Linux虚拟机,而不是个人办公电脑。
建议起步配置:
text
CPU:4核
内存:8GB
磁盘:100~200GB SSD
网络:固定内网IP,千兆网络
系统:公司支持的Linux长期维护版本
备份:公司备份平台或另一台独立存储设备
访问量很低且没有大附件时,2核、4GB内存也可用于试运行。服务器容量主要取决于并发用户、查询复杂度和附件大小,而不是页面数量。
交给公司IT的申请描述
申请一台用于内网Web应用测试及后续正式部署的Linux虚拟机。建议4核CPU、8GB内存、100GB以上SSD和固定内网IP。服务器计划运行OpenResty/Nginx、Python FastAPI/Django和PostgreSQL。需要内网DNS、HTTPS访问、管理员维护通道、独立备份位置,以及后续通过公司VPN、零信任平台或应用网关提供外部访问的可能性。Python应用端口和数据库端口不直接向用户网络或互联网开放。
服务器端口规划
| 端口 | 用途 | 建议开放范围 |
|---|---|---|
| 80 | HTTP跳转到HTTPS | 按公司策略开放 |
| 443 | 用户访问网站 | 内网用户,后续可由外网网关访问 |
| 8000 | FastAPI/Django | 仅服务器本机或指定反向代理 |
| 5432 | PostgreSQL | 仅服务器本机或指定应用服务器 |
| 22 | Linux管理 | 仅管理员网络或VPN |
| 1Panel面板端口 | 服务器管理 | 仅管理员IP、VPN或管理网 |
是否使用1Panel
适合以下情况:
- 公司IT允许安装;
- 目前没有统一运维平台;
- 需要图形化管理多个小型网站;
- 使用者尚不熟悉Linux命令和OpenResty配置。
如果公司已有统一容器平台、自动化部署、数据库、备份和安全审计系统,应优先遵循公司平台,不额外安装1Panel。
使用1Panel时的部署步骤
- 由管理员在Linux服务器上安装1Panel;
- 安装并启用OpenResty;
- 安装PostgreSQL,数据库端口不对外开放;
- 准备Python运行环境或部署Python容器;
- 执行
npm run build生成Vue的dist; - 上传
dist并创建静态网站; - 将
/api/反向代理至127.0.0.1:8000; - 配置内网域名和HTTPS;
- 配置数据库、网站和配置文件备份;
- 测试服务器重启后服务能否自动恢复。
OpenResty/Nginx核心配置概念
nginx
server {
listen 80;
server_name portal.company.example;
root /srv/information-system/frontend/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8000;
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_set_header X-Forwarded-Proto $scheme;
}
}
在1Panel中通常通过图形界面建立网站和反向代理,不建议同时手工修改同一份配置,以免配置漂移或被覆盖。
验收标准
- 任意授权内网电脑可以通过域名访问;
- 用户只接触80/443端口;
- Python端口和数据库端口不能被普通用户直接访问;
- Vue路由页面刷新不会出现404;
- 服务器重启后网站、后端和数据库自动恢复;
- 备份保存到服务器之外,并完成一次恢复验证。
阶段5:学习Django并替换FastAPI
推荐学习顺序:
- Django项目与Django App;
- URL路由;
- Model数据模型;
- Migration数据库迁移;
- Django Admin管理后台;
- 用户、用户组和权限;
- Django REST Framework;
- Serializer;
- APIView、ViewSet和Router;
- Session登录、CSRF和权限控制;
- 日志、测试和部署设置。
建立环境的典型命令:
powershell
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install Django djangorestframework
django-admin startproject config .
python manage.py startapp submissions
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
推荐目录:
text
backend-django/
├─ manage.py
├─ config/
│ ├─ settings.py
│ ├─ urls.py
│ ├─ asgi.py
│ └─ wsgi.py
├─ users/
├─ submissions/
├─ reports/
└─ tests/
替换策略
FastAPI已有:
text
POST /api/v1/submissions
GET /api/v1/submissions
Django REST Framework应实现完全相同的:
- URL;
- 请求字段;
- 成功响应;
- 错误响应;
- 状态码;
- 分页和筛选格式。
完成后只需要让OpenResty将 /api/ 从FastAPI进程切换到Django进程,Vue无需感知后端变化。
登录建议
如果系统主要由浏览器访问并且前后端使用同一域名,优先学习Django Session登录:
- 使用Django标准登录流程;
- Vue对POST、PUT、PATCH、DELETE请求携带CSRF令牌;
- Django REST Framework设置身份认证和权限类;
- 不要只隐藏前端按钮,后端必须再次验证权限。
验收标准
- Django提供与FastAPI相同的API;
- Vue不修改业务接口即可继续运行;
- 管理员可以通过Django Admin管理基础数据;
- 普通用户与管理员权限正确隔离;
- 测试数据完成导入或明确废弃;
- 接口具备最基本的自动化测试。
阶段6:正式内网运行
数据库
正式多人使用时推荐PostgreSQL。至少做到:
- 为应用创建独立数据库用户;
- 不使用数据库超级管理员账号运行应用;
- 只监听本机或指定应用服务器地址;
- 每日自动备份;
- 备份复制到另一台设备;
- 定期执行恢复演练。
Django部署检查
正式部署前执行:
powershell
python manage.py check --deploy
重点检查:
DEBUG = False;- 正确设置
ALLOWED_HOSTS; - 密钥通过服务端环境变量提供;
- 正确设置
CSRF_TRUSTED_ORIGINS; - 启用HTTPS后设置安全Cookie;
- 反向代理与Django正确处理HTTPS状态;
- 管理后台不对匿名用户开放;
/docs、调试页面和错误堆栈不向普通用户暴露;- 日志不记录密码、令牌和完整敏感数据。
运维
- Python进程开机自动启动;
- 异常退出后自动重启;
- 监控CPU、内存、磁盘和数据库连接;
- 监控证书到期、备份失败和服务不可用;
- 制定升级、回滚和维护窗口;
- 定期更新Linux、1Panel、OpenResty、Python依赖和数据库。
阶段7:扩展至外网访问
优先级
- 只有公司员工访问:公司VPN或零信任平台;
- 指定合作方访问:公司应用网关、强身份认证、访问白名单;
- 公众访问:公网域名、WAF、HTTPS、限流和完整安全评审。
为平滑过渡提前做好
- 使用公司拥有的域名,不依赖裸IP;
- 前端只访问
/api/v1/*; - 内外网使用相同域名时,可由IT配置内外DNS解析;
- 所有用户访问统一经过OpenResty/Nginx;
- Django和PostgreSQL继续位于内网或受保护网络;
- 账号权限、日志和HTTPS在内网阶段就启用;
- 附件上传限制类型和大小,并考虑病毒扫描;
- 管理员账号启用MFA;
- 公开表单增加频率限制和滥用防护。
1Panel管理面的安全要求
即使业务网站开放外网,也不要让1Panel管理页面对整个互联网开放。至少配置:
- 只允许管理员IP、管理网或VPN访问;
- 启用面板HTTPS;
- 启用MFA;
- 使用独立且高强度密码;
- 设置安全入口和域名绑定;
- 不直接开放数据库、容器管理和Python应用端口;
- 定期检查登录和操作日志。
6. 多页面和多网站的组织方式
| 情况 | 推荐方式 | 是否新增OpenResty配置 |
|---|---|---|
| 一个Vue项目中的多个页面 | 使用Vue Router,例如 /submit、/records、/reports |
通常不需要 |
| 同一业务的多个后端模块 | 一个Django项目建立多个App | 通常不需要 |
| 多个相互独立的Vue项目 | 每个项目独立构建,使用不同子域名 | 每个站点一个配置 |
| 需要严格隔离的独立系统 | 独立后端进程、数据库用户和目录 | 需要 |
推荐域名示例:
text
forms.company.example 信息提交
quality.company.example 质量管理
reports.company.example 报表系统
同一台服务器和一个OpenResty可以根据域名把请求分配给不同Vue目录和Python服务:
text
forms.company.example → Vue A → Python 8001
quality.company.example → Vue B → Python 8002
reports.company.example → Vue C → Python 8003
如果这些页面共享用户、权限和数据,优先合并为一个Vue门户和一个Django项目,避免过早拆分成多个服务。
7. 推荐学习路径
学习模块A:Web基础
需要掌握:
- 浏览器、服务器、请求和响应;
- URL、域名、IP和端口;
- HTTP方法和常用状态码;
- JSON;
- Cookie、Session、CORS和CSRF的基本概念;
- 浏览器开发者工具的Network和Console页面。
建议资料:
学习模块B:现有Vue项目
需要掌握:
package.json和npm脚本;- Vue组件、响应式数据和事件;
- 表单绑定;
- Vue Router;
fetch或Axios;- Vite开发代理;
npm run build与dist。
建议资料:
学习模块C:FastAPI
需要掌握:
- 路由和HTTP方法;
- Pydantic请求模型;
- 参数校验;
- 异常和状态码;
- 依赖注入的基本概念;
- SQL数据库基础;
- 自动API文档;
- CORS和部署进程。
建议资料:
学习模块D:数据库和PostgreSQL
需要掌握:
- 表、行、列和主键;
- 字段类型和约束;
- 增删改查;
- 索引;
- 事务;
- 数据库用户和权限;
- 备份与恢复。
建议资料:
学习模块E:Django和Django REST Framework
需要掌握:
- Project与App;
- Model、Migration和ORM;
- Admin;
- 用户、组和权限;
- Serializer;
- ViewSet与Router;
- Session认证与CSRF;
- 测试;
- 正式部署设置。
建议资料:
学习模块F:Linux、OpenResty/Nginx和1Panel
需要掌握:
- Linux目录、文件权限和进程;
- 服务端口和防火墙;
- 静态文件;
- 反向代理;
- 域名和DNS;
- HTTPS证书;
- 服务开机启动;
- 日志定位;
- 备份恢复;
- 1Panel管理面与业务网站的区别。
建议资料:
学习模块G:内外网和安全
需要掌握:
- 内网IP、固定地址和DNS;
- 防火墙和端口范围;
- VPN、零信任和反向代理入口;
- HTTPS和证书续期;
- 密码、MFA和最小权限;
- 上传文件安全;
- 日志、监控和备份恢复;
- 为什么数据库不能暴露到互联网。
建议资料:
8. 建议用来练习的最小业务功能
不要一开始开发全部正式功能,按以下顺序练习:
/api/v1/health健康检查;- 提交一条信息;
- 保存到数据库;
- 显示提交列表;
- 查看一条记录;
- 修改状态;
- 按部门、状态和时间筛选;
- 用户登录;
- 普通用户与管理员权限;
- 导出CSV或Excel;
- 操作日志;
- 文件上传;
- 部署到内网;
- 备份和恢复;
- 再替换为Django实现。
每完成一步都应同时验证:
- 正常数据;
- 缺少字段;
- 错误格式;
- 未登录访问;
- 无权限访问;
- 服务或数据库暂时不可用;
- 重复提交。
9. 不建议采用的做法
- 把后端IP和端口写死在Vue组件中;
- 使用Vue环境变量保存数据库密码或服务密钥;
- 将Vite开发服务器作为正式网站;
- 将FastAPI/Django开发服务器作为正式服务;
- 让PostgreSQL直接暴露给普通用户网络或互联网;
- 为方便调试长期保持
DEBUG = True; - 只备份在原服务器磁盘上;
- 只创建备份但从不验证恢复;
- 业务网站开放外网时顺便开放1Panel管理端口;
- 未经公司IT审批自行做公网端口映射;
- 一开始就同时学习Vue重构、FastAPI、Django、Docker和外网部署。
10. 里程碑与完成标准
| 里程碑 | 可交付结果 | 完成标准 |
|---|---|---|
| M1 Vue可运行 | 现有页面正常打开 | 知道启动和构建命令 |
| M2 FastAPI可运行 | /docs 和健康检查 |
能测试GET/POST |
| M3 前后端联调 | Vue成功提交 | 使用相对 /api/v1 地址 |
| M4 数据持久化 | SQLite保存记录 | 重启后数据存在 |
| M5 内网试部署 | 内网域名可访问 | Vue、API、数据库均正常 |
| M6 PostgreSQL | 正式数据库 | 权限、备份和恢复可用 |
| M7 Django替换 | 相同API由Django实现 | Vue基本不修改 |
| M8 权限与管理 | 登录、角色、Admin | 后端正确验证权限 |
| M9 正式内网运行 | 稳定服务 | 自启动、日志、监控、备份完备 |
| M10 外部访问 | VPN或公司网关接入 | 通过IT和安全审查 |
11. 当前建议的下一步
现在先完成以下四件事:
- 检查现有Vue项目的
package.json,确认启动和构建命令; - 列出页面需要提交、查询和修改的数据字段;
- 建立最小FastAPI项目,实现
/api/v1/health和/api/v1/submissions; - 让Vue通过相对地址
/api/v1/submissions完成第一次提交。
完成这四项后,再加入SQLite。等本机闭环稳定后,再申请Linux虚拟机并学习1Panel/OpenResty部署。不要在本机接口尚未跑通时提前处理公网访问。
12. 最终推荐方案摘要
text
开发:
Vue + Node.js/npm + Vite(或项目现有工具)
FastAPI + SQLite
内网试运行:
Linux虚拟机
1Panel(可选)
OpenResty/Nginx
Vue dist
FastAPI
PostgreSQL
正式系统:
Linux虚拟机
OpenResty/Nginx
Vue dist
Django + Django REST Framework
PostgreSQL
HTTPS + 日志 + 监控 + 异地备份
外部访问:
优先公司VPN/零信任
或公司WAF/应用网关
不直接暴露Python、数据库和1Panel管理端口