YU.
技术 ·
置顶

宝塔面板 Docker 博客完整发布与更新指南

Docker更新博客环境

宝塔面板 Docker 博客完整发布与更新指南 封面

宝塔面板 Docker 博客完整发布与更新指南

适用环境:Ubuntu/Linux、宝塔面板、Docker Compose V2、linux/amd64 服务器。
部署方式:本地构建 Docker 镜像,服务器只负责加载镜像,不在服务器编译源码。


一、最终服务器目录结构

服务器只需要保留以下内容:

Text
/www/wwwroot/zhu-blog/
├── .env
├── docker-compose.bt.yml
└── storage/
    └── uploads/

每次更新时,临时上传两个镜像 TAR:

Text
/www/wwwroot/zhu-blog/
├── panxi-blog-backend-版本-linux-amd64.tar
└── panxi-blog-frontend-版本-linux-amd64.tar

更新完成并验证成功后,两个 TAR 可以删除。

服务器不再需要:

Text
backend/
frontend/
src/
migrations/
node_modules/
Dockerfile
源码文件
历史 ZIP/TAR 发布包

二、本地提交代码

2.1 提交后端

在 Windows PowerShell 中执行:

PowerShell
cd D:\code\backend\blog-backend

git status
git add -A
git commit -m "release: 发布新版本"
git log -1 --oneline

如果没有需要提交的内容,Git 会提示工作区干净,可以继续打包。

2.2 提交前端

PowerShell
cd D:\code\frontend\blog-frontend

git status
git add -A
git commit -m "release: 发布新版本"
git log -1 --oneline

三、本地打包 Docker 镜像

3.1 设置版本号

只需要修改一次版本号:

PowerShell
$Version = "v2-$(Get-Date -Format 'yyyyMMdd-HHmm')-update"

生成示例:

Text
v2-20260816-2030-update

版本号只能包含:

Text
英文字母、数字、点、下划线、短横线

3.2 打包后端

PowerShell
cd D:\code\backend\blog-backend

.\scripts\package-image.ps1 `
  -Version $Version `
  -Platform "linux/amd64"

生成文件:

Text
D:\code\backend\blog-backend\release\
├── panxi-blog-backend-版本-linux-amd64.tar
└── panxi-blog-backend-版本-linux-amd64.zip

3.3 打包前端

PowerShell
cd D:\code\frontend\blog-frontend

.\scripts\package-image.ps1 `
  -Version $Version `
  -Platform "linux/amd64"

生成文件:

Text
D:\code\frontend\blog-frontend\release\
├── panxi-blog-frontend-版本-linux-amd64.tar
└── panxi-blog-frontend-版本-linux-amd64.zip

3.4 检查生成的文件

PowerShell
$BackendTar = "D:\code\backend\blog-backend\release\panxi-blog-backend-$Version-linux-amd64.tar"
$FrontendTar = "D:\code\frontend\blog-frontend\release\panxi-blog-frontend-$Version-linux-amd64.tar"

Get-Item $BackendTar, $FrontendTar |
  Select-Object Name, Length, LastWriteTime

检查 SHA256:

PowerShell
Get-FileHash -Algorithm SHA256 -LiteralPath $BackendTar
Get-FileHash -Algorithm SHA256 -LiteralPath $FrontendTar

保存输出的 SHA256,上传后可以再次比对。


四、ZIP 是否需要解压

推荐直接上传 .tar,不需要上传 .zip

Docker 可以直接加载 TAR:

Bash
docker load -i 镜像文件.tar

不要执行:

Bash
tar -xf 镜像文件.tar

Docker 镜像 TAR 不需要手动解压。

ZIP 主要用于本地归档。如果只保留了 ZIP,可以在本地解压:

PowerShell
$BackendUnpack = "D:\code\release-unpacked\backend-$Version"
$FrontendUnpack = "D:\code\release-unpacked\frontend-$Version"

Expand-Archive `
  -LiteralPath "D:\code\backend\blog-backend\release\panxi-blog-backend-$Version-linux-amd64.zip" `
  -DestinationPath $BackendUnpack `
  -Force

Expand-Archive `
  -LiteralPath "D:\code\frontend\blog-frontend\release\panxi-blog-frontend-$Version-linux-amd64.zip" `
  -DestinationPath $FrontendUnpack `
  -Force

然后从解压目录中找到 TAR 并上传。


五、上传发布包

5.1 使用宝塔面板上传

打开:

Text
宝塔面板 → 文件 → /www/wwwroot/zhu-blog

直接上传:

Text
panxi-blog-backend-版本-linux-amd64.tar
panxi-blog-frontend-版本-linux-amd64.tar

