前端转 AI 第 30 天:正式上线 - 从零部署一个完整服务(含 30 天复盘)
说在前面
今天是第 30 天,一个里程碑。
前 29 天把 Python 基础和整个后端工程化走完了,今天我们做两件事:
- 把服务真正部署到一个云服务器上,公网可访问
- 复盘 30 天的收获,调整下一阶段计划
Day 30 目标:上线一个域名 + HTTPS 的正式服务,同时回顾第一阶段的全部成果。
一、先看目标:上线后的样子
今天结束,你将拥有:
用户 ──► https://api.your-domain.com ──► Nginx ──► FastAPI ──► SQLite
↑
│ Let's Encrypt SSL
│ CI/CD 自动部署
│ Docker 容器化
一个真实的、有域名、有 HTTPS、能自动化部署的服务。
简历上可以写:
独立设计并上线命令行 AI 助手服务,采用 FastAPI + SQLAlchemy + Pydantic + Docker + GitHub Actions,实现自动化测试覆盖率 90%、CI/CD 全流程自动化、Nginx 反代 + HTTPS 生产级部署。
这已经是一个"能拿得出手"的项目。
二、准备工作:服务器 + 域名
1. 租服务器
选哪家?
| 云厂商 | 优点 | 价格 |
|---|---|---|
| 阿里云 / 腾讯云 | 国内快,备案方便 | ¥60-100/月(学生机更便宜) |
| Vultr / DigitalOcean | 国外,不用备案 | $5-6/月 |
| Oracle Cloud | 免费额度大 | 免费 |
| AWS / GCP / Azure | 大厂 | 有免费额度 |
我的建议:
- 国内用户 → 阿里云/腾讯云轻量应用服务器(¥60/月起)
- 不备案 → Vultr/DO($6/月)
- 折腾 → Oracle Cloud 免费机(但要抢)
配置建议:
| 项目 | 推荐 |
|---|---|
| CPU | 2 核 |
| 内存 | 2GB+ |
| 硬盘 | 40GB SSD |
| 带宽 | 按流量或 3-5 Mbps |
| 系统 | Ubuntu 22.04 LTS |
为什么选 Ubuntu? 生态最全,教程最多,Docker 一键装。
2. 域名注册
便宜域名渠道:
- 阿里云 / 腾讯云(国内,需备案)
- Namecheap(国外,$10/年)
- Cloudflare(成本价卖,$10/年)
推荐 .com / .dev / .io——别选 .xyz / .top 这类"廉价感"太强的。
3. 域名解析
在域名商后台加 A 记录:
类型 主机记录 记录值
A api 1.2.3.4 # 你的服务器 IP
A @ 1.2.3.4 # 根域名也指向
等 5-10 分钟生效,验证:
dig api.your-domain.com
# 应该返回你的服务器 IP
国内服务器要备案才能用 80 / 443 端口。 不备案可以先用其他端口测试。备案周期一般 1-2 周。
4. 服务器初始化
SSH 登录:
ssh root@1.2.3.4
创建普通用户(不要用 root 操作):
adduser deploy
usermod -aG sudo deploy
配置 SSH 免密:
本地:
# 生成密钥(如果还没有)
ssh-keygen -t ed25519 -C "deploy@ai-assistant"
# 上传公钥到服务器
ssh-copy-id deploy@1.2.3.4
禁用 root 密码登录(安全):
服务器上编辑 /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
重启 SSH:
sudo systemctl restart sshd
之后只能用密钥登录,无法暴力破解。
三、服务器环境搭建
1. 安装 Docker
# 一键安装(官方脚本)
curl -fsSL https://get.docker.com | sh
# 把 deploy 用户加入 docker 组(不用 sudo)
sudo usermod -aG docker deploy
# 重新登录生效
exit
# 重新 ssh 进来
# 验证
docker --version
# Docker version 27.x.x
2. 安装 docker compose plugin
Docker 27 已经内置 compose(docker compose 命令)——不用再单独装。
验证:
docker compose version
# Docker Compose version v2.x.x
3. 基础配置
设置时区:
sudo timedatectl set-timezone Asia/Shanghai
配置防火墙:
sudo ufw allow 22 # SSH
sudo ufw allow 80 # HTTP
sudo ufw allow 443 # HTTPS
sudo ufw enable
开了防火墙后,只有 22 / 80 / 443 端口能从外部访问,其他端口安全了。
装一些常用工具:
sudo apt update
sudo apt install -y git curl vim htop
四、部署项目
1. 代码推到 GitHub
本地:
git init
git add .
git commit -m "ready for production"
git branch -M main
# 在 GitHub 创建仓库后
git remote add origin git@github.com:yourname/ai-assistant.git
git push -u origin main
2. 服务器上拉代码
cd /opt
sudo mkdir ai-assistant
sudo chown deploy:deploy ai-assistant
cd ai-assistant
git clone git@github.com:yourname/ai-assistant.git .
用 deploy 用户操作,避免权限问题。
3. 创建生产 .env
cat > .env <<EOF
API_KEY=$(openssl rand -hex 32)
ENV=prod
LOG_LEVEL=INFO
EOF
chmod 600 .env
openssl rand -hex 32 生成强随机 API Key。
chmod 600 只有自己可读——.env 里有密钥,不能让别人看到。
4. 准备 SSL 证书
先申请证书(先用 HTTP 起一个临时服务):
# 修改 nginx 配置,暂时只用 80
vim nginx/conf.d/api.conf
临时配置(只用 80):
server {
listen 80;
server_name api.your-domain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 200 "ok";
}
}
起 Nginx:
mkdir -p nginx/www nginx/certs
docker run -d --name temp-nginx \
-p 80:80 \
-v $(pwd)/nginx/www:/var/www/certbot:ro \
-v $(pwd)/nginx/conf.d:/etc/nginx/conf.d:ro \
nginx:alpine
申请证书:
docker run --rm \
-v $(pwd)/nginx/certs:/etc/letsencrypt \
-v $(pwd)/nginx/www:/var/www/certbot \
certbot/certbot certonly \
--webroot -w /var/www/certbot \
-d api.your-domain.com \
--email you@example.com \
--agree-tos --no-eff-email
成功的话:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/api.your-domain.com/fullchain.pem
证书目录:
ls nginx/certs/live/api.your-domain.com/
# cert.pem chain.pem fullchain.pem privkey.pem README
停掉临时 Nginx:
docker stop temp-nginx && docker rm temp-nginx
5. 切换到完整 HTTPS 配置
恢复 nginx/conf.d/api.conf 为完整版本(Day 29 写的),把域名替换成你的:
upstream api_backend {
least_conn;
server api:8000;
keepalive 32;
}
server {
listen 80;
server_name api.your-domain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
http2 on;
server_name api.your-domain.com;
ssl_certificate /etc/nginx/certs/live/api.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/api.your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
client_max_body_size 10M;
location / {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
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;
proxy_read_timeout 60s;
}
}
6. 启动完整服务
docker compose -f docker-compose.prod.yml up -d --build
看状态:
docker compose -f docker-compose.prod.yml ps
应该看到:
NAME IMAGE STATUS
ai-api ai-assistant:prod Up (healthy)
ai-nginx nginx:alpine Up
7. 验证上线
本机验证:
# HTTP 跳转
curl -I http://api.your-domain.com
# HTTP/1.1 301 Moved Permanently
# Location: https://api.your-domain.com/
# HTTPS 访问
curl https://api.your-domain.com/health/live
# {"status": "alive"}
# 带认证的业务接口
curl -H "X-API-Key: $(grep API_KEY .env | cut -d= -f2)" \
https://api.your-domain.com/api/sessions
# {"sessions": [], "total": 0}
用浏览器打开 https://api.your-domain.com/docs——Swagger UI 可以访问,且浏览器显示"连接安全"。
🎉 服务正式上线!
五、上线后的运维
1. 配置自动续期证书
加一个 certbot 服务:
# docker-compose.prod.yml 里加
certbot:
image: certbot/certbot
volumes:
- ./nginx/certs:/etc/letsencrypt
- ./nginx/www:/var/www/certbot
entrypoint: /bin/sh
command: >
-c "trap exit TERM;
while :; do
certbot renew --webroot -w /var/www/certbot;
sleep 12h & wait $${!};
done"
restart: unless-stopped
注意需要先 docker compose up -d certbot 起它。
2. 日志轮转
Docker 日志默认无限制,会撑爆磁盘。
配置 Docker 日志限制:
/etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
重启 Docker:
sudo systemctl restart docker
每个容器最多 30MB 日志——不会撑爆服务器。
3. 定期备份
备份数据库和配置:
# 加一个 cron 任务
crontab -e
内容:
# 每天凌晨 3 点备份
0 3 * * * cd /opt/ai-assistant && tar -czf /opt/backups/ai-$(date +\%Y\%m\%d).tar.gz data/ .env && find /opt/backups -name "ai-*.tar.gz" -mtime +7 -delete
这行做了:
- 打包
data/和.env - 存到
/opt/backups/ - 删除 7 天前的旧备份
4. 简易监控
查看服务器状态:
# 系统负载
htop
# 磁盘
df -h
# Docker 占用
docker system df
# 容器状态
docker compose -f docker-compose.prod.yml ps
清理 Docker 无用资源(每周):
docker system prune -f # 清理停止的容器、无用镜像、网络
docker system prune -a --volumes # 更彻底(小心 volume)
5. 应用日志查看
# API 日志
docker compose -f docker-compose.prod.yml logs -f api
# Nginx 日志
docker compose -f docker-compose.prod.yml logs -f nginx
# Nginx 访问日志(最近 100 行)
tail -100 /var/lib/docker/volumes/ai-assistant_nginx_logs/_data/access.log
# 慢请求排查(rt > 1s)
tail -1000 /var/lib/docker/volumes/ai-assistant_nginx_logs/_data/access.log | \
awk '$NF > 1.0' | head -20
6. 故障排查清单
常见问题及排查步骤:
| 现象 | 可能原因 | 排查 | |
|---|---|---|---|
| 502 Bad Gateway | 后端挂了 | docker compose ps 看 api 状态 | |
| 503 | 健康检查失败 | curl localhost:8000/health/ready | |
| 504 | 后端超时 | 看 nginx error.log | |
| SSL 错误 | 证书过期 | docker compose logs certbot | |
| 域名不通 | DNS 没生效 | dig api.your-domain.com | |
| 服务崩了 | OOM | `dmesg | grep -i kill` |
排错顺序:
docker compose ps— 容器都起来了吗?docker compose logs api— 有报错吗?curl localhost:8000/health/ready— 后端健康吗?curl localhost/health/live— Nginx 通吗?dig api.your-domain.com— DNS 对了吗?
从内到外一层层测。
六、上线检查清单
正式上线前,逐项确认:
安全
- ✅ SSH 只用密钥登录
- ✅ 防火墙只开 22 / 80 / 443
- ✅
.env权限 600 - ✅ API Key 强随机
- ✅ 没有敏感信息提交到 git
- ✅ Nginx 隐藏版本号(
server_tokens off) - ✅ HTTPS 强制,无 HTTP
- ✅ HSTS 已启用
- ✅ 常用安全头全加
可用性
- ✅ 容器
restart: always - ✅ 健康检查配置正确
- ✅ Docker 日志限制
- ✅ SSL 证书自动续期
- ✅ 数据库定时备份
可观测性
- ✅ 结构化日志(JSON)
- ✅ Trace ID 全链路
- ✅ Prometheus 指标接口
- ✅ 关键错误有告警
性能
- ✅ Nginx Gzip
- ✅ 连接池配置
- ✅ 常用查询有索引
- ✅ 静态资源缓存
自动化
- ✅ CI 自动跑测试
- ✅ CD 自动构建镜像
- ✅ Tag 自动部署
这份清单能让你从"能跑"到"能上生产"。上线前刷一遍,避免低级事故。
七、30 天复盘:走了多远
1. 知识地图回顾
┌──────────────────────────────────────────────────┐
│ 第 1 阶段(Day 1-15) │
│ Python 基础 + 项目起步 │
├──────────────────────────────────────────────────┤
│ Day 1-12 Python 语法(12 天) │
│ Day 13-14 命令行 AI 助手 v1 / v2 │
│ Day 15 阶段复盘 │
├──────────────────────────────────────────────────┤
│ 第 2 阶段(Day 16-30) │
│ 后端工程化 + 上线 │
├──────────────────────────────────────────────────┤
│ Day 16-17 数据库 + ORM │
│ Day 18-19 pytest 测试 │
│ Day 20 CLI 打包发布 │
│ Day 21-24 FastAPI 全链路 │
│ Day 25 性能优化 │
│ Day 26 可观测性 │
│ Day 27-30 Docker + CI/CD + Nginx + 上线 │
└──────────────────────────────────────────────────┘
2. 30 天收获清单
技术能力:
- ✅ Python 从 0 到能写生产代码
- ✅ 异步编程(asyncio)
- ✅ 数据库设计 + ORM
- ✅ 单元测试 + 集成测试
- ✅ FastAPI 全栈后端
- ✅ Docker 容器化
- ✅ CI/CD 自动化
- ✅ Nginx + HTTPS 部署
- ✅ 可观测性(日志 / 指标 / 追踪)
工程能力:
- ✅ 从"写脚本"到"做项目"
- ✅ 分层架构(API / 业务 / 存储)
- ✅ 依赖注入
- ✅ 接口契约
- ✅ 测试驱动
- ✅ 生产级配置
软实力:
- ✅ 遇到问题先查文档
- ✅ 学会看报错栈
- ✅ 习惯记录踩坑
- ✅ 每天有产出
3. 项目进化史
从 Day 13 到 Day 30,项目长成这样:
v1(Day 13):命令行助手,Mock LLM
- 500 行代码
- 本地跑
v2(Day 14):加记忆系统
- 800 行代码
- 支持长对话
v3-v4(Day 16-17):接入数据库
- 1200 行代码
- 会话持久化
v5(Day 18-20):加测试 + CLI
- 2000 行代码
- 90% 覆盖率
v6(Day 21-26):转 HTTP 服务
- 3000 行代码
- 完整 FastAPI 后端
v7(Day 27-30):上线
- 4000 行代码
- 公网可访问
从一个"玩具脚本"到"真实服务",30 天。 这就是项目驱动的学习的威力。
4. 数据说话
| 指标 | Day 1 | Day 30 |
|---|---|---|
| 代码行数 | 2 | ~4000 |
| 测试数 | 0 | 40+ |
| 覆盖率 | 0% | 90% |
| Python 文件 | 1 | 30+ |
| 部署方式 | 无 | Docker + CI/CD |
| 访问方式 | 本地 | 公网 HTTPS |
这不是"感觉学到了",是"数字证明了"。
八、反思:做得好和做得差
做得好的
1. 每天固定时间学 2 小时
工作日晚上 9-11 点,周末白天。比"周末猛学一天"效果好太多。
2. 每天有产出
哪怕只是 20 行代码,也要落到文件上。这是"学习"和"看视频"的本质区别。
3. 项目驱动
不追求"学完再做",而是"边做边学"。 Day 13 就有第一个可跑的版本,后面是持续迭代。
4. 记录踩坑
每次遇到报错,都记一句"为什么错 / 怎么解"。30 天积累下来,就是一份宝贵的"自留地"。
做得差的
1. 前期过早引入 Pydantic
Day 11 讲 Pydantic 时,其实还没到真正需要它的场景。应该在做 API 时再引入,效果会更好。
2. 异步一块练得太少
asyncio 的概念过了,但真正写 async 代码的机会不多。后面 Day 46 接真 LLM 时,要补上。
3. 没有开源项目贡献
一直在"自己写",没读过大项目源码。后面要抽时间读一读 FastAPI / LangChain 的代码。
4. 英文文档看得少
一直在中文社区找答案,英文一手资料看得不够。AI 领域更新快,英文能力是长期刚需。
调整方向
1. 每周至少读一次英文文档
Python / FastAPI / OpenAI 官方文档都是英文的,直接从源头学。
2. 开始读开源项目源码
从 LangChain 开始,理解大型项目的组织方式。
3. 多写"生产级"代码
接下来的 LLM 部分,从第一天就按"能上线"的标准写。
九、下一阶段预告
Day 31-45:大模型 API + Prompt 工程
核心任务:把 Mock LLM 换成真 LLM。
内容大纲:
| Day | 内容 |
|---|---|
| 31 | LLM 是什么:大模型基础概念 |
| 32 | OpenAI API 入门 |
| 33 | 流式输出(SSE) |
| 34 | Function Calling 入门 |
| 35 | 结构化输出 |
| 36 | Prompt 工程基础 |
| 37 | Few-shot / CoT |
| 38 | Token 管理与成本优化 |
| 39 | 多模型适配(OpenAI / Claude / 通义 / DeepSeek) |
| 40 | 错误处理与重试策略 |
| 41 | 本地模型(Ollama) |
| 42 | 流式 + 工具调用的组合 |
| 43 | 对话历史与上下文管理 |
| 44 | LLM 应用测试策略 |
| 45 | 阶段复盘:把 Mock 换成真 LLM |
这一阶段会实现:
- ✅ 真实 LLM 调用
- ✅ 流式输出(打字机效果)
- ✅ Function Calling(工具调用雏形)
- ✅ 多模型切换
- ✅ 成本控制
做完 Day 45,你的助手就是一个"真 AI 助手"了。
Day 46-60:RAG + 向量数据库
核心任务:让助手"读懂"你的文档。
Day 61-80:Agent 框架
核心任务:让助手"会用工具"。
Day 81-100:完整 Agent 项目
核心任务:做一个能上线、有用户的完整 Agent 产品。
十、给跟我一起学的你
30 天了,感谢还在跟着看的你。
几个想说的:
1. 不要"打卡式学习"
"看了 30 篇文章"不等于"学会了 30 天"。
真正的学习,是每一篇的代码都跑过、改过、想过。 哪怕只跟着做了 10 天,也比"看了 30 天"强。
2. 慢一点没关系
有人 30 天能做完的事,你 60 天做完不丢人。
重要的是"持续",不是"速度"。 3 个月后回头看,每天 1 小时也是 90 小时。
3. 不要怕"答不出来"
遇到不懂的,先记下来,别停在那。
继续往下走,回头再看,"不懂"可能会自己变"懂"。
4. 找个人一起学
评论区是很好的交流场。
看到别人卡在哪,你也能学到东西;你卡住的地方,别人可能已经踩过坑。
5. 30 天后,你回头看
如果你从 Day 1 跟到现在,请你此刻回头看看 Day 1 的那段代码。
你会发现——"这么简单的东西,当时怎么卡了半天。"
这就是成长。
十一、今日总结
今天核心收获三件事:
- 完整走通了"从代码到上线"的全流程:租服务器 → 配域名 → 装 Docker → 部署 → HTTPS → 运维
- 上线不只是"跑起来":还要 SSL、限流、日志、备份、监控、告警
- 30 天从 0 到 1:从 Python 语法到能上线服务,一个人、一台电脑、每天 2 小时
一个感受:
很多人问"学 Python 要多久才能做项目"。
答案不是"学完语法后",而是"从第一天就开始做"。
Day 1 写 Hello World,Day 30 上线 HTTPS 服务。
中间隔的不是"学了多少知识",是"坚持了多少天"。
你的项目在线上跑着了。 这件事本身就是最好的证明——你不再是"学 Python 的人",而是"用 Python 做出东西的人"。
Day 30 完成度:✅
明日预告(Day 31)
进入大模型世界的第一天。
- 大模型到底是什么:从 GPT 到 ChatGPT
- Token / 上下文窗口 / 温度这些概念
- 主流大模型对比:GPT-4o / Claude / DeepSeek / 通义
- 怎么选:成本、速度、能力三角
- 注册 OpenAI / 通义 / DeepSeek 账号
- 拿到第一个 API Key
明天,我们的助手要接入真正的"大脑"。
最后
如果这篇对你有用,请一定点个赞——30 天的成果值得一个赞。
评论区互动: 你从第几天开始跟的?30 天里最大的收获是什么?下一阶段最期待学什么?说出来,我们互相见证。
100 天,第 31 天见。
附录:系列目录
第一阶段(已完成 ✅)
| 天数 | 内容 | 状态 |
|---|---|---|
| 01-06 | Python 语法基础 | ✅ |
| 07-08 | HTTP + 异步 | ✅ |
| 09-12 | 工程基础(正则/装饰器/Pydantic/日志) | ✅ |
| 13-14 | 命令行 AI 助手 v1 / v2 | ✅ |
| 15 | 阶段复盘 | ✅ |
| 16-17 | 数据库 + ORM | ✅ |
| 18-19 | pytest 测试 | ✅ |
| 20 | CLI 打包发布 | ✅ |
| 21-24 | FastAPI 全链路 | ✅ |
| 25 | 性能优化 | ✅ |
| 26 | 可观测性 | ✅ |
| 27 | Docker 容器化 | ✅ |
| 28 | CI/CD | ✅ |
| 29 | Nginx + HTTPS | ✅ |
| 30 | 正式上线 + 阶段复盘 | ✅ |
第二阶段(进行中 🎯)
| 阶段 | 天数 | 内容 |
|---|---|---|
| 大模型 | 31-45 | LLM API + Prompt 工程 |
| RAG | 46-60 | 向量数据库 + 知识库 |
| Agent | 61-80 | LangChain / 工具调用 |
| 实战 | 81-100 | 完整 Agent 项目上线 |
30 天已过,70 天还在。
一起从切图仔变成 Agent 开发者。