
简介
最近搭了一套自己的漫画库。漫画下载好以后放进 Komga,服务跑在 Kubernetes 里,iPhone 上用 KMReader 看。文件和阅读进度都在自己手里,用起来比我原来想的省事。
我现在的用法
整个流程没多复杂:
漫画网站下载
↓
上传到 Komga 的 /data
↓
Komga 扫描和整理
↓
iPhone 用 KMReader 阅读
Komga 负责服务端。它会扫描本地目录,把漫画分成系列和书籍,还能管理封面、元数据和阅读进度。
KMReader 是 iOS 上的 Komga 原生客户端。能在线读,也能整本下载到手机离线看。进度会自动同步回 Komga。我用的就是国区这个版本:
漫画文件来源就不展开了。注意一下版权,尽量只整理自己有权获取的内容。
为什么用 Komga
我一开始只是想找个 iOS 漫画阅读器。后来发现只在手机里塞文件不太好管,换设备、清缓存、同步进度都麻烦。
Komga 正好把这些事挪到服务端。它支持 cbz、zip、cbr、rar、pdf 和 epub。浏览器里也能直接看,不过我平时还是用 KMReader。
还有个原因是它很适合我现在的自托管环境。服务跑在 K8s 里,Traefik 暴露 HTTPS,ArgoCD 管配置。和我其他服务的部署方式一样,不用再单独维护一套。
K8s 部署
Komga 官方 Docker 文档里有几个关键点:
- 服务端口是
25600 /config存数据库和配置/data放漫画文件- 容器可以用
1000:1000运行 /config要放在本地文件系统,不建议用 CIFS 或 NFS
我这里用的是 StatefulSet,只跑一个副本。存储也只要一个 Volume,再用 subPath 分成 config 和 data 两个目录。
核心配置是这样:
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