不需要创建 backendfrontend 目录。


5.2 使用 SCP 上传

在本地 PowerShell 中执行:

PowerShell
$Server = "root@服务器IP"
$RemoteDir = "/www/wwwroot/zhu-blog/"

scp $BackendTar "${Server}:${RemoteDir}"
scp $FrontendTar "${Server}:${RemoteDir}"

示例:

PowerShell
scp "D:\code\backend\blog-backend\release\panxi-blog-backend-v2-20260816-update-linux-amd64.tar" root@服务器IP:/www/wwwroot/zhu-blog/

scp "D:\code\frontend\blog-frontend\release\panxi-blog-frontend-v2-20260816-update-linux-amd64.tar" root@服务器IP:/www/wwwroot/zhu-blog/

六、部署前备份

6.1 设置目录和备份编号

登录服务器后执行:

Bash
APP_DIR=/www/wwwroot/zhu-blog
BACKUP_TIME=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="/www/backup/zhu-blog/$BACKUP_TIME"

mkdir -p "$BACKUP_DIR"
chmod 700 "$BACKUP_DIR"

6.2 备份环境变量和 Compose 配置

Bash
cp -a "$APP_DIR/.env" "$BACKUP_DIR/.env"
cp -a "$APP_DIR/docker-compose.bt.yml" "$BACKUP_DIR/docker-compose.bt.yml"

6.3 备份上传文件

Bash
tar -czf "$BACKUP_DIR/storage.tar.gz" \
  -C "$APP_DIR" \
  storage

检查备份:

Bash
ls -lah "$BACKUP_DIR"
du -sh "$BACKUP_DIR"

6.4 备份数据库

如果数据库由宝塔管理,推荐使用:

Text
宝塔面板 → 数据库 → 对应数据库 → 备份

如果服务器已经安装 pg_dump,也可以执行:

Bash
set -a
source /www/wwwroot/zhu-blog/.env
set +a

pg_dump \
  --dbname="$DATABASE_URL" \
  --format=custom \
  --file="$BACKUP_DIR/database.dump"

unset DATABASE_URL

检查数据库备份:

Bash
ls -lh "$BACKUP_DIR/database.dump"

如果提示:

Text
pg_dump: command not found

请使用宝塔数据库备份功能,不要因为缺少该命令而中断其他部署步骤。


七、为当前镜像创建回滚标签

更新前给旧镜像添加回滚标签。添加标签不会复制镜像,不会立即额外占用大量空间。

Bash
ROLLBACK_TAG=$(date +%Y%m%d-%H%M%S)

docker tag \
  panxi-blog-backend:local \
  "panxi-blog-backend:rollback-$ROLLBACK_TAG"

docker tag \
  panxi-blog-frontend:local \
  "panxi-blog-frontend:rollback-$ROLLBACK_TAG"

echo "本次回滚标签:$ROLLBACK_TAG"

记住输出的回滚编号。

查看回滚镜像:

Bash
docker image ls | grep panxi-blog

八、校验上传文件

先设置本次版本号:

Bash
VERSION="v2-20260816-update"

APP_DIR=/www/wwwroot/zhu-blog
BACKEND_TAR="panxi-blog-backend-${VERSION}-linux-amd64.tar"
FRONTEND_TAR="panxi-blog-frontend-${VERSION}-linux-amd64.tar"

根据实际文件名修改 VERSION

检查文件:

Bash
ls -lh \
  "$APP_DIR/$BACKEND_TAR" \
  "$APP_DIR/$FRONTEND_TAR"

计算服务器 SHA256:

Bash
sha256sum \
  "$APP_DIR/$BACKEND_TAR" \
  "$APP_DIR/$FRONTEND_TAR"

将结果与本地 PowerShell 的 Get-FileHash 结果比较。

SHA256 一致后再继续部署。


九、加载新 Docker 镜像

Bash
cd /www/wwwroot/zhu-blog

docker load -i "$BACKEND_TAR"
docker load -i "$FRONTEND_TAR"

加载后检查:

Bash
docker image inspect panxi-blog-backend:local \
  --format '后端镜像={{.Id}} 创建时间={{.Created}}'

docker image inspect panxi-blog-frontend:local \
  --format '前端镜像={{.Id}} 创建时间={{.Created}}'

十、部署新版本

执行:

Bash
cd /www/wwwroot/zhu-blog

docker compose -f docker-compose.bt.yml \
  up -d \
  --force-recreate \
  --remove-orphans

不需要先执行:

Bash
docker compose down

up -d --force-recreate 会重新创建容器,通常只有短暂中断。


