9. 附录:项目参考与命令手册
本章提供三个独立参考:Linux 命令速查手册、项目结构/API 参考,以及部署哲学复盘——适合随时翻阅查找。
9.1 Linux 命令速查手册
SSH & 远程连接
# 使用配置别名登录
ssh tao
# 上传文件到服务器(在本地终端执行)
scp index.html tao:/root/
# 上传整个文件夹(-r 递归)
scp -r ./my-project tao:/root/
目录导航
pwd # 显示当前路径
ls # 列出文件
ls -lh # 详细信息(大小、修改时间)
cd /root/ # 进入目录
cd .. # 返回上级
cd ~ # 回到用户家目录
文件操作
mkdir my_demo # 创建文件夹
rm test.txt # 删除文件
rm -rf my_demo # 强制删除整个文件夹
mv old.txt new.txt # 重命名
mv test.txt /root/ # 移动文件
cp source.txt dest.txt # 复制文件
文件查看
cat config.json # 一次性显示所有内容
tail -f error.log # 实时查看日志(Ctrl+C 退出)
less config.json # 分页查看(空格翻页,q 退出)
head -n 20 file.txt # 查看前 20 行
终端文本编辑
# vi 编辑器基本操作
vi .env
# i → 进入编辑模式(底部显示 -- INSERT --)
# Esc → 退出编辑模式
# :wq → 保存并退出
# :q! → 不保存退出
# nano 编辑器(新手友好)
nano .env
# Ctrl+O → 保存
# Ctrl+X → 退出
系统状态
free -h # 查看内存占用
df -h # 查看磁盘剩余
top # 查看 CPU 负载(按 q 退出)
ps aux # 查看运行中的进程
Docker 快速参考
# 容器生命周期
docker compose up -d --build # 一键启动(后台)
docker compose ps # 查看容器状态
docker compose logs -f # 查看日志
docker compose down # 停止并移除容器
docker compose restart db # 重启单个服务
# 数据库
docker compose exec db psql -U openrise -d openrise # SQL 命令行
docker compose exec frontend npx prisma studio # 数据库可视化
# 镜像管理
docker compose build frontend --no-cache # 无缓存构建
docker image prune -f # 清理旧镜像
操作技巧
| 技巧 | 说明 |
|---|---|
| Tab 键 | 自动补全命令/路径(命令行的灵魂) |
| 方向键 ↑ | 快速找回之前敲过的长命令 |
| clear | 清屏,还你干净的桌面 |
| 选中即复制 | 大多数终端:鼠标选中即复制,右键即粘贴 |
9.2 项目架构参考(ai-web-community)
完整目录结构
ai-web-community/
├── docker-compose.yml # Docker 编排(定义 3 个容器)
├── .env.example # 环境变量模板
│
├── frontend/ # Next.js 主目录
│ ├── app/ # App Router
│ │ ├── layout.tsx # 根布局(包含 <html><body>)
│ │ ├── page.tsx # 首页(/)
│ │ ├── account/ # 用户账户
│ │ │ ├── page.tsx # 仪表板
│ │ │ ├── courses/[id]/ # 课程管理
│ │ │ └── lessons/[id]/ # 小节管理
│ │ ├── courses/ # 公开课程
│ │ │ ├── page.tsx # 课程列表
│ │ │ ├── [slug]/ # 课程详情
│ │ │ └── [slug]/lessons/[id]/ # 公开小节
│ │ ├── api/ # API Routes
│ │ │ ├── auth/ # 认证相关
│ │ │ ├── courses/ # 课程 CRUD
│ │ │ ├── chapters/ # 章节管理
│ │ │ ├── lessons/ # 小节管理
│ │ │ └── health/ # 健康检查
│ │ ├── login/ register/ # 登录注册页
│ │ ├── forgot-password/ # 忘记密码
│ │ ├── reset-password/ # 重置密码
│ │ ├── community/ # 社区页面
│ │ ├── pricing/ # 定价页面
│ │ ├── resources/ # 资源页面
│ │ └── verify/ # 邮箱验证
│ │
│ ├── components/ # 可复用组件
│ │ ├── AuthButton.tsx
│ │ ├── CollapsibleChapter.tsx
│ │ ├── CourseCard.tsx
│ │ └── ...
│ │
│ ├── lib/ # 工具和服务层
│ │ ├── auth.ts # NextAuth.js 配置
│ │ ├── prisma.ts # Prisma 客户端实例
│ │ ├── resend.ts # Resend 邮件客户端
│ │ ├── turnstile.ts # Cloudflare Turnstile 验证
│ │ ├── course-permissions.ts # 课程权限服务
│ │ ├── services/ # 业务逻辑层
│ │ │ └── course-service.ts
│ │ └── types/ # TypeScript 类型
│ │ └── course.ts
│ │
│ ├── prisma/ # 数据库
│ │ ├── schema.prisma # 数据模型
│ │ ├── migrations/ # 迁移文件
│ │ └── seed.ts # 种子数据
│ │
│ ├── public/ # 静态资源
│ ├── scripts/ # 工具脚本
│ │ └── dev.mjs # 开发服务器启动脚本
│ ├── Dockerfile # 容器构建
│ ├── entrypoint.sh # 容器启动脚本
│ └── package.json # 依赖清单
│
├── nginx/
│ └── nginx.conf # 反向代理配置
│
└── docs/ # 项目文档
├── plans/
└── resource/
API 路由一览
认证 API (/api/auth/*)
| 端点 | 方法 | 功能 |
|---|---|---|
/api/auth/register |
POST | 用户注册 |
/api/auth/forgot-password |
POST | 发送密码重置邮件 |
/api/auth/reset-password |
POST | 重置密码 |
/api/auth/[...nextauth] |
GET/POST | NextAuth.js 认证处理 |
课程 API (/api/courses/*)
| 端点 | 方法 | 功能 |
|---|---|---|
/api/courses |
GET | 获取用户课程列表 |
/api/courses |
POST | 创建新课程 |
/api/courses/public |
GET | 获取公开课程 |
/api/courses/[id] |
GET | 课程详情 |
/api/courses/[id] |
PUT | 更新课程 |
/api/courses/[id] |
DELETE | 删除课程 |
章节 API (/api/chapters/*)
| 端点 | 方法 | 功能 |
|---|---|---|
/api/chapters |
POST | 创建章节 |
/api/chapters/[id] |
GET | 章节详情 |
/api/chapters/[id] |
PUT | 更新章节 |
/api/chapters/[id] |
DELETE | 删除章节 |
小节 API (/api/lessons/*)
| 端点 | 方法 | 功能 |
|---|---|---|
/api/lessons |
POST | 创建小节 |
/api/lessons/[id] |
GET | 小节详情 |
/api/lessons/[id] |
PUT | 更新小节 |
/api/lessons/[id] |
DELETE | 删除小节 |
其他 API
| 端点 | 方法 | 功能 |
|---|---|---|
/api/health |
GET | 健康检查 |
/api/me |
GET | 获取当前用户 |
/api/upload |
POST | 文件上传 |
权限系统结构
// 课程访问规则
// 公开课程 (isPublic: true) → 所有人可看,仅作者可编辑
// 私有课程 (isPublic: false) → 仅作者可看可编辑
// 核心权限函数
canViewCourse(user, courseId) // 检查是否可查看
canEditCourse(user, courseId) // 检查是否可编辑
canViewLesson(user, lessonId) // 检查是否可查看小节
getViewableCourses(user) // 获取可查看的课程列表
9.3 工程哲学复盘
从"个人玩玩"到"生产级部署"的思维转变
在自己的电脑上可以随意安装插件、修改配置。但在云服务器上的核心追求是:环境一致性和可恢复性。
核心感悟:服务器本质是另一台电脑,你可以像玩本地 Linux 一样在上面改。但如果你手工改了一个配置,三个月后宕机重装,你还能记起那个配置吗?这就是 Docker(把环境写成脚本)和 Git(把修改留存记录)的终极意义。
各环节的"为什么"
| 环节 | 工具 | 解决的核心问题 | 一句话感悟 |
|---|---|---|---|
| 本地模拟 | Docker Desktop | "我电脑上明明是好的" | 确保代码在进入服务器前已通过测试 |
| 代码中转 | GitHub / Git | "万一改坏了回不去" | Git 是后悔药,每一行代码都有据可查 |
| 环境封装 | Docker / Image | "换台服务器又要装半天环境" | 一次构建,到处运行 |
| 远程接管 | SSH / Config | "远程操控效率低" | 操作服务器像操作本地目录一样顺滑 |
| 自动化 | CI/CD | "手动部署太繁琐" | 你只需 git push,剩下的交给机器 |
不可变基础设施
在传统部署中,手动配置的环境极其脆弱("人肉运维"),重启可能导致路径丢失。在 Docker 时代:
- 确定性:所有环境依赖写在
Dockerfile里 - 幂等性:无论重启 1 次还是 100 次,起出来的环境永远一致
- 自动化:随时通过一行脚本完成"销毁 → 重建"
服务端 vs 客户端渲染
为什么 Next.js 需要"启动"服务器?
传统静态网站用浏览器打开
index.html即可。但 Next.js 是服务端渲染框架,需要一个 Node.js 进程持续运行,负责实时编译、路由处理和热更新。不启动开发服务器,浏览器无法访问任何页面。
生产与本地的心态差异
本地环境 = 实验室 → 可以爆炸,可以重来
生产环境 = 前线战场 → 必须用标准化、工业化流程保证坚不可摧
数据与逻辑分离的生存法则:
- 无状态(Stateless):前端 (Next.js)、Nginx → 不挂载数据卷,随用随抛
- 有状态(Stateful):数据库 (PostgreSQL)、上传文件 → 使用 Volume 挂载,数据是资产
← 返回知识库