小鱼网站制作 SOP
从本地开发到服务器部署 域名注册 ICP备案与上线维护
版本 1.1 · 更新日期 2026年10月14日 · 面向第一次独立建站的同学
先读这一页
照这份手册完成一个网站:在Windows上写页面,在Ubuntu服务器上部署,用自己的域名访问,再学会修改、备份和排查故障。
小鱼的实际路线:本地开发 → 阿里云ECS → Nginx提供页面 → FastAPI处理业务 → SQLite保存数据。 主站用React/Vite,课表、调酒、建站手册等子页面则可以用独立HTML。它们共享服务器和域名,各自保留功能目录。
附带 starter/ 是一个可立即运行的练习:先做静态页面,再接一个后端接口。页面做出来后,才有必要扩展账号、记录和管理台。
先抓住五件事
- 功能决定架构。 页面展示和浏览器内文件转换可以只做前端;多人共享账号、积分和记录需要后端与数据库。
- 资源决定能否备案。 内地服务器、公网能力、购买周期和域名实名信息要在付款前核对。
- 备案与开发并行。 本地继续开发,首次ICP备案通过后再开放内地网站。参考 备案期间访问说明。
- 上线只发布运行需要的文件。 Vite发布
dist/;数据库独立存放;管理权限在后端检查。 - 每次更新留得住旧版本。 代码回滚与数据库恢复分别处理。
完成路线
确认网站用途与备案主体
↓
本地开发和验收 ←→ 购买域名及合格服务器 → 提交ICP备案
↓ ↓
准备发布包和服务器配置 审核通过
└──────────────────────┬───────────┘
↓
DNS解析 → 正式部署 → HTTPS
↓
开站验收 → 公安联网备案 → 持续维护
每个章节末尾给出验收结果,用它判断这一步是否完成。
01 先确定你究竟要做什么
1.1 写一张项目卡
先写清第一版的核心功能。例如,课表转换器处理一个文件;联赛助手保存四人的对局结果。再决定需要哪些页面、接口和数据。
| 项目 | 需要填的内容 |
|---|---|
| 网站名称 | 页面展示名称及拟申请的备案名称 |
| 使用者 | 面向哪些人 是否需要登录 |
| 核心功能 | 用户进入页面后完成的一件事 |
| 网站主办者 | 个人还是单位 谁持有云账号与域名 |
| 服务内容 | 是否有用户发布内容 注册 上传 投票 支付等 |
| 数据范围 | 收集什么 为什么收集 保存多久 如何删除 |
| 预算 | 首年总额 续费总额 备份及带宽费用 |
| 维护人 | 谁处理故障 续费 内容投诉和数据请求 |
1.2 备案手续分别做什么
| 手续 | 作用 | 何时办理 |
|---|---|---|
| 域名注册及实名认证 | 注册地址并确认持有人 | 购买域名后 |
| ICP备案 | 非经营性互联网信息服务备案 | 内地网站开通前 |
| 公安联网备案 | 网站的公安联网备案 | 开通后按要求提交 |
| 经营性ICP许可等资质 | 相应经营性或特定业务的准入 | 业务涉及时先确认办理路径 |
普通非经营性站点走备案流程;收费信息服务或特定行业,应先确认相应许可及前置手续。互联网信息服务管理办法
1.3 个人工具站和公开树洞的区别
备案看实际服务内容,不只看网页名称。 个人工具展示与面向公众的留言社区,在主体和内容要求上有区别。做树洞时,把留言、评论、上传等功能列清楚,向接入商确认该业务可采用的主体和备案路径;申请中的用途应与上线内容一致。网站信息填写规范
备案按主办者所在地省份规则办理;杭州只是小鱼服务器的机房地域。这两项填错,会影响材料准备和审核。
本阶段验收: 能用三句话说明网站用途、主办者和所需办理路径;确认拟上线的功能与该路径相符。
02 理解网站的基本结构
| 部件 | 通俗理解 | 小鱼式架构中的位置 |
|---|---|---|
| 前端 | 用户看到和点击的页面 | HTML CSS JS 或 React构建后的文件 |
| 后端 | 检查身份 权限及业务规则的服务 | FastAPI接口 |
| 数据库 | 保存账号 记录和业务数据 | SQLite 起步或其他合适数据库 |
| 服务器 | 全天运行网站的远程电脑 | 云服务器 |
| 域名 | 用户容易记住的地址 | 例如 example.com |
| DNS | 告诉浏览器域名对应哪个服务器 | A AAAA CNAME等解析记录 |
| Nginx | 对外提供页面并转发接口请求 | 公网80和443入口 |
| HTTPS证书 | 加密连接并验证访问的域名 | TLS证书及续期机制 |
浏览器 → DNS查找 → example.com上的Nginx
├─ / 静态页面
├─ /tools/ 工具子页面
└─ /api/ 仅转给本机后端 127.0.0.1:8000
管理台 admin.example.com → 后端身份及权限校验
数据库 /var/lib/fishsite/ → 与公开页面目录分开
小鱼的课表转换器可以在浏览器内处理文件;调酒记录、联赛积分则由后端存储。先按功能选择架构,静态站只部署前端即可。
本手册的两条练习路线
- 必做路线: 附带的HTML CSS JS练习站。本地无需Node.js,发布时直接上传前端文件。
- 进阶路线: 附带的FastAPI健康检查接口。再往后才是React/Vite、账号、数据库及管理台。
03 准备本地开发环境
3.1 安装哪些工具
| 工具 | 必要程度 | 官方入口 |
|---|---|---|
| 代码编辑器 | 必需 可选自己熟悉的编辑器 | https://code.visualstudio.com/ |
| 浏览器及开发者工具 | 必需 | 使用现有Edge或Chrome即可 |
| Python | 本教程本地服务及进阶后端需要 | https://www.python.org/downloads/ |
| Git | 建议 用于源码版本管理 | https://git-scm.com/downloads/ |
| OpenSSH客户端 | 部署时需要 | Windows设置中的可选功能或系统现有工具 |
| Node.js及npm | 只有React/Vite等构建项目需要 | https://nodejs.org/en/download |
Windows可把软件和缓存放D盘、项目源码放独立项目目录。已有工具能用就直接复用。
在Windows PowerShell检查:
python --version
git --version
Get-Command ssh, scp
# 只有选择React/Vite路线时才检查下面两项
node --version
npm --version
python找不到时,检查安装及应用执行别名,也可试 py --version。安装后重新打开终端。PowerShell拦截 npm.ps1 时,使用 npm.cmd运行相同命令即可。
3.2 建立清楚的项目目录
fishsite/
├─ frontend/ 页面源码或React项目
├─ backend/ 后端源码 如有需要
├─ ops/ Nginx及服务配置模板
├─ docs/ 规则 使用说明和维护说明
├─ backups/ 本地备份 不提交公开仓库
├─ .gitignore
└─ README.md
将教学包中的 starter/ 复制或重命名为 D:\Projects\fishsite。源码、部署配置、说明和备份按上面的目录存放。
3.3 设置版本管理边界
.gitignore负责排除环境文件、数据库、私钥、依赖和备份。提交前用 git status查看文件列表,再添加源码。
Set-Location "D:\Projects\fishsite"
git init
git status --short
# 添加本次需要保存的源码
git add frontend backend ops README.md .gitignore
git diff --cached --stat
git commit -m "Create first website"
commit保存本地版本,push上传到远程仓库。私钥和生产配置放在项目之外,团队共享源码和示例配置。
本阶段验收: 能打开终端、运行工具检查;知道源码、依赖、构建文件和秘密分别在哪里。
04 在本地完成第一版网页
4.1 运行附带的静态练习站
在练习项目目录运行下列命令。127.0.0.1表示只在这台电脑上访问。
Set-Location "D:\Projects\fishsite"
python -m http.server 8080 --bind 127.0.0.1 --directory frontend
浏览器打开 http://127.0.0.1:8080。仍使用教学包原始目录时,先进入 starter。按 Ctrl+C结束服务。
练习站有主题切换和一个后端检查按钮;仅启动静态服务时,后端检查提示未连接是正常的,不代表网页无法运行。
4.2 完成四个小练习
- 在
frontend/index.html修改标题、简介和三张卡片的文字。 - 在
frontend/styles.css修改一种主题颜色,观察手机宽度下的排列。 - 在
frontend/app.js找到主题按钮,理解点击后保存到本机浏览器的逻辑。 - 使用浏览器开发者工具的Network和Console,确认没有缺失的CSS、JS和图片。
完成这四项后,你就掌握了页面内容、样式、交互和调试入口,再按项目需要增加功能。
4.3 借助AI时怎么下达任务
把目标、文件结构和验收方式一起交给AI,效果比“帮我做个网站”更稳定:
请制作一个中文个人工具展示页。
第一版只包含标题 三张工具卡片 手机适配和返回首页入口。
使用HTML CSS JS 先给出文件结构 再实现。
给出本地启动命令。
检查320px和1440px宽度 确认按钮和链接可用。
现有功能保持不变 新增功能完成后说明修改的文件。
4.4 如果你选择React和Vite
小鱼树洞主站使用React/Vite。选择这条路线时,在新的 fishsite-react 目录创建项目:
npm create vite@latest fishsite-react -- --template react
Set-Location fishsite-react
npm install
npm run dev -- --host 127.0.0.1
根据终端显示打开本地地址。准备发布时:
# 已有package-lock.json的项目建议用npm ci复现依赖
npm ci
npm run build
npm run preview -- --host 127.0.0.1
开发看源码,上线发 dist/。 npm run build生成发布文件;npm run preview用于本地检查。当前Vite指南的Node.js要求为20.19+或22.12+。Vite官方指南
4.5 本地验收清单
05 选择并购买服务器
5.1 购买前先做备案可行性检查
按小鱼的路线选择阿里云中国内地ECS,备案也在阿里云办理;域名可以在其他符合备案要求的服务商注册。
付款前检查三项:内地节点、包年包月、公网带宽。 当前ECS备案条件还要求累计购买时长大于3个月,选择6个月或12个月比较直接。免费试用和按量实例应先在控制台核验或转换计费方式。备案前准备
5.2 教学起步配置
小鱼起步采用2核、2GiB内存、3Mbps带宽。这个配置适合轻量页面和小规模API;扩容看实际CPU、内存和网络占用。
| 项目 | 起步选择 | 判断方法 |
|---|---|---|
| 产品 | 可备案的ECS或接入商明确支持的产品 | 付款前验证备案资格 |
| 地域 | 中国内地且靠近主要使用者 | 不等于备案主体所在省份 |
| CPU及内存 | 2核2GiB可作为轻量起点 | 数据库 写入 图片处理多时评估4GiB |
| 系统 | 云平台官方Ubuntu LTS镜像 | 小鱼实例使用Ubuntu22.04 |
| 磁盘 | 如40GiB起步 并计划备份空间 | 看图片 数据库和日志增长 |
| 网络 | 具备公网访问能力 | 核对带宽 流量计费和公网IP |
| 购买周期 | 比较6个月及12个月 | 同时记录首购与续费价格 |
图多先优化传输。 3Mbps约等于0.375MB/s理论总速率,所有访问者共享。小鱼调酒有63款配图,采用WebP和延迟加载;建站手册是纯静态页面,无需新增后端。优先压缩图片和减少首屏请求,再根据监控决定加带宽或内存。
5.3 填一张费用表
| 费用项 | 首年实付 | 后续年度续费 | 是否自动续费 |
|---|---|---|---|
| 云服务器及系统盘 | 待填 | 待填 | 待填 |
| 公网带宽或流量 | 待填 | 待填 | 待填 |
| 域名 | 待填 | 待填 | 待填 |
| 备份及快照 | 待填 | 待填 | 待填 |
| 可选付费证书或其他服务 | 待填 | 待填 | 待填 |
ICP备案行政办理本身不收费;接入商提供的付费代办属于可选服务。通信管理局服务指南
5.4 购买后记录什么
- 网站主办者持有云账号并设置多因素验证。
- 确认地域、规格、磁盘、公网能力、周期和续费价格。
- 实例取名,如
fishsite-prod,便于区分正式站与测试站。 - 设置SSH密钥或独立的服务器登录口令。
- 记录公网IP、实例ID、到期日、账单和维护人。
本阶段验收: 实例运行、公网IP已记录、备案资格可用,首年和续费成本已算清。
06 注册域名和准备实名资料
域名按年注册和续费。选择容易记和输入的名称,比较首年、续费及转入价格。
6.1 操作顺序
- 在正规的域名注册服务商查询名称,确认可注册及后缀的备案适用性。
- 创建域名持有人信息模板,按真实主办者完成实名认证。
- 注册域名,确认域名状态正常、实名认证已通过。
- 保存域名证书,核对持有人与备案主体的一致性要求。
- 开启可控的续费提醒或自动续费,确认付款方式仍有效。
注册后查看实名认证状态,等待信息同步后提交备案。域名注册快速入门
6.2 准备材料
- 个人准备身份证件、手机号、邮箱和实际地址;单位准备证照及负责人材料。
- 域名实名持有人与备案主体按所在地要求保持一致。
- 写清网站名称、服务内容、域名和服务器信息。
- 在备案系统上传证件;源码包保存操作说明,证件单独存放。
本阶段验收: 域名实名通过,材料齐全,审核联系人能接电话和短信。
07 提交ICP备案并等待结果
7.1 应该在哪提交
域名注册商管域名,服务器接入商协助办理备案。采用阿里云ECS,就进入阿里云ICP备案系统;已有其他接入商备案的站点迁移到阿里云,需要办理相应接入手续。备案流程
7.2 办理步骤
- 校验主体、域名及云产品资格。同账号按系统引导选择实例,跨账号按服务码流程办理。
- 填主体信息、网站名称和实际用途。
- 上传资料,完成真实性核验。
- 接入商初审,按反馈补齐材料。
- 工信部短信核验。
- 管局审核通过,取得备案号。
短信核验要在收到后24小时内完成。 接入商的“订单已提交”通知与工信部核验短信是两条信息;以系统显示的核验人员名单逐一完成。短信核验指引
材料齐全的管局审核有20个工作日办理时限,项目计划还要加上初审、补正和节假日。备案服务指南
7.3 等待期间可以做什么
继续本地开发,并通过SSH配置服务器、在回环地址测试服务。首次备案等待期间,公网Web入口保持关闭;取得正式结果后开站。
7.4 收到结果后
在 工信部备案查询 核对结果,把取得的备案号放在首页底部并链接该入口。
本阶段验收: 正式结果已保存、可核对备案号、实际用途与申报一致;接入状态符合当前服务器要求。
08 初始化新服务器
新服务器先用云平台提供的初始账号登录;本例用 root完成初始化,随后用 deploy维护。已有服务器从检查目录和配置开始,跳过已完成的初始化步骤。
8.1 换成你自己的参数
| 示例值 | 实际应填什么 |
|---|---|
| example.com | 你的域名 |
| 203.0.113.10 | 你的服务器公网IPv4地址 |
| 198.51.100.20 | 你当前可信管理网络的公网IPv4地址 |
| fishsite | 你的独立项目名称 |
| v1 | 本次发布版本目录名 每次使用新名称 |
后续命令使用这张参数表。代码块上方的“Windows PowerShell”和“Ubuntu Bash”标明执行位置。
8.2 建立和验证SSH连接
Windows PowerShell:
ssh-keygen -t rsa -b 4096 -f "$env:USERPROFILE\.ssh\fishsite_rsa" -C "fishsite-deploy"
# 为本机私钥设置口令
Get-Content "$env:USERPROFILE\.ssh\fishsite_rsa.pub"
在ECS控制台导入 .pub 公钥,选择同地域实例绑定,按提示处理重启。私钥留在本机。本例用RSA,适配阿里云ECS的公钥导入流程。ECS登录凭据管理
完成绑定后再从Windows连接:
ssh -i "$env:USERPROFILE\.ssh\fishsite_rsa" root@203.0.113.10
首次连接时,将SSH提示的主机指纹与云控制台中下列命令的输出对照:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
在Ubuntu上初始化:
sudo apt update
sudo apt upgrade
sudo apt install nginx python3-venv sqlite3 ufw
sudo adduser deploy
sudo usermod -aG sudo deploy
给新用户安装你自己的同一份公钥:
sudo install -d -m 0700 -o deploy -g deploy /home/deploy/.ssh
sudoedit /home/deploy/.ssh/authorized_keys
# 在编辑器里加入本机.pub显示的一整行公钥
sudo chown deploy:deploy /home/deploy/.ssh/authorized_keys
sudo chmod 0600 /home/deploy/.ssh/authorized_keys
在Windows第二个终端用同一私钥连接 deploy@203.0.113.10,执行 sudo -v。验证这条登录通路后,再调整SSH认证设置。
8.3 安全组与系统防火墙是两层
一次连接要同时通过云安全组和Ubuntu防火墙。按下面的端口表配置,80/443在正式开站时放行。
| 端口 | 用途 | 允许范围 |
|---|---|---|
| 22 TCP | SSH管理 | 你的可信管理IP 或受控VPN入口 |
| 80 TCP | HTTP及常见证书校验 | 上线后按需对公众开放 |
| 443 TCP | HTTPS | 上线后按需对公众开放 |
| 8000 5173 8080 | 示例后端及开发服务 | 不开放公网 |
| 数据库及管理面板端口 | 内部服务 | 不默认开放公网 |
Ubuntu上先允许你的SSH来源,再启用防火墙;下列管理IP是示例值。动态公网IP变化时要先更新规则,并保留云控制台救援方式。
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 198.51.100.20 to any port 22 proto tcp
sudo ufw enable
sudo ufw status verbose
备案通过并准备开站时,再分别在安全组和Ubuntu中允许Web访问:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
使用IPv6时,同步检查IPv6规则。ECS安全组、Ubuntu防火墙
本阶段验收: 第二终端可登录;22限制管理来源,后端监听回环地址。
09 在备案通过后配置DNS
9.1 主域名和子域名怎么填
到域名的DNS管理控制台添加记录;DNS由NS指定的服务商管理,NS保持现有设置即可。
| 主机记录 | 类型 | 记录值 | 用途 |
|---|---|---|---|
| @ | A | 服务器公网IPv4 | example.com |
| www | A | 同一公网IPv4 | www.example.com |
| admin | A | 管理台所在公网IPv4 | 只有做独立管理台时才添加 |
普通工具用子页面,独立管理台用子域名。 小鱼的课表工具、调酒和本手册使用 /tools/、/cocktails/、/sop/,沿用主站DNS和证书。admin.example.com则要单独添加解析、Nginx虚拟主机和证书,登录权限仍由后端校验。
A记录填公网IPv4;服务器具备可用公网IPv6时再添加AAAA。填错AAAA会造成部分设备能访问、部分设备一直超时。域名指向网站
9.2 从本机验证
Resolve-DnsName example.com -Type A
Resolve-DnsName www.example.com -Type A
Test-NetConnection example.com -Port 80
Test-NetConnection example.com -Port 443
DNS返回正确IP后,端口仍不通,就查安全组、系统防火墙和监听服务。443在配置HTTPS后再验收;修改解析后要考虑TTL缓存。
本阶段验收: DNS返回正确公网地址,没有遗留不可用AAAA记录,管理台子域名只在需要时配置。
10 发布前端并配置Nginx
10.1 准备发布文件
静态站发布 frontend/ 内容,React/Vite发布 dist/内容。Nginx的 root只指向这些发布文件。
小鱼按三处存放:源码在项目目录,公开页面在 dist/,生产数据在 /var/lib/。修改一个子页面时,只同步它自己的目录。 本手册上线只发布 /sop/,树洞首页和数据库保持原样。
新站可按下面的版本目录方式发布:每次建立新目录,用 current指向正在使用的版本,上一版本留作回滚。
Ubuntu上准备独立目录:
sudo install -d -m 0755 -o deploy -g deploy /var/www/fishsite
sudo install -d -m 0755 -o deploy -g deploy /var/www/fishsite/releases
Windows PowerShell上传;此时当前目录是练习项目根目录:
scp -i "$env:USERPROFILE\.ssh\fishsite_rsa" -r .\frontend deploy@203.0.113.10:~/fishsite-release-v1
Ubuntu上检查上传内容,然后发布;v1必须是尚未使用的新版本目录:
( # 用子Shell运行 检查失败即停止 不退出原SSH会话
set -eu
ls -la ~/fishsite-release-v1
test ! -e /var/www/fishsite/releases/v1
mkdir /var/www/fishsite/releases/v1
cp -a ~/fishsite-release-v1/. /var/www/fishsite/releases/v1/
test -f /var/www/fishsite/releases/v1/index.html
find /var/www/fishsite/releases/v1 -type d -exec chmod 0755 {} +
find /var/www/fishsite/releases/v1 -type f -exec chmod 0644 {} +
# current用符号链接指向正在使用的版本
test ! -e /var/www/fishsite/current || test -L /var/www/fishsite/current
ln -sfn /var/www/fishsite/releases/v1 /var/www/fishsite/current.next
mv -Tf /var/www/fishsite/current.next /var/www/fishsite/current
)
命令块的 set -e使检查失败时停止;文件齐全后才切换 current。下一次改用 v2等新目录。数据库继续使用独立数据目录。
10.2 安装网站配置
将附带 ops/nginx-static.conf.example 的域名和路径替换后,用 sudoedit保存到 /etc/nginx/sites-available/fishsite。
核心配置示意如下,完整安全头配置见模板:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/fishsite/current;
index index.html;
location /api/ { return 404; }
location / { try_files $uri $uri/ =404; }
}
启用和验收:
sudo ln -s /etc/nginx/sites-available/fishsite /etc/nginx/sites-enabled/fishsite
sudo nginx -t
# 只有语法检查成功才执行下一行
sudo systemctl reload nginx
curl -I http://example.com/
配置已启用时,查看现有链接,修改配置后直接执行语法检查和reload。Nginx入门指南
React前端路由使用 try_files $uri $uri/ /index.html;回退到入口页,API与静态资源分别处理。部署到子目录时,构建 base应与访问路径一致,否则首页可能有内容、CSS和图片却404。
10.3 页面空白与CSP
小鱼管理台曾因CSP拦截内联脚本而空白,解决方式是将CSS和JS拆成独立文件。模板也是这一结构,配合 script-src 'self'和 style-src 'self'。遇到空白页,先看Console,再按被拦截的资源修复。
本阶段验收: 主域名及www展示新页面;不存在的文件返回404;秘密文件不在公开目录;旧版本仍保留。
11 配置HTTPS和证书续期
DNS和HTTP访问正常后,用Certbot为域名申请HTTPS证书。命令里的每个域名都要有正确解析;只使用主域名时,删去 -d www.example.com。
# 查看现有Certbot安装
command -v certbot
没有现成安装时,按官方当前安装方式使用Snap:
sudo apt install snapd
sudo snap install --classic certbot
sudo /snap/bin/certbot --nginx -d example.com -d www.example.com
填写联系邮箱,配置HTTP到HTTPS跳转,然后检查Nginx和证书。
sudo nginx -t
curl -I https://example.com/
sudo /snap/bin/certbot renew --dry-run
systemctl list-timers --all
签发一次只是起点,续期演练成功才算完成。 renew --dry-run验证续期流程,定时任务负责自动续期;另设到期提醒。其他安装渠道使用对应Certbot路径。Ubuntu证书教程、Certbot安装指引
页面和接口优先使用 /api/等相对路径,随站点使用HTTPS,避免混合内容错误。
本阶段验收: HTTPS证书的域名正确、浏览器无证书警告、续期演练成功、有到期提醒。
12 可选进阶 增加后端与管理台
需要账号、保存记录或多人同步时,才接入后端。先用附带健康检查接口跑通“页面 → Nginx → FastAPI”,再增加业务表和权限。
12.1 本地运行附带FastAPI示例
Windows PowerShell,在练习项目根目录执行:
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r backend\requirements.txt
.\.venv\Scripts\python.exe -m uvicorn backend.main:app --host 127.0.0.1 --port 8000 --reload
访问 http://127.0.0.1:8000,点击后端检查;/api/health返回JSON。示例同时提供本地页面,页面与接口同源。开发用 --reload,上线由systemd维护进程。FastAPI手动部署
验证后记录实际依赖版本,后续部署按相同版本复现。
12.2 服务器部署进阶示例
上传后端源码和依赖文件,服务器创建自己的虚拟环境,业务进程使用 deploy用户:
sudo install -d -m 0755 -o deploy -g deploy /var/www/fishsite/backend
# 将你自己的backend源码上传并检查后放入上述目录
python3 -m venv /var/www/fishsite/venv
/var/www/fishsite/venv/bin/python -m pip install -r /var/www/fishsite/backend/requirements.txt
第10章已将 /var/www/fishsite归属设为 deploy。创建环境遇到权限错误时,检查这个目录的所有者。
将 ops/fishsite-api.service.example安装到 /etc/systemd/system/fishsite-api.service。它在本机8000端口运行,退出后自动重启:
sudo systemctl daemon-reload
sudo systemctl enable --now fishsite-api
systemctl is-active fishsite-api
curl http://127.0.0.1:8000/api/health
sudo journalctl -u fishsite-api -n 30 --no-pager
将Nginx配置中的 /api/块替换为附带 nginx-with-api.conf.example 的代理配置;这里 proxy_pass 后没有附加斜杠,从而保留 /api/health 路径。先执行 nginx -t,通过后再reload。
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 $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
用 https://example.com/api/health验证整条链路:浏览器访问443,Nginx转发到本机8000,后端返回JSON。
12.3 小鱼管理台的关键设计
| 场景 | 实际做法 |
|---|---|
| 账号密码 | 保存带盐密码哈希 后台提供密码重置 |
| 操作权限 | 后端逐请求检查身份 写操作校验来源 |
| 项目隔离 | 全局管理员与赛事项目管理员分开 |
| 私密手记和照片 | 仅授权用户读取 分享链接可撤销 |
| 图片上传 | 限制大小 验证图像内容 再编码保存 |
| 香草园名单 | 停用和恢复保留历史票数与资料 |
| 管理操作 | 记录目标 时间和变更结果 |
会话Cookie使用Secure、HttpOnly和适合部署方式的SameSite设置。验收权限时直接请求接口:未登录应返回401,无相应权限应返回403。
本阶段验收: 关闭SSH窗口后API仍运行,域名接口正常,身份和权限测试通过。
13 开站验收和公安联网备案
13.1 上线前最后一道检查
13.2 公安联网备案
在开站之日起30日内,通过 全国互联网安全管理服务平台 提交公安联网备案:申请主体 → 新办网站 → 填写信息和上传资料 → 审核 → 悬挂编号、图标和查询链接。办理指引
13.3 有投稿功能时补齐什么
人物头像和小传等投稿增加审核、投诉与删除入口,素材保存来源和授权信息。AI生成素材按适用规则做声明和标识。生成合成内容标识办法
本阶段验收: 开站清单完成;公安备案已按要求申请,完成后悬挂正确编号;有人负责受理投诉和资料请求。
14 每次修改都按同一套流程
确认范围 → 备份 → 本地修改 → 测试 → 发布新版本
↓
线上验收 → 成功留记录 或失败回滚
14.1 发布前备份什么
- 代码及正在使用的前端版本,Nginx及服务配置,依赖版本记录。
- 业务数据库、上传素材,以及恢复所需的秘密配置;秘密备份加密并严格控制访问。
- 域名及服务器到期信息、备案信息、负责人和恢复步骤。
备份放到网站目录之外,并保留异地副本,覆盖服务器磁盘损坏等情况。
14.2 用SQLite在线备份
小鱼多个业务使用SQLite。运行中的数据库采用在线备份,日期或时间戳区分不同副本:
sudo install -d -m 0700 /var/backups/fishsite
stamp=$(date +%Y%m%d-%H%M%S)
sudo sqlite3 -readonly /var/lib/fishsite/site.db ".backup '/var/backups/fishsite/site-$stamp.db'"
sudo chmod 0600 "/var/backups/fishsite/site-$stamp.db"
sudo sqlite3 "/var/backups/fishsite/site-$stamp.db" "PRAGMA integrity_check;"
换成实际数据库路径;integrity_check返回 ok表示完整性检查通过。WAL模式下只复制 .db可能漏掉最近写入,.backup会生成一致性快照。SQLite在线备份
14.3 出问题时怎样回滚
- 纯静态页面:确认上一版本目录完整,将
current重新切换到上一版本,再验证主域名。 - 后端代码:恢复兼容的旧代码及依赖,重启对应服务,并验证接口。
- 数据库结构改变:检查旧代码与新结构的兼容性,按对应迁移方案处理。
- 恢复数据库:暂停写入,保存当前副本,试恢复并核对记录,再切换生产数据。
代码版本与数据版本分别管理。 发布记录写清版本、备份位置、测试结果和回滚方案。
14.4 建议的维护频率
| 周期 | 要检查的事项 |
|---|---|
| 每日 | 可用性及备份任务失败告警 |
| 每周 | 内存 磁盘 带宽 错误日志 投诉与审核队列 |
| 每月 | 恢复演练 依赖更新评估 权限和秘密配置检查 |
| 到期前 | 域名 云服务器及证书提醒 建议提前30天核查 |
| 内容或主体变更时 | 核对备案变更 接入迁移及其他手续 |
15 常见问题按层排查
| 现象 | 判断位置 | 处理方法 |
|---|---|---|
| 开全局代理后访问超时 | 客户端出口或分流 | 将域名设为直连 对照直连结果 SSH还要检查管理IP规则 |
| 域名和公网IP都超时 | 网络入口或服务监听 | 检查安全组 UFW和ss输出 |
| DNS返回旧IP | 解析位置及缓存 | 核对NS对应控制台 A记录和TTL |
| 首页正常 子页404 | 文件或路由 | 检查对应目录和构建base |
| 接口502 | 后端未就绪 | 查看systemctl和journalctl 验证本机health |
| 页面空白 Console报CSP | 资源被拦截 | 外置内联CSS和JS 核对允许的资源来源 |
| 证书申请失败 | 域名校验 | 检查每个域名的解析及80端口 |
| 手机卡片超过屏幕 | 布局固有宽度 | 检查viewport min-width与图片尺寸 |
| 页面正常 数据不见了 | 数据目录或环境变量 | 核对实际数据库路径 与备份比较记录 |
| 备案被退回 | 材料或用途 | 按退回理由修改对应字段并重提 |
Ubuntu常用只读检查:
systemctl status nginx --no-pager
sudo nginx -t
sudo ss -lntp
sudo ufw status verbose
free -h
df -h
# 若部署了本教程后端
sudo journalctl -u fishsite-api -n 50 --no-pager
反馈故障时附上现象、发生时间、上述检查结果和脱敏日志。
16 教学安排和最终交接
16.1 建议分成三次课
- 第一课 本地做出可运行的页面。 解释结构、修改示例、做手机适配、看控制台,验收第一版。购买资源前完成用途和主体讨论。
- 第二课 准备上线所需资源。 创建账号、比较费用、购买合格资源、注册实名域名、提交备案。等待审核期间继续完善页面。
- 第三课 审核通过后正式上线。 做DNS、Nginx、HTTPS及可选后端,完成开站清单、公安备案申请和恢复演练。
学生持有自己的域名和云账号,老师指导操作与验收,后续维护归属清楚。
16.2 给维护者的交接包
- 源码、锁文件或依赖版本、README及目录说明。
- 域名和服务器归属、续费安排、负责人及联系办法。
- 部署配置模板、发布记录、备份机制和经过测试的恢复步骤。
- 备案结果、证件及秘密配置的单独存储位置。
- 凭据交接及必要的轮换记录。
- 已知问题、待办功能及权限划分。
16.3 最终通过标准
学员能独立完成五件事:解释访问链路,修改页面,发布版本,定位一次故障,恢复一次备份。再核对资源归属与续费安排,完成交接。
官方资料入口
规则与操作入口于2026年10月14日核对,办理时查看所对应的最新页面。