十一、验证部署结果

11.1 检查容器状态

Bash
docker compose \
  -f /www/wwwroot/zhu-blog/docker-compose.bt.yml \
  ps

正常状态应类似:

Text
backend    Up ... (healthy)
frontend   Up ...

11.2 检查后端健康状态

Bash
curl -fsS http://127.0.0.1:5800/api/health

查看 HTTP 状态:

Bash
curl -I http://127.0.0.1:5800/api/health

11.3 检查前端

Bash
curl -I http://127.0.0.1:3000

正常应返回:

Text
HTTP/1.1 200

或其他正常的 2xx/3xx 响应。


11.4 检查容器和本地镜像 ID

检查后端:

Bash
docker image inspect panxi-blog-backend:local \
  --format '后端本地镜像={{.Id}}'

docker inspect \
  --format '后端容器镜像={{.Image}} 配置名称={{.Config.Image}}' \
  "$(docker compose -f /www/wwwroot/zhu-blog/docker-compose.bt.yml ps -q backend)"

检查前端:

Bash
docker image inspect panxi-blog-frontend:local \
  --format '前端本地镜像={{.Id}}'

docker inspect \
  --format '前端容器镜像={{.Image}} 配置名称={{.Config.Image}}' \
  "$(docker compose -f /www/wwwroot/zhu-blog/docker-compose.bt.yml ps -q frontend)"

本地镜像 ID 和容器镜像 ID 应一致。


11.5 查看日志

后端日志:

Bash
docker compose \
  -f /www/wwwroot/zhu-blog/docker-compose.bt.yml \
  logs --tail=100 backend

前端日志:

Bash
docker compose \
  -f /www/wwwroot/zhu-blog/docker-compose.bt.yml \
  logs --tail=100 frontend

持续查看日志:

Bash
docker compose \
  -f /www/wwwroot/zhu-blog/docker-compose.bt.yml \
  logs -f --tail=100

Ctrl+C 退出日志查看,不会停止容器。


11.6 浏览器功能验证

至少检查:

  • 网站首页能正常打开
  • 网站顶部名称显示正确
  • 图片和历史上传文件能正常访问
  • 后台可以正常登录
  • 文章列表能正常加载
  • 文章发布、下线、删除、置顶操作正常
  • 置顶文章存在对应标记
  • 最多只允许置顶三篇文章
  • 深色背景下按钮文字清晰可见

十二、部署失败时回滚

假设部署前生成的回滚标签是:

Text
20260816-203000

设置回滚编号:

Bash
ROLLBACK_TAG="20260816-203000"

把旧镜像重新标记为 local

Bash
docker tag \
  "panxi-blog-backend:rollback-$ROLLBACK_TAG" \
  panxi-blog-backend:local

docker tag \
  "panxi-blog-frontend:rollback-$ROLLBACK_TAG" \
  panxi-blog-frontend:local

重新创建容器:

Bash
cd /www/wwwroot/zhu-blog

docker compose -f docker-compose.bt.yml \
  up -d \
  --force-recreate \
  --remove-orphans

验证:

Bash
docker compose -f docker-compose.bt.yml ps
curl -fsS http://127.0.0.1:5800/api/health
curl -I http://127.0.0.1:3000

十三、验证成功后清理发布包

13.1 查看待删除的 TAR、ZIP 和临时文件

只检查根目录,不进入其他目录:

Bash
find /www/wwwroot/zhu-blog \
  -maxdepth 1 \
  -type f \
  \( \
    -name 'panxi-blog-*.tar' \
    -o -name 'panxi-blog-*.zip' \
    -o -name '*.upload.tmp' \
  \) \
  -printf '%s bytes\t%TY-%Tm-%Td %TH:%TM\t%p\n'

13.2 删除历史发布包

确认部署成功后执行:

Bash
find /www/wwwroot/zhu-blog \
  -maxdepth 1 \
  -type f \
  \( \
    -name 'panxi-blog-*.tar' \
    -o -name 'panxi-blog-*.zip' \
    -o -name '*.upload.tmp' \
  \) \
  -delete

这只会清理 /www/wwwroot/zhu-blog 根目录中的发布包,不会进入 storage


十四、清理旧 Docker 镜像

14.1 部署刚完成时先不要清理回滚镜像

建议观察一段时间,确认网站完全正常后再删除回滚标签。

查看镜像:

Bash
docker image ls | grep panxi-blog

14.2 删除指定回滚镜像

Bash
ROLLBACK_TAG="实际回滚编号"

docker image rm \
  "panxi-blog-backend:rollback-$ROLLBACK_TAG" \
  "panxi-blog-frontend:rollback-$ROLLBACK_TAG"

