跳至主要内容

⬇️⬇️⬇️ 欢迎关注我的 telegram 频道和 twitter ⬇️⬇️⬇️


联系方式: Twitter Github Email Telegram

用 Komga 搭一个自己的漫画库

September 3, 2026 2235 字 阅读约 5 分钟
文章目录(9)

简介

最近搭了一套自己的漫画库。漫画下载好以后放进 Komga,服务跑在 Kubernetes 里,iPhone 上用 KMReader 看。文件和阅读进度都在自己手里,用起来比我原来想的省事。

我现在的用法

整个流程没多复杂:

漫画网站下载
上传到 Komga 的 /data
Komga 扫描和整理
iPhone 用 KMReader 阅读

Komga 负责服务端。它会扫描本地目录,把漫画分成系列和书籍,还能管理封面、元数据和阅读进度。

KMReader 是 iOS 上的 Komga 原生客户端。能在线读,也能整本下载到手机离线看。进度会自动同步回 Komga。我用的就是国区这个版本:

KMReader - App Store

漫画文件来源就不展开了。注意一下版权,尽量只整理自己有权获取的内容。

为什么用 Komga

我一开始只是想找个 iOS 漫画阅读器。后来发现只在手机里塞文件不太好管,换设备、清缓存、同步进度都麻烦。

Komga 正好把这些事挪到服务端。它支持 cbzzipcbrrarpdfepub。浏览器里也能直接看,不过我平时还是用 KMReader。

还有个原因是它很适合我现在的自托管环境。服务跑在 K8s 里,Traefik 暴露 HTTPS,ArgoCD 管配置。和我其他服务的部署方式一样,不用再单独维护一套。

K8s 部署

Komga 官方 Docker 文档里有几个关键点:

  • 服务端口是 25600
  • /config 存数据库和配置
  • /data 放漫画文件
  • 容器可以用 1000:1000 运行
  • /config 要放在本地文件系统,不建议用 CIFS 或 NFS

我这里用的是 StatefulSet,只跑一个副本。存储也只要一个 Volume,再用 subPath 分成 configdata 两个目录。

核心配置是这样:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: komga
  namespace: app
spec:
  serviceName: komga
  replicas: 1
  podManagementPolicy: OrderedReady
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: komga
  template:
    metadata:
      labels:
        app: komga
    spec:
      securityContext:
        fsGroup: 1000
        fsGroupChangePolicy: OnRootMismatch
      initContainers:
      - name: init-storage
        image: busybox:1.37.0
        command:
        - sh
        - -c
        - mkdir -p /storage/config /storage/data && chown -R 1000:1000 /storage/config /storage/data
        securityContext:
          runAsUser: 0
          runAsGroup: 0
          allowPrivilegeEscalation: false
        volumeMounts:
        - name: storage
          mountPath: /storage
      containers:
      - name: komga
        image: gotson/komga:1.26.3
        imagePullPolicy: IfNotPresent
        securityContext:
          runAsUser: 1000
          runAsGroup: 1000
          runAsNonRoot: true
          allowPrivilegeEscalation: false
        ports:
        - name: http
          containerPort: 25600
        env:
        - name: TZ
          value: Asia/Shanghai
        - name: JAVA_TOOL_OPTIONS
          value: -Xmx1536m
        volumeMounts:
        - name: storage
          mountPath: /config
          subPath: config
        - name: storage
          mountPath: /data
          subPath: data
  volumeClaimTemplates:
  - metadata:
      name: storage
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: local-path
      resources:
        requests:
          storage: 100Gi

StatefulSet 会生成一个叫 storage-komga-0 的 PVC。/config/data 还是两个独立目录,但底层只有一个 Volume。备份时也省心,整个卷一起处理就行。

initContainer 用来创建目录并修正权限。Komga 自己还是以 1000:1000 跑,不需要让主容器拿 root。

Service 就是普通的 ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: komga
  namespace: app
spec:
  type: ClusterIP
  selector:
    app: komga
  ports:
  - name: http
    port: 80
    targetPort: http

外面走 Traefik,域名是:

https://komga.example.com

创建漫画库

Komga 跑起来以后,先打开 Web 页面创建管理员账号。

左边 Libraries 旁边点 +,新建一个漫画库。Root Folder 选:

/data

Komga 会把书库下面的每个子目录当成一个系列,目录最好提前整理一下:

/data/
├── 海贼王/
│   ├── 海贼王 第001卷.epub
│   ├── 海贼王 第002卷.epub
│   └── 海贼王 第003卷.epub
├── 火影忍者/
│   ├── 火影忍者 第001卷.cbz
│   └── 火影忍者 第002卷.cbz
└── 一拳超人/
    └── 一拳超人 第001卷.cbz

别把所有文件直接堆在 /data 根目录。刚开始看着没什么,书多以后会很乱。

怎么把漫画传进去

Komga 的 Web 页面不是网盘,没有直接选本地文件上传到服务器的按钮。它是扫描服务器上的目录。

我现在用 kubectl cp。先创建系列目录:

kubectl exec -n app komga-0 -- mkdir -p "/data/海贼王"

再把本地文件传进去:

kubectl cp "/本地路径/海贼王 第001卷.epub" \
  app/komga-0:"/data/海贼王/海贼王 第001卷.epub"

传完去 Komga 里执行 Scan Library Files。它会找到新文件,分析格式和页数,再生成封面。

文件多的时候也可以单独留一个导入目录:

/data/import
/data/library

书库根目录设成 /data/library,文件先传到 /data/import。然后在 Import > Books 里扫描,选目标系列,再移动、复制或者硬链接过去。两个目录在同一个 Volume 里,硬链接这条路也能走。

我目前懒得多绕一层,直接按系列传进 /data,传完扫描就行。

KMReader 怎么连

iPhone 打开 KMReader,点 + 添加服务器。

服务器地址填:

https://komga.example.com

这里填根地址就行,不用加 /opds。认证可以选 Komga 用户名密码,也可以用 API Key。连上以后书库、封面和阅读进度都会同步过来。

KMReader 可以给每个系列设置离线策略:

  • Manual:手动下载
  • Latest:自动保留最新几本
  • All:整个系列全部下载

我比较喜欢手动下载。想看哪本就先缓存哪本,不占太多手机空间。断网时照样能看,重新联网以后进度会传回 Komga。

踩过的坑

坑1. Komga 网页里没有普通的上传入口

一开始我还在页面里找了半天。Komga 的逻辑不是接收浏览器上传,而是扫描已经存在于服务器目录里的文件。K8s 环境下最简单的办法就是 kubectl cp,或者另外挂一个下载目录。

坑2. 一个系列要放一个目录

Komga 扫描时会按父目录组织系列。目录没分好,后面整理起来更麻烦。下载完先改好目录和文件名,省得进后台慢慢修。

坑3. /config 不要放网络盘

官方文档专门提醒过,/config 必须使用本地文件系统。这里面有 Komga 的数据库和配置。我直接用了 local-path,和漫画数据放在同一个本地 Volume 里。

坑4. 一个 Volume 要用 subPath 分目录

我不想单独维护两个 PVC,所以只建了一个 storage。容器里分别挂到 /config/data。如果不加 subPath,两个路径看到的会是同一份根目录,目录结构就混了。

坑5. KMReader 填服务器根地址

KMReader 直接调用 Komga API,不是通用 OPDS 阅读器。地址填 https://komga.example.com 就行。加上 OPDS 路径反而连不上正常的 Komga API。

现在这套用下来

我现在下载完漫画,丢进 /data/漫画名/,回 Komga 扫一下。iPhone 打开 KMReader 就能看到。想离线看就提前下载,阅读进度也不用自己记。

这套东西没什么复杂架构。一个 StatefulSet,一个 Volume,一个域名。对我这种已经有 K8s 和 ArgoCD 的环境来说,维护成本基本可以忽略。

后面有空再把下载、目录整理和扫描串起来。目前手动传也够用,先看漫画再说。

欢迎关注我的博客 www.bboy.app

Have Fun