CBZ Tagger is a tool to tag comic book files in CBZ format. Many cbz based files are incorrectly formatted in ways that are not compatible with the ComicInfo.xml format. This tool utilizes public metadata sources to tag the files correctly. It populates the majority of fields specified by the ComicRack metadata format. Additionally, it is capable of retrieving the cover image from the metadata source and embedding it into the CBZ file along with correctly formatting the file structure to be compatible with readers such as Komga.
CBZ Tagger ships with a web UI (React, served by the same container on port 8080) for browsing tracked series,
adding new series, and managing configuration. The command line interface is also available for scripted or
one-off usage. CBZ Tagger implements a tracking and refresh system to help keep your library up to date, and this
has been undergoing continuous revisions to try and make the API processing more robust.
If you discover issues while using CBZ Tagger, please feel free to file an issue in github. This helps to improve the code base and keep the tool functional and reliable!
CBZ tagger is best run as a docker image. It is published to the
GitHub Container Registry and can be installed
with docker pull ghcr.io/mjnitz02/cbz-tagger:latest. CBZ Tagger can be run locally through
python by executing python cbz-tagger/run.py and specifying the environment variables defined below. If no variables
are specified everything will be run in the root directory of the project. Because CBZ Tagger is designed to run
continuously 24/7, it is recommended to run it as a docker container on some sort of always on infrastructure (e.g. a
home server). CBZ Tagger is developed and tested primarily using Unraid, but should work on any docker compatible
system.
Note
Unless a parameter is flaged as 'optional', it is mandatory and a value must be provided.
Important
As of v5.2.0 images are published to ghcr.io/mjnitz02/cbz-tagger. The old Docker Hub repository
(mjnitz02/cbz_tagger) is deprecated and will not receive new releases — update your image reference to keep
getting updates.
docker-compose (recommended, click here for more info)
A ready-to-edit file is provided in the repo as
docker-compose.example.yaml. Copy it to docker-compose.yaml, adjust the volume
paths, and run docker compose up -d.
---
services:
cbztagger:
image: ghcr.io/mjnitz02/cbz-tagger:latest
container_name: cbztagger
restart: unless-stopped
environment:
- TIMER_DELAY=43200
- PROXY_URL=http://proxy:3128
- PUID=1000
- PGID=1000
- UMASK=002
volumes:
- /path/to/cbz_tagger/config:/config
- /path/to/import:/scan
- /path/to/storage:/storage
ports:
- 8080:8080docker cli (click here for more info)
docker run -d \
--name=cbztagger \
-e TIMER_DELAY=43200 \
-e PROXY_URL=http://proxy:3128 \
-e PUID=1000 \
-e PGID=1000 \
-e UMASK=002 \
-v /path/to/cbz_tagger/config:/config \
-v /path/to/import:/scan \
-v /path/to/storage:/storage \
ghcr.io/mjnitz02/cbz-tagger:latestA container template is kept in the repo at unraid-template.xml. It is not published to
Community Applications, so add it manually: on the Unraid Docker tab choose Add Container, then paste the
following into the Template field:
https://raw.githubusercontent.com/mjnitz02/cbz-tagger/main/unraid-template.xml
The template pre-fills the ports, paths and environment variables described below, defaulting PUID/PGID to
Unraid's nobody/users (99/100). Point Scan and Storage at the shares you use for imports and your
tagged library.
Containers are configured using parameters passed at runtime (such as those above). These parameters are separated by
a colon and indicate <external>:<internal> respectively. For example, -p 8080:80 would expose port 80 from
inside the container to be accessible from the host's IP on port 8080 outside the container.
| Parameter | Function |
|---|---|
-p 8080:8080 |
WebUI |
-e TIMER_DELAY=43200 |
The default number of seconds to wait between scans. It is recommended to set this to at least several hours. |
-e PROXY_URL=None |
Specify the URL of the http proxy. All requests will be redirected, proxy must be available if defined. |
-e PUID=1000 |
for UserID - see below for explanation |
-e PGID=1000 |
for GroupID - see below for explanation |
-e UMASK=002 |
File mode creation mask for everything written to /storage.002 gives directories 775 and files 664; 022 gives 755/644. |
-e TZ=Etc/UTC |
specify a timezone to use, see this list. |
-v /config |
Persistent config files |
-v /scan |
Path to scan for new files that will be imported on scan. |
-v /storage |
Path to store all processed files. |
When using volumes (-v flags), permissions issues can arise between the host OS and the container, we avoid this issue by allowing you to specify the user PUID and group PGID.
Ensure any volume directories on the host are owned by the same user you specify and any permissions issues will vanish like magic.
In this instance PUID=1000 and PGID=1000, to find yours use id your_user as below:
id your_userPUID, PGID and UMASK apply to /storage only. That directory is your library — it is shared with readers and
other containers, so everything written there is given the ownership and mode you specify. /config holds the
container's own database and cover cache and is left owned by whoever the container runs as.
Note
Before v5.2.0 UMASK was read but never applied, so directories were always created 755 regardless of what you
set, and ownership was only applied to directories at the moment they were created. Existing folders are now
re-checked as the library is processed, so a library with wrong permissions will heal itself over subsequent scans
rather than needing a manual chown -R.
Development and contribution to the project is welcome. Please feel free to fork the project and submit a pull request.
There are a variety of make commands designed to make development easier. Additionally, the codebase features a
comprehensive suite of unit and integration tests. These are all designed to be run using pytest. The integration
tests will allow you to execute commands against the backend by mocking the docker environment. This is useful for
testing the API and ensuring that the code is functioning as expected.
All code contributions should contain sufficient test additions to the codebase. This is to ensure that the code is maintainable and that new features do not break existing functionality.
- Docker (https://docs.docker.com/engine/install/)
- uv (https://docs.astral.sh/uv/getting-started/installation/)
- Python 3.13 (https://www.python.org/downloads/)
You can set up the environment using uv to create a virtual environment. This will allow you to install the
required dependencies without affecting your system Python installation.
make installYou can also install pre-commit hooks to ensure that code is formatted correctly and passes linting checks before
committing.
make pre-commit-install# Run the full test suite locally and in Docker
make test
# Run unit tests only (locally or in Docker)
make test-unit
make test-unit-docker
# Run integration tests only (locally or in Docker)
make test-integration
make test-integration-dockermake run-docker