Add Docker image workflow for ani-cli-web

This commit is contained in:
Dymas
2026-05-17 11:26:40 +02:00
parent 68fdc99bbd
commit 48efe840eb
7 changed files with 147 additions and 3 deletions
+12
View File
@@ -0,0 +1,12 @@
.git
.ani-cli-web
downloads
__pycache__
**/__pycache__/
*.py[cod]
*.pyo
.python-version
.venv
venv
env
*.log
+6
View File
@@ -1,5 +1,11 @@
# Changelog
## 0.30.0 - 2026-05-17
- Added a Docker image build that clones `ani-cli` and `ani-cli-web` from configurable git remotes, installs `ani-cli` system-wide, and starts `ani-cli-web` from `/app`.
- Added container startup support for `UPDATE_ON_START=true`, which runs `sudo ani-cli --update` before launching the web app.
- Documented the Docker build arguments, runtime mounts for `./downloads` and `./.ani-cli-web`, and the default container networking and storage layout.
## 0.29.5 - 2026-05-16
- Fixed `/api/config` malformed-body handling so non-object JSON payloads now return `400 Bad Request` instead of silently resetting saved settings to defaults.
+53
View File
@@ -0,0 +1,53 @@
FROM python:3.12-slim
ARG ANI_CLI=https://github.com/pystardust/ani-cli.git
ARG ANI_CLI_BRANCH=master
ARG ANI_CLI_WEB=https://gitea.coreplay.eu/Dymas/ani-cli-web.git
ENV DEBIAN_FRONTEND=noninteractive \
ANI_CLI_REPO=${ANI_CLI} \
ANI_CLI_BRANCH=${ANI_CLI_BRANCH} \
ANI_CLI_WEB_REPO=${ANI_CLI_WEB} \
ANI_CLI_BIN=ani-cli \
ANI_CLI_DOWNLOAD_DIR=/downloads \
ANI_CLI_WEB_HOST=0.0.0.0 \
ANI_CLI_WEB_PORT=8421 \
UPDATE_ON_START=false
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
aria2 \
ca-certificates \
curl \
ffmpeg \
fzf \
git \
grep \
openssl \
patch \
sed \
sudo \
&& rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 --branch "${ANI_CLI_BRANCH}" "${ANI_CLI}" /tmp/ani-cli-src \
&& install -m 0755 /tmp/ani-cli-src/ani-cli /usr/local/bin/ani-cli \
&& ani_cli_raw_repo="$(printf '%s' "${ANI_CLI}" | sed -E 's#^https://github.com/##; s#\\.git$##')" \
&& case "${ANI_CLI}" in \
https://github.com/*) \
sed -i "s|https://raw.githubusercontent.com/pystardust/ani-cli/master/ani-cli|https://raw.githubusercontent.com/${ani_cli_raw_repo}/${ANI_CLI_BRANCH}/ani-cli|" /usr/local/bin/ani-cli ;; \
esac \
&& rm -rf /tmp/ani-cli-src
RUN git clone --depth 1 "${ANI_CLI_WEB}" /app \
&& rm -rf /app/.git
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod 0755 /usr/local/bin/docker-entrypoint.sh \
&& mkdir -p /downloads /app/.ani-cli-web
WORKDIR /app
EXPOSE 8421
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
+55 -1
View File
@@ -2,7 +2,7 @@
A local web UI for a system-wide `ani-cli` install.
Current version: `0.29.5`
Current version: `0.30.0`
## Project Layout
@@ -10,11 +10,13 @@ Current version: `0.29.5`
ani-cli-web/
app.py Public entrypoint, runtime wiring, watchlist domain logic, and CLI startup.
app_support.py Shared runtime/state/config helpers plus queue and library file utilities.
Dockerfile Container image build for system-wide ani-cli plus /app ani-cli-web.
queue_jobs.py Download queue and background watchlist-refresh workers.
watchlist_identity.py Safer watchlist identity resolution for queued download jobs.
title_matching.py Shared anime-title normalization and matching helpers.
http_handler.py HTTP route handling, request parsing, and remote-access guard.
web_templates.py Shared Search, Config, and Watchlist page markup aggregation.
docker-entrypoint.sh Container startup wrapper with optional ani-cli self-update.
search_page.py Search page template.
config_page.py Config page template.
watchlist_page.py Watchlist page template.
@@ -50,6 +52,56 @@ http://127.0.0.1:8421/
By default the server binds to `127.0.0.1:8421`.
## Docker
The container image installs `ani-cli` system-wide and clones `ani-cli-web` into `/app` during `docker build`.
Default build arguments:
```text
ANI_CLI=https://github.com/pystardust/ani-cli.git
ANI_CLI_BRANCH=master
ANI_CLI_WEB=https://gitea.coreplay.eu/Dymas/ani-cli-web.git
```
Build the image:
```sh
docker build -t ani-cli-web .
```
Override the `ani-cli` branch when needed:
```sh
docker build \
--build-arg ANI_CLI_BRANCH=my-feature-branch \
--build-arg ANI_CLI=https://github.com/pystardust/ani-cli.git \
--build-arg ANI_CLI_WEB=https://gitea.coreplay.eu/Dymas/ani-cli-web.git \
-t ani-cli-web .
```
Run the container with the requested persistent mounts:
```sh
docker run --rm \
-p 8421:8421 \
-e UPDATE_ON_START=true \
-v "$(pwd)/downloads:/downloads" \
-v "$(pwd)/.ani-cli-web:/app/.ani-cli-web" \
ani-cli-web
```
Container defaults:
- `ani-cli` is installed at `/usr/local/bin/ani-cli`.
- `ani-cli-web` is cloned into `/app` and started from there.
- Downloads are written to `/downloads`, so bind-mount `./downloads:/downloads`.
- App state stays under `/app/.ani-cli-web`, so bind-mount `./.ani-cli-web:/app/.ani-cli-web`.
- The image sets `ANI_CLI_WEB_HOST=0.0.0.0` and exposes port `8421`.
- `UPDATE_ON_START=true` runs `sudo ani-cli --update` before the web app starts.
The installed `ani-cli` update URL is rewritten during the image build so `ani-cli --update` follows the same `ANI_CLI_BRANCH` you built into the image when the `ANI_CLI` remote is a GitHub repository.
## Overview
`ani-cli-web` keeps search and download management on `/`, saved defaults on `/config`, and the watchlist on `/watchlist`, all with the same sidebar navigation layout and a Tsuki-inspired visual style.
@@ -292,6 +344,7 @@ Environment variables:
- `ANI_CLI_WEB_REMOTE_TOKEN`: required shared secret for non-loopback clients when remote access is enabled.
- `ANI_CLI_WEB_DEBUG`: enable debug logging when set to `1`, `true`, `yes`, or `on`.
- `ANI_CLI_WEB_STATE_ROOT`: override the project-local state directory path; useful for isolated test runs or custom storage locations.
- `UPDATE_ON_START`: when set to `1`, `true`, `yes`, or `on` in the container, runs `sudo ani-cli --update` before `ani-cli-web` starts.
Saved defaults from the UI are written into the project-local `config.json`.
@@ -303,4 +356,5 @@ Saved defaults from the UI are written into the project-local `config.json`.
- The CLI startup path itself also stays lazy now; runtime bootstrap happens when the first runtime-backed request arrives.
- Watchlist and queue data are stored in the same project-local SQLite database file, `state.sqlite3`.
- Runtime folders such as `.ani-cli-web/`, `downloads/`, and Python bytecode cache directories at any depth are ignored by git.
- The Docker image clones both upstream repositories during build, so the app source inside the container comes from the configured git remotes rather than the local build context.
- Focused regression tests live in `test_app.py`, run against an isolated temporary state root, and can be started with `python3 -m unittest test_app.py`.
+1 -1
View File
@@ -1 +1 @@
0.29.5
0.30.0
+1 -1
View File
@@ -16,7 +16,7 @@ from uuid import uuid4
PROJECT_ROOT = Path(__file__).resolve().parent
ANI_CLI = os.environ.get("ANI_CLI_BIN") or shutil.which("ani-cli") or "ani-cli"
APP_NAME = "ani-cli-web"
VERSION = "0.29.5"
VERSION = "0.30.0"
ALLANIME_BASE = "allanime.day"
ALLANIME_API = f"https://api.{ALLANIME_BASE}"
ALLANIME_REFERER = "https://allmanga.to"
+19
View File
@@ -0,0 +1,19 @@
#!/bin/sh
set -eu
is_true() {
case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in
1 | true | yes | on) return 0 ;;
*) return 1 ;;
esac
}
mkdir -p /downloads /app/.ani-cli-web
if is_true "${UPDATE_ON_START:-false}"; then
echo "Checking for ani-cli updates with sudo ani-cli --update"
sudo ani-cli --update
fi
cd /app
exec ./ani-cli-web "$@"