QinMgr 博客工作流配置与使用

QinMgr 博客工作流配置与使用

最近更新了博客框架,连带优化了一下我的博客工作流:通过QinMgr进行日常写作和快速发布。
整个工作流由三个项目构成,其中QinBlog博客引擎开源,其余私有:

  • QinMgr:管理台、配置、工作流入口、Docker 运行单元。
  • QinBlog:Astro 博客引擎、主题、构建逻辑、站点配置。
  • QinBlog-Post:Markdown 文章源文件,作为写作数据源长期保存。

三者互相解耦,QinMgr 镜像不打包 QinBlog,也不打包文章,运行后再通过页面配置拉取。

整个项目先由docker构建QinMgr,在Mgr中配置拉取博客引擎和文章,并将文章映射到主机目录,主机通过samba服务进行局域网共享。

目录模型

当前树莓派上的工作目录是:

/home/lyra/workspace/QinMgr/QinMgr

关键路径如下:

QinMgr/ ├── docker-compose.yml ├── data/ │ ├── config.json # QinMgr 运行配置,不提交 Git │ └── blog_posts/ │ ├── posts/ # 文章 Markdown,建议用 Samba 共享这个目录 │ └── images/ # 文章图片镜像目录 └── project/ └── QinBlog/ # 非 Docker bind mount 时通常在 named volume 内

Docker Compose 当前持久化三类数据:

volumes: - ./data:/app/data - qinmgr_project:/app/project - qinmgr_ssh:/app/.ssh

含义:

  • ./data:/app/data:宿主机当前目录下的 data/ 映射到容器 /app/data,保存配置、文章、上传文件和图片。
  • qinmgr_project:/app/project:Docker named volume,保存 QinBlog 引擎仓和 node_modules
  • qinmgr_ssh:/app/.ssh:Docker named volume,保存 QinMgr 生成的 SSH key,容器重建后仍然可用。

QinMgr 初始化配置

在树莓派上准备目录:

mkdir -p /home/lyra/workspace/QinMgr cd /home/lyra/workspace/QinMgr

如果树莓派还没有配置本机 GitHub SSH key,按照如下操作

ssh-keygen -t ed25519 -C "qinmgr@raspberry-pi"

一路回车即可使用默认位置:

/home/lyra/.ssh/id_ed25519

然后打印公钥,复制整行内容到 GitHub:

cat ~/.ssh/id_ed25519.pub

GitHub 添加位置:

GitHub -> Settings -> SSH and GPG keys -> New SSH key

登记后测试连接:

ssh -T git@github.com

第一次连接会提示是否信任 github.com,输入 yes。如果看到类似 Hi QinAoi! You've successfully authenticated,说明 SSH key 已生效。

如果树莓派已经配置好 GitHub SSH key,推荐用 SSH 拉取:

git clone git@github.com:QinAoi/QinMgr.git cd QinMgr

如果暂时只能用 HTTPS,GitHub 不支持直接输入登录密码,需要使用 Personal Access Token:

git clone https://github.com/QinAoi/QinMgr.git cd QinMgr

长期建议使用 SSH,因为 QinMgr 自身、QinBlog 私有仓和文章仓都可能依赖 SSH 认证。

Docker 构建与启动

拉取项目后,在 QinMgr 项目根目录执行:

cd /home/lyra/workspace/QinMgr/QinMgr docker compose up -d --build

检查容器状态:

docker compose ps docker compose logs -f qinmgr

浏览器访问:

http://<Host-IP>:8000

当前 Compose 暴露两个端口:

  • 8000:QinMgr 管理页面、文件共享 /share/、聊天室 /chat/
  • 4321:QinBlog dev 预览,也就是 Astro 本地开发服务器。

首次使用 QinMgr

首次打开 QinMgr 后,先完成全局配置,再执行拉取和构建。

配置 Git 认证

进入「全局设置」查看或生成 QinMgr 服务端 SSH key。私有仓库需要把公钥登记到 GitHub:

GitHub -> Settings -> SSH and GPG keys -> New SSH key

容器内的 SSH key 会保存在 qinmgr_ssh 这个 Docker volume 中,容器重建不会丢。

配置 QinBlog 引擎仓

在「全局设置」填写 QinBlog 引擎仓地址。

私有仓推荐:

git@github.com:QinAoi/QinBlog.git

公共仓也可以使用 HTTPS:

https://github.com/QinAoi/QinBlog.git

然后执行:

获取分支 -> 选择 main -> 保存 -> 更新引擎

「更新引擎」会做这些事:

  • 空目录时执行 git clone
  • 已存在仓库时执行 fetch + reset --hard origin/<分支> + clean -fd
  • 更新完成后自动执行 pnpm install --frozen-lockfile

这里的设计是让本地 QinBlog 始终强制对齐上游,引擎源码不要在运行环境里手改。

配置文章内容仓

在「全局设置」填写内容仓地址。文章管理页顶部会显示内容仓状态,并提供「下载 / 上传」。

首次使用时点击「下载」:

  • posts/ 为空时会 clone 内容仓。
  • 已存在内容仓时会执行 git pull --ff-only

写完文章后点击「上传」:

  • QinMgr 会执行 git add -A
  • 自动提交。
  • 推送到远端内容仓。

Blog dev 预览

在「Blog 部署」页面点击 Dev,会在容器内启动 QinBlog 开发服务器。访问:

