2026年02月25日 星期三 阴
缘起
上午同事找我了两次,说我软件有问题。我听完需求,回到座位一看,我最新软件是好的。第二次是他不懂得配置软件。
我想了一下,以后提醒他们用最新软件好了,我在每次软件运行的时候添加软件版本检测。于是用AI花了一天的时间写完并部署到Pythonanywhere了。主要坑点是fastapi是asgi的,而Pythonanywhere是老牌站点,支持的是wsgi。AI引导我搞得乱七八糟,后来AI不经意发现官方文档,我要求AI遵循官方指南,AI才引导我部署成功。部署花了我60%的时间,所以写下此文记录一下。
说到免费的支持python的服务器,除了PythonAnywhere外,我觉得Render(今天没选是看到它好像有个间歇性休眠的问题)、Oracle Cloud Free Tier下次可以尝试一下。
今天还第一次感受了FastAPI,它自动支持swagger,感觉很好。我们要多接触一些现代化的东西,下面看正文:
最近在 PythonAnywhere 上部署 FastAPI 时踩了不少坑,最终通过官方的 ASGICommandLine 方案 成功解决了所有问题。本文将完整梳理部署流程,包括准备工作、具体步骤、常见问题及解决方案,帮助大家快速上手。
为什么选择 PythonAnywhere + FastAPI?
- PythonAnywhere :免费、易用,适合部署小型 Python Web 应用,支持虚拟环境和自定义域名。
- FastAPI :高性能、异步支持、自动生成 API 文档,是现代 Python Web 开发的热门选择。
- 官方 ASGI 方案 :PythonAnywhere 提供的实验性 ASGI 部署方式,直接托管 uvicorn 运行 FastAPI,无需复杂的转发配置,稳定可靠。
参考文献 :PythonAnywhere ASGICommandLine 官方文档
准备工作
1. 注册 PythonAnywhere 账号
访问 PythonAnywhere 官网 注册免费账号,注册后会自动分配一个子域名(如 yourusername.pythonanywhere.com)。
2. 创建虚拟环境并安装依赖
打开 PythonAnywhere 的 Bash 终端,执行以下命令:
bash
运行
# 创建 Python 3.10 虚拟环境
mkvirtualenv my_venv --python=python3.10
# 激活虚拟环境
workon my_venv
# 安装 FastAPI 和 uvicorn
pip install "uvicorn[standard]" fastapi
# 安装项目依赖(根据你的项目补充)
pip install sqlalchemy python-multipart jinja2
3. 生成 API Token
官方 ASGI 方案需要通过 API Token 连接 PythonAnywhere,步骤如下:
- 点击右上角「Account」→「API token」;
- 点击「Create a new API token」;
- 复制生成的 token(格式类似
1234567890abcdef1234567890abcdef)。
在 Bash 终端配置 API Token:(根据官方指南,只需要生成token就行了,下面这步应该不需要。
bash运行
export PA_API_TOKEN="你的API_TOKEN"
具体部署步骤
1. 删除旧的 Web app(避免冲突)
如果之前在「Web」页面创建过旧的 WSGI 模式 app,先删除:
- 打开「Web」页面;
- 找到旧 app,点击底部「Delete web app」→ 确认删除。
2. 准备 FastAPI 项目
确保你的项目结构如下(以本文的 Pulse 项目为例):
plaintext
Pulse/
├── main.py # FastAPI 主文件
├── templates/ # 模板目录
│ ├── login.html # 登录页面
│ └── admin.html # 后台页面
└── pulse.db # 数据库文件(可选,会自动创建)
关键修改 :将 main.py 中的模板目录改为 绝对路径 (避免找不到模板):
python
运行
from fastapi.templating import Jinja2Templates
# 错误:相对路径,部署后会找不到模板,官方好像有说配置静态文件好像有问题,我就临时解决一下
# templates = Jinja2Templates(directory="templates")
# 正确:绝对路径,替换为你的项目实际路径
templates = Jinja2Templates(directory="/home/yourusername/tktools/app/Pulse/templates")
3. 用 pa 命令创建 ASGI 网站
在 Bash 终端执行( 替换 yourusername 为你的 PythonAnywhere 用户名 ):
bash
运行
# 激活虚拟环境
workon my_venv
# 创建 ASGI 网站
pa website create \
--domain yourusername.pythonanywhere.com \
--command '/home/yourusername/.virtualenvs/my_venv/bin/uvicorn --app-dir /home/yourusername/tktools/app/Pulse --uds ${DOMAIN_SOCKET} main:app'
命令详解 :
--domain:你的网站域名;--command:启动命令,核心参数说明:/home/yourusername/.virtualenvs/my_venv/bin/uvicorn:虚拟环境中 uvicorn 的绝对路径;--app-dir:FastAPI 项目的根目录(main.py所在目录);--uds ${DOMAIN_SOCKET}:官方要求的 Unix Socket 监听方式, 禁止替换为--bind端口模式 ;main:app:FastAPI 实例入口,对应main.py中app = FastAPI()的实例名。
4. 验证网站创建成功
执行以下命令查看已创建的 ASGI 网站:
bash
运行
pa website get
终端输出你的域名和启动命令,即代表创建成功。
5. 重启并验证部署结果
bash
运行
# 重启网站,加载最新代码
pa website reload --domain yourusername.pythonanywhere.com
# 查看启动日志,确认服务正常运行
tail -50 /var/log/yourusername.pythonanywhere.com.server.log
成功启动日志示例 :
plaintext
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on unix socket /var/sockets/yourusername.pythonanywhere.com/app.sock (Press CTRL+C to quit)
访问以下地址验证功能:
- FastAPI 自动文档:
https://yourusername.pythonanywhere.com/docs - 自定义页面:
https://yourusername.pythonanywhere.com/login - 健康检查接口:
https://yourusername.pythonanywhere.com/health
常见问题及解决方案
1. 模板找不到报错:jinja2.exceptions.TemplateNotFound: login.html
核心原因 :Jinja2Templates 使用了相对路径,--app-dir 启动时无法正确定位模板目录。
解决方案 :将模板目录路径改为服务器上的 绝对路径 ,参考上文「准备 FastAPI 项目」部分的代码修改。
2. hypercorn 导入错误:ModuleNotFoundError: No module named 'hypercorn.wsgi'
核心原因 :hypercorn 版本适配问题,或 WSGI 转 ASGI 方案的兼容性缺陷。
解决方案 :放弃 hypercorn 适配方案,直接使用本文推荐的官方 ASGICommandLine 原生 uvicorn 部署方案,无需任何适配层。
3. 日志中仍出现旧的 uWSGI 启动信息
核心原因 :旧的 WSGI 模式 Web app 未完全删除,域名被占用。
解决方案 :进入「Web」页面,确认所有旧 app 已删除,重新执行 pa website create 命令创建 ASGI 网站。
4. ASGI 网站不在「Web」页面显示
核心原因 :官方明确说明 ASGI 部署为实验性功能,暂不支持在 Web 页面可视化管理。
解决方案 :正常现象,无需处理。所有管理操作通过 pa 命令行完成,直接访问域名即可使用服务。
5. 修改代码后不生效
核心原因 :代码修改后未重启 ASGI 网站,服务仍运行旧版本代码。
解决方案 :执行 pa website reload --domain yourusername.pythonanywhere.com 重启服务,加载最新代码。
常用 pa 命令汇总
表格
| 操作 | 命令 |
|---|---|
| 查看所有 ASGI 网站 | pa website get |
| 查看指定网站详情 | pa website get --domain yourusername.pythonanywhere.com |
| 重启网站(更新代码) | pa website reload --domain yourusername.pythonanywhere.com |
| 删除网站 | pa website delete --domain yourusername.pythonanywhere.com |
| 为自定义域名申请 SSL 证书 | pa website create-autorenew-cert --domain yourcustomdomain.com |
总结
PythonAnywhere 的 ASGICommandLine 方案 是部署 FastAPI 的最优选择,它:
- ✅ 无需复杂的 WSGI 转发 / 适配代码,原生支持 ASGI 应用;
- ✅ 直接托管 uvicorn 进程,无端口冲突、协议兼容问题;
- ✅ 完整支持 FastAPI 异步特性、模板渲染、接口文档等所有功能;
- ✅ 免费账号即可使用,无额外配置门槛。
只要按照本文的步骤操作,重点注意模板路径使用绝对路径,就能快速完成 FastAPI 的部署上线。
官方参考文档 :PythonAnywhere ASGICommandLine 官方文档
真实记录
以上是 AI 生成的,下面文字是自己的真实记录:
-
注册 PythonAnywhere,选择 free 账号并激活。
-
登录后,进入 Account → API token,创建 API TOKEN。
创建就行了,不用在 Bash 里显式调用(除非碰到文末提到的报错)。
-
把项目 zip 压缩包上传到目标目录,例如:
/home/YOURUSERNAME/tktools/app/Pulse -
打开 Consoles,选择 Bash,依次执行下面这些命令。
创建虚拟环境(我用的是和本地一样的 3.13,注意老账户好像还是 3.10):
mkvirtualenv my_venv --python=python3.13安装 pythonanywhere(主要是为了使用
pa命令,部分错误可忽略):pip install --upgrade pythonanywhere安装 FastAPI 和 uvicorn:
pip install "uvicorn[standard]" fastapi解压上传的项目压缩包:
cd /home/YOURUSERNAME/tktools/app/Pulse unzip Pulse.zip -
官方给的
main.py示例大致如下(用于快速验证环境):from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello from FastAPI"} -
安装项目依赖:
pip install -r requirements.txt -
特别提醒:如果是部署在公网服务器,建议关闭
docs_url和redoc_url; 另外,由于 ASGI 部署的关系,在 PythonAnywhere 上静态文件/模板目录也要强行指定绝对路径,否则容易 404。可以参考类似下面的写法(根据自己项目调整):
DEBUG = False if DEBUG: app = FastAPI(title="Pulse", version="0.1.0") templates = Jinja2Templates(directory="templates") else: app = FastAPI( title="Pulse", version="0.1.0", docs_url=None, # 关闭对外暴露的 Swagger /docs redoc_url=None, # 关闭 ReDoc 文档 ) # 模板目录(替换为你自己的绝对路径) templates = Jinja2Templates(directory="/home/yourusername/tktools/app/Pulse/templates") -
使用
pa创建 ASGI 网站(命令与前文一致,这里再贴一次方便对照):pa website create \ --domain yourusername.pythonanywhere.com \ --command '/home/yourusername/.virtualenvs/my_venv/bin/uvicorn --app-dir /home/yourusername/tktools/app/Pulse --uds ${DOMAIN_SOCKET} main:app' -
如果 Bash Console 是在创建 API token 之前开的,可能会报错提示没有 token。
解决方案:
-
要么关掉当前 Bash,重新开一个;
-
要么手动导出环境变量:
export PA_API_TOKEN="你的API_TOKEN"
重新打开 Bash 后记得先激活虚拟环境:
workon my_venv -
-
常用的
pa操作命令:查看 website 运行状态:
pa website get重启网站:
pa website reload --domain yourusername.pythonanywhere.com查看日志(在 Web 页面里也可以点击可视化日志):
tail -50 /var/log/yourusername.pythonanywhere.com.access.log tail -50 /var/log/yourusername.pythonanywhere.com.error.log tail -50 /var/log/yourusername.pythonanywhere.com.server.log删除网站:
pa website delete --domain YOURUSERNAME.pythonanywhere.com支持 HTTPS(应该是自定义域名场景,free 账号一般用不到):
pa website create-autorenew-cert --domain YOURCUSTOMDOMAIN -
其他官方参考:
...