NoneBot2 + NapCat 港服 Docker 部署“禁漫下载”Bot 全攻略:避坑指南

发表于
8

如果你也想在香港服务器(或其他海外服务器)上部署一个 NoneBot2 机器人,用于下载“禁漫”内容,并且选择使用 Docker 编排(NoneBot + NapCat/OneBotV11),那么这篇博客就是为你准备的。

这里的“折磨”不是指代码难写,而是指那些让你感觉“配置全对,但就是不工作”的底层细节。

一、 核心架构图

我们采用 Docker Multi-Container 架构。理解这两个容器如何通信和共享文件是解决所有问题的关键。

二、 先把坑踩完:我的折磨历程

在最终成功之前,我卡在了很多莫名其妙的地方:

  1. Docker 启动的“生死时速” (Racy Condition):

    • 现象: 重启服务后,NapCat 日志疯狂报 ECONNREFUSED 172.19.0.x:8080(连接被拒绝)。

    • 坑点: 我们的 jm-bot 启动命令里包含 pip install ...。每次重启容器,它都要联网下载安装几十个复杂的 Python 库(如 pikepdf)。在安装完之前,bot.py 根本没运行,8080 端口也没开。NapCat 启动极快,连不上当然报错。

    • 教训: 在 Docker 环境中,尽量不要在启动命令(CMD/ENTRYPOINT)里跑大规模编译/安装。

  2. “Slim”镜像的沉默陷阱:

    • 现象: 为了节省空间用了 python:3.10-slim 镜像,结果容器显示“运行中”,但完全没有新日志,不报错也不工作,像僵尸一样。

    • 坑点: 禁漫插件依赖的某些库(如 curl-cffi)在安装时需要底层编译工具(GCC 等)。slim 镜像没有这些,导致 pip 安装沉默地崩溃了。

    • 教训: 生产环境部署复杂插件,首选 full 版镜像(如 python:3.10),并设置 PYTHONUNBUFFERED=1 强制输出日志。

  3. Docker 容器间的“叹息之墙”:识别URL失败 / 发送文件失败:

    • 现象: 漫画下好了,转 PDF 也好了,机器人也说话了,最后却报 发送文件失败。查看 NapCat 日志显示 识别URL失败, uri=/root/.cache/.../258435.pdf

    • 坑点: jm-bot 容器把 PDF 打包到了它自己的缓存目录里,然后给 NapCat 发指令:“去这个路径拿文件”。NapCat 站在它自己的集装箱里,怎么可能拿得到别的容器里的文件?

    • 教训: 必须在 docker-compose.yml 中给这两个容器挂载同一个宿主机目录作为共享缓存

  4. 指令匹配的“文字游戏”:

    • 现象: 环境都通了,发 /jm 12345/jm下载 12345 机器人沉默,Debug 日志显示 Checking for matchers completed(检查完毕,无匹配)。

    • 坑点: 我们太依赖习惯了,以为 /jm 是指令名。通过扫描代码才发现,这个插件没有纯粹的 /jm 指令,它的正确指令名是 /jm下载/jm搜索

    • 教训: 遇到沉默,先看 Debug 日志,确认 Matcher 是否加载成功。如果加载成功但无法触发,那就是指令名字对不上。

三、 终极胜利配置 (一键开箱即用)

1. 目录结构

在宿主机建立如下结构:

Bash

/opt/docker-compose/jm-bot/
├── bot/
│   ├── bot.py
│   ├── .env.prod
│   ├── Dockerfile
│   └── (共享目录会自动生成: downloads, cache)
├── napcat/
│   └── (napcat自己的配置目录)
└── docker-compose.yml

2. 核心文件代码

文件 A: bot/Dockerfile (解决依赖安装慢的问题) 我们需要在这个 Dockerfile 里把依赖封死,实现秒速启动。

Dockerfile

# 必须用完整版, slim版缺编译环境
FROM python:3.10

WORKDIR /app
ENV PYTHONUNBUFFERED=1

# 预装所有禁漫机器人需要的核心库,利用Docker缓存
RUN pip install --no-cache-dir --upgrade pip && \
    pip install --no-cache-dir \
    nonebot2[fastapi] \
    nonebot-adapter-onebot \
    nonebot-plugin-alconna \
    nonebot-plugin-jmdownloader \
    nonebot-plugin-apscheduler

# 启动指令
CMD ["python", "bot.py"]

文件 B: bot/.env.prod (关键配置)

Plaintext

ENVIRONMENT=prod
DRIVER=~fastapi
HOST=0.0.0.0
PORT=8080
LOGLEVEL=DEBUG # 强烈建议开启,排错神器
SUPERUSERS=["你的QQ号"] # 必须设置,否则无法使用管理员指令
COMMAND_START=["/"] # 指令前缀

# 核心:无限车票配置
JMCOMIC_USER_LIMITS=99999 # 每人每周下载次数限制,设为无限
JMCOMIC_PUNISH_ON_VIOLATION=False # 彻底关闭违规自动拉黑(车票黑名单)

文件 C: docker-compose.yml (终极通关文件) 关键在于打通两个容器的缓存共享。

YAML

services:
  napcat:
    image: mlikiowa/napcat-docker:latest
    container_name: napcat
    hostname: napcat
    environment:
      - WEBUI_TOKEN=你的登录密码
    ports:
      - "6099:6099" 
    volumes:
      - ./napcat/config:/app/napcat/config
      - ./napcat/qq:/app/.config/QQ
      # 💥 核心共享:打通 NapCat 的缓存任意门,让它能看到 bot 的缓存文件
      - ./bot/cache:/root/.cache/nonebot2
    networks:
      - bot-net
    restart: always

  jm-bot:
    # --- 核心修改:使用 build 模式使用我们自定义的 Dockerfile ---
    build: 
      context: ./bot
      dockerfile: Dockerfile
    container_name: jm-bot
    hostname: jm-bot
    volumes:
      - ./bot:/app
      # 💥 核心共享:把 bot 的缓存文件暴露给宿主机共享目录
      - ./bot/cache:/root/.cache/nonebot2
    working_dir: /app
    depends_on:
      - napcat
    networks:
      - bot-net
    restart: always

networks:
  bot-net:
    driver: bridge

四、 运行与日常使用手册

  1. 启动: 在目录执行 docker-compose up -d --build (第一次需要 --build 构建镜像,以后只需要 up -d)。

  2. 解锁本群权限 (超级管理员在群里发): 为了防止机器人在无关群里发涩图导致 QQ 号被腾讯秒封,插件默认禁止了群聊。必须先解锁: 在群里发:/开启jm (或者 /jm启用群)

  3. 群友使用指令表 (复制给他们): (注意:所有指令前面必须加斜杠 / )

    • 🔍 找漫画:/jm搜索 关键词

    • 📥 下载漫画 (自动发PDF):/jm下载 漫画ID


五、 结语

通过这次部署,再次验证了“Docker 不是万能的”。不理解容器间的隔离机制、不仔细阅读Debug日志、不深入扫描插件代码规则,仅仅依靠 default 配置去撞运气,最终迎来的只能是“超级折磨”。希望这份避坑指南能帮你省下那绝望的几小时。