http://<树莓派IP>:4321

Docker 里只有端口映射还不够,QinMgr 会用下面的方式启动 dev,使 Astro 监听所有网卡:

pnpm dev --host 0.0.0.0

如果图床或 CDN 开启了防盗链,dev 预览页可能加载不到图片。需要把预览地址加入白名单:

http://<Host-IP>:4321

具体是加 Referer 白名单还是 IP 白名单,取决于图床/CDN 的防盗链规则。

Samba 共享文章目录

为了在 Windows 上直接用 Typora 或 VS Code 写文章,推荐在树莓派宿主机配置 Samba,只共享文章目录:

/home/lyra/workspace/QinMgr/QinMgr/data/blog_posts/posts

不要优先共享整个 QinMgr 项目目录。文章目录是写作边界,误删风险更小。

安装 Samba

sudo apt update sudo apt install -y samba

确认文章目录存在

mkdir -p /home/lyra/workspace/QinMgr/QinMgr/data/blog_posts/posts sudo chown -R lyra:lyra /home/lyra/workspace/QinMgr/QinMgr/data/blog_posts/posts

添加 Samba 用户

sudo smbpasswd -a lyra sudo smbpasswd -e lyra

这里设置的是 Samba 访问密码,不一定等同于 Linux 登录密码。

修改 Samba 配置

编辑:

sudo nano /etc/samba/smb.conf

先确认 [global] 里明确使用用户认证,并禁止降级成 Guest:

[global] security = user map to guest = Never

然后在文件末尾追加共享配置:

[qinblog-posts] path = /home/lyra/workspace/QinMgr/QinMgr/data/blog_posts/posts browseable = yes read only = no writable = yes valid users = lyra guest ok = no create mask = 0644 directory mask = 0755 force user = lyra force group = lyra

这几项的含义是:

  • security = user:要求客户端使用 Samba 用户认证。
  • map to guest = Never:认证失败时不要自动映射成 Guest。
  • valid users = lyra:只允许 lyra 访问这个共享。
  • guest ok = no:明确禁止匿名访问。

检查配置并重启 Samba:

testparm sudo systemctl restart smbd sudo systemctl enable smbd

Windows 访问

在 Windows 文件资源管理器地址栏输入:

\\<树莓派IP>\qinblog-posts

例如:

\\192.168.0.10\qinblog-posts

也可以映射为网络驱动器,之后 Typora、VS Code 都可以直接打开这个目录。

日常写作流程

日常写作时按这个顺序操作:

  1. 在 Windows 通过 Samba 打开 \\<Host-IP>\qinblog-posts(文件管理器 -> 网络 -> 映射网络驱动器)
  2. 新建或修改 Markdown 文章。
  3. 回到 QinMgr 的「文章管理」页面确认文章树。
  4. 文章/配置更新后执行 Build。
  5. 需要预览时进入「Blog 部署」点击 Dev,然后访问 http://<Host-IP>:4321
  6. 确认无误,执行 Deploy 上限到服务器。
  7. 文章需要同步到远端文章仓时点击「上传」。

文章的分类由目录决定。比如:

Project/QinMgr博客工作流.md Linux/Samba配置.md

QinBlog 构建时会把 data/blog_posts/posts/ 同步到:

project/QinBlog/src/content/posts/

同步时会忽略 .git 等目录,避免把内容仓的 Git 元数据复制进 QinBlog。

后续更新

更新 QinMgr

QinMgr 项目更新后,在树莓派上执行:

cd /home/lyra/workspace/QinMgr/QinMgr git pull --ff-only docker compose up -d --build

然后检查状态:

docker compose ps docker compose logs --tail=100 qinmgr

正常情况下不需要删除 volume。下面这些数据会保留:

  • ./data:配置、文章、图片、上传文件。
  • qinmgr_project:QinBlog 引擎仓和 node_modules
  • qinmgr_ssh:QinMgr 服务端 SSH key。

如果只是 QinBlog 引擎更新,不需要重新构建 QinMgr 镜像。直接在 QinMgr 页面点击「更新引擎」即可。

更新 QinBlog 引擎

当 QinBlog 仓库有新提交时:

  1. 打开 QinMgr。
  2. 进入「Blog 部署」。
  3. 点击「更新引擎」。
  4. 等待 git 更新和 pnpm install --frozen-lockfile 完成。
  5. 执行 Dev 或 Build 验证。

引擎仓更新是强制对齐上游的动作。如果需要改 QinBlog 源码,应该在 QinBlog 仓库里修改、提交、推送,再让 QinMgr 拉取。

更新文章仓

如果其它设备也修改了文章仓,在 QinMgr 的「文章管理」点击「下载」:

  • 没有本地提交时会快进更新。
  • 有本地未提交内容时,先确认本地改动,不要盲目覆盖。

我的推荐使用方式是:树莓派上的 data/blog_posts/posts/ 作为主要写作源,Windows 只是通过 Samba 编辑这份数据。这样可以减少多端冲突。

常用排查命令

查看容器:

docker ps docker compose ps

查看日志:

docker compose logs -f qinmgr

进入容器:

docker exec -it qinmgr bash

查看 Docker volume:

docker volume ls docker volume inspect qinmgr_qinmgr_project docker volume inspect qinmgr_qinmgr_ssh

查看宿主机文章目录:

ls -la /home/lyra/workspace/QinMgr/QinMgr/data/blog_posts/posts