py2htmlblog 发布与部署指南
从构建到上线:三种发布方式的详细配置与最佳实践。
概述
py2htmlblog 执行 python main.py build 后,静态站点生成在 wwwroot/ 目录中。将 wwwroot/ 部署到线上有三种内置方式:
| 方式 | 适用场景 | 传输协议 | 需要安装 |
|---|---|---|---|
| FTP | 虚拟主机、cPanel 空间 | FTP | 无(Python 内置) |
| SFTP | VPS、云服务器 | SSH File Transfer | pip install paramiko |
| Git | GitHub Pages、Gitee Pages | Git | 无(需安装 Git) |
配置写在 data/info.json 的 deploy 字段中,一次配置,一键部署。
FTP 发布
适用场景
- 传统的 PHP 虚拟主机(Bluehost、HostGator、阿里云虚拟主机等)
- 通过 cPanel / DirectAdmin 管理的空间
- 任何支持 FTP 上传的托管服务
配置
在 data/info.json 中添加:
{
"deploy": {
"method": "ftp",
"ftp": {
"host": "ftp.yourdomain.com",
"port": 21,
"user": "ftp_username",
"password": "your-ftp-password",
"remote_dir": "/public_html/"
}
}
}
| 参数 | 说明 |
|---|---|
host |
FTP 服务器地址 |
port |
FTP 端口,默认 21 |
user |
FTP 用户名 |
password |
FTP 密码 |
remote_dir |
远程上传目录。虚拟主机一般是 /public_html/ 或 /htdocs/ |
发布
# 先构建
python main.py build
# 发布到 FTP
python main.py deploy
工作流程
- 连接 FTP 服务器
- 自动创建远程目录结构
- 逐个上传 wwwroot 下所有文件
- 显示上传进度和结果
注意事项
- FTP 密码明文存储在
info.json中,建议将此文件加入.gitignore - 如果虚拟主机支持 SFTP,优先使用 SFTP(加密传输)
- 某些虚拟主机的
remote_dir可能是/或./,按需调整
SFTP 发布
适用场景
- VPS(阿里云 ECS、腾讯云 CVM、AWS EC2 等)
- 云服务器(DigitalOcean、Linode、Vultr 等)
- 任何支持 SSH 登录的 Linux 服务器
安装依赖
pip install paramiko
配置
密码认证
{
"deploy": {
"method": "sftp",
"sftp": {
"host": "123.45.67.89",
"port": 22,
"user": "root",
"password": "your-password",
"remote_dir": "/var/www/html/"
}
}
}
SSH 密钥认证(推荐)
{
"deploy": {
"method": "sftp",
"sftp": {
"host": "123.45.67.89",
"port": 22,
"user": "root",
"key_file": "~/.ssh/id_rsa",
"remote_dir": "/var/www/html/"
}
}
}
| 参数 | 说明 |
|---|---|
host |
服务器 IP 或域名 |
port |
SSH 端口,默认 22 |
user |
SSH 用户名 |
password |
密码(与 key_file 二选一) |
key_file |
SSH 私钥路径(支持 ~ 展开) |
remote_dir |
远程 Web 目录。常见路径:/var/www/html/、/usr/share/nginx/html/ |
发布
# 构建 + 发布
python main.py build
python main.py deploy
智能增量上传
SFTP 发布会自动比较文件修改时间,只上传有变化的文件,跳过未修改的文件,大幅提升多次发布的速度。
# 第一次发布:全部上传
[1/50] ✓ index.html
[2/50] ✓ archives.html
...
# 第二次发布:只上传变更
[1/50] - index.html (未变化,跳过)
[2/50] ✓ archives.html ← 这里改了
[3/50] - rss.xml (未变化,跳过)
...
安全建议
- 优先使用密钥:
password留空,只用key_file - 限制 SSH 用户权限:不要用 root,创建一个只对 Web 目录有写权限的专用用户
- 文件权限:确保远程目录的所有者与 SSH 用户一致
# 在服务器上
sudo chown -R deploy:deploy /var/www/html/
Git 发布
适用场景
- GitHub Pages —
username.github.io仓库 - Gitee Pages — Gitee 提供的静态页面服务
- Coding Pages — 腾讯云开发者平台的静态托管
- 自建 Git 服务器 — 通过 Git Hooks 自动部署
配置
{
"deploy": {
"method": "git",
"git": {
"remote": "origin",
"branch": "main",
"repo_dir": "D:/projects/my-blog",
"commit_message": "Site update: {{date}}",
"sub_dir": ""
}
}
}
| 参数 | 说明 |
|---|---|
remote |
远程仓库名,默认 origin |
branch |
推送分支,GitHub Pages 通常为 main 或 gh-pages |
repo_dir |
本地 Git 仓库的绝对路径 |
commit_message |
提交信息(支持 {{date}} 自动替换为当前日期) |
sub_dir |
子目录(如有需要在仓库子目录中部署) |
GitHub Pages 典型设置
假设你的 GitHub Pages 仓库是 https://github.com/username/username.github.io,已 clone 到本地 D:/projects/username.github.io/:
{
"deploy": {
"method": "git",
"git": {
"remote": "origin",
"branch": "main",
"repo_dir": "D:/projects/username.github.io",
"commit_message": "Blog update {{date}}"
}
}
}
发布流程:
- 清空
D:/projects/username.github.io/下的旧文件(保留.git) - 将
wwwroot/所有文件复制进去 - 执行
git add -A && git commit -m "Blog update 2026-07-22" - 执行
git push origin main - GitHub Actions 自动部署(或直接生效,取决于配置)
Gitee Pages 设置
Gitee Pages 需要手动点击"更新"按钮。推送后记得去 Gitee Pages 设置页触发重新部署。
{
"deploy": {
"method": "git",
"git": {
"remote": "origin",
"branch": "master",
"repo_dir": "D:/projects/gitee-blog",
"commit_message": "Site update"
}
}
}
注意事项
repo_dir必须是已经 clone 好的 Git 仓库- 确保本地仓库已正确设置 remote:
git remote -v - 如果使用 HTTPS 认证,确保已配置 Git 凭据管理器(
git config credential.helper) - 如果使用 SSH 认证,确保 SSH key 已添加到 GitHub/Gitee
模拟运行
不确定配置是否正确?使用 --dry-run 参数预览:
python main.py deploy --dry-run
输出示例:
FTP → ftp_user@ftp.example.com:21
远程目录: /public_html/
文件数: 25
[模拟运行] 不会实际上传
[DRY-RUN] index.html
[DRY-RUN] archives.html
[DRY-RUN] rss.xml
[DRY-RUN] sitemap.xml
[DRY-RUN] css/style.css
[DRY-RUN] archives/cat_log.html
...
一键构建 + 发布
构建和发布是两个步骤,但可以合并为一条命令:
python main.py build && python main.py deploy
或通过 publish 命令(它会先处理 mdblog 再构建,但不包含 deploy):
python main.py publish && python main.py deploy
如果需要更自动化的流程,可以写一个简单的脚本:
Windows (build-and-deploy.bat):
@echo off
python main.py build
if %errorlevel% equ 0 (
python main.py deploy
) else (
echo 构建失败,取消发布
)
Linux/Mac (build-and-deploy.sh):
#!/bin/bash
python main.py build && python main.py deploy
常见问题
Q: FTP 上传失败:"550 Permission denied"
A: 检查 remotedir 路径是否正确。虚拟主机通常不允许写入根目录,确保路径指向 publichtml 或 htdocs。
Q: SFTP 连接超时
A: 检查服务器防火墙是否开放了 SSH 端口(默认 22)。如果服务器换了 SSH 端口,修改 port 参数。
Q: Git push 失败:"Permission denied (publickey)"
A: SSH 密钥未配置或未添加到 GitHub/Gitee。检查:
ssh -T git@github.com # 测试 GitHub 连接
如果失败,重新生成并添加 SSH 密钥。
Q: 为什么 Git 发布要清空仓库?
A: 确保仓库中的文件与 wwwroot 完全同步,避免残留删除的文章页面。如果你有需要在仓库中保留的文件,可以使用 sub_dir 参数将博客部署到子目录。
Q: 可以同时配置多个发布方式吗?
A: 每次只能使用一种。如果需要切换,修改 deploy.method 的值即可。所有子配置(ftp/sftp/git)可以同时填写,系统只读取当前 method 对应的配置。
Q: 上传时会覆盖远程已有文件吗?
A: 会。FTP 和 Git 是全量同步。SFTP 会对比修改时间,只上传变更的文件。