然后清理没有标签、没有容器使用的旧镜像层:

Bash
docker image prune -f

查看 Docker 空间:

Bash
docker system df

不要随意执行:

Bash
docker system prune -a

因为它可能删除备用镜像和其他暂时未运行的镜像。


十五、下载并清理服务器备份

验证新版本稳定后,将备份下载到本地。

在本地 PowerShell 中执行:

PowerShell
scp -r root@服务器IP:/www/backup/zhu-blog/备份编号 "D:\code\backups\"

确认本地备份完整后,服务器上可以删除对应备份目录:

Bash
rm -rf -- "/www/backup/zhu-blog/准确的备份编号"

删除前必须确认路径包含具体备份编号,不要直接删除:

Text
/www/backup
/www/backup/zhu-blog
/

十六、最终空间检查

检查博客目录:

Bash
du -xhd 2 /www/wwwroot/zhu-blog | sort -h

检查磁盘:

Bash
df -h /www/wwwroot/zhu-blog

检查 Docker:

Bash
docker system df

检查最终文件:

Bash
find /www/wwwroot/zhu-blog \
  -maxdepth 2 \
  -printf '%y\t%p\n' \
  | sort

正常情况下最终主要保留:

Text
/www/wwwroot/zhu-blog/.env
/www/wwwroot/zhu-blog/docker-compose.bt.yml
/www/wwwroot/zhu-blog/storage
/www/wwwroot/zhu-blog/storage/uploads

十七、日常更新最简流程

本地 PowerShell

PowerShell
$Version = "v2-$(Get-Date -Format 'yyyyMMdd-HHmm')-update"

cd D:\code\backend\blog-backend
.\scripts\package-image.ps1 -Version $Version -Platform "linux/amd64"

cd D:\code\frontend\blog-frontend
.\scripts\package-image.ps1 -Version $Version -Platform "linux/amd64"

$BackendTar = "D:\code\backend\blog-backend\release\panxi-blog-backend-$Version-linux-amd64.tar"
$FrontendTar = "D:\code\frontend\blog-frontend\release\panxi-blog-frontend-$Version-linux-amd64.tar"

scp $BackendTar root@服务器IP:/www/wwwroot/zhu-blog/
scp $FrontendTar root@服务器IP:/www/wwwroot/zhu-blog/

服务器

修改版本号后执行:

Bash
VERSION="实际版本号"
APP_DIR=/www/wwwroot/zhu-blog

cd "$APP_DIR"

docker tag panxi-blog-backend:local "panxi-blog-backend:rollback-$(date +%Y%m%d-%H%M%S)"
docker tag panxi-blog-frontend:local "panxi-blog-frontend:rollback-$(date +%Y%m%d-%H%M%S)"

docker load -i "panxi-blog-backend-${VERSION}-linux-amd64.tar"
docker load -i "panxi-blog-frontend-${VERSION}-linux-amd64.tar"

docker compose -f docker-compose.bt.yml \
  up -d \
  --force-recreate \
  --remove-orphans

docker compose -f docker-compose.bt.yml ps

curl -fsS http://127.0.0.1:5800/api/health
curl -I http://127.0.0.1:3000

确认成功后删除本次发布包:

Bash
rm -f -- \
  "/www/wwwroot/zhu-blog/panxi-blog-backend-${VERSION}-linux-amd64.tar" \
  "/www/wwwroot/zhu-blog/panxi-blog-frontend-${VERSION}-linux-amd64.tar"

docker image prune -f
df -h /www/wwwroot/zhu-blog

十八、重要注意事项

  1. 服务器不再编译前后端源码。
  2. 不需要上传 srcmigrationsnode_modules 等源码目录。
  3. 发布时只上传两个 Docker 镜像 TAR。
  4. Docker 镜像 TAR 不需要执行 tar -xf
  5. 更新前必须备份 .env、Compose、上传文件和数据库。
  6. 不需要执行 docker compose down
  7. 删除 TAR 不会删除已经加载到 Docker 中的镜像。
  8. 必须保留 .envdocker-compose.bt.ymlstorage/uploads
  9. 不要删除当前使用的 panxi-blog-backend:localpanxi-blog-frontend:local 镜像。
  10. 不要使用 docker system prune -a 进行无差别清理。
TAGS #Rust #Vue 3
DISCUSSION

留下你的想法

0 条评论
还没有公开评论,来成为第一个留言的人吧。

写下评论

评论审核通过后公开显示,邮箱只用于识别身份,不会对外展示。

保持热爱,奔赴山海。

STAY CURIOUS · KEEP GOING