From 596115f26a47cf48859a8ec804b119a5f32db666 Mon Sep 17 00:00:00 2001 From: Nick Vance Date: Sun, 10 May 2026 22:13:50 -0700 Subject: [PATCH 1/4] feat(docker): Add multi-stage build with Ubuntu Resolute and kimageformats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upgrade the Docker image from Ubuntu Noble (24.04) to Ubuntu Resolute (26.06 LTS), adopt the cmake build system, and add support for AVIF, JXL, HEIC, and 20+ additional image formats via kimageformat6-plugins. Changes from upstream develop: - Base: ghcr.io/linuxserver/baseimage-ubuntu:resolute (Ubuntu 26.06 LTS) with Qt 6.10 — avoids Noble's backport packaging complexity - Multi-stage build: separate sevenzip-builder and runtime stages keep the final image lean - RAR support: 7z.so is still built from source (YACReader/yacreader-7z-deps) in a dedicated sevenzip-builder stage and copied into the runtime image; apt 7zip-rar alone does not provide the same RAR codec behavior - kimageformat6-plugins: available directly from Ubuntu Resolute apt (KF6 6.24.0) — no source build required; brings AVIF (libavif16), JXL (libjxl0.11), HEIC (libheif), WebP, and more - Package updates for Resolute: libqt6network6 (was libqt6network6t64), removed libqt6opengl6-dev and libunarr-dev (not available on Resolute) - Fix COPY root.tar.gz path to docker/root.tar.gz to match build context Co-Authored-By: Claude Sonnet 4.6 --- docker/Dockerfile | 58 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index a6fad3761..3f0e43af2 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,34 @@ -FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS builder +FROM ghcr.io/linuxserver/baseimage-ubuntu:resolute AS base + +# ============================================================================ +# Stage: sevenzip-builder +# ============================================================================ +FROM base AS sevenzip-builder + +# get 7zip source +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + 7zip \ + build-essential \ + make \ + wget && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN cd /tmp && \ + wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O 7z2301-src.7z && \ + 7z x 7z2301-src.7z -o/tmp/lib7zip + +# install 7z.so with RAR support +RUN cd "/tmp/lib7zip/CPP/7zip/Bundles/Format7zF" && \ + make -f makefile.gcc && \ + mkdir -p /app/lib/7zip && \ + cp ./_o/7z.so /app/lib/7zip + +# ============================================================================ +# Stage: yacreader-builder +# ============================================================================ +FROM base AS yacreader-builder # repository URL and version, which can be a tag, branch, or commit SHA ARG YACR_REPOSITORY="https://github.com/YACReader/yacreader.git" @@ -28,8 +58,6 @@ RUN \ qt6-tools-dev-tools \ libgl-dev \ qt6-l10n-tools \ - libqt6opengl6-dev \ - libunarr-dev \ qt6-declarative-dev \ libqt6svg6-dev \ libqt6core5compat6-dev \ @@ -55,7 +83,6 @@ RUN \ zlib1g-dev && \ ldconfig - # clone YACReader repo RUN git clone "$YACR_REPOSITORY" /src/git && \ cd /src/git && \ @@ -72,15 +99,13 @@ RUN cd /src/git && \ cmake --build build --parallel && \ cmake --install build -# install 7z.so with RAR support -RUN echo "Building and installing 7z.so with RAR support..." && \ - cd "/src/git/compressed_archive/lib7zip/CPP/7zip/Bundles/Format7zF" && \ - make -f makefile.gcc && \ - mkdir -p /app/lib/7zip && \ - cp ./_o/7z.so /app/lib/7zip +# Use pre-built 7z.so from sevenzip-builder (provides RAR support) +COPY --from=sevenzip-builder /app/lib/7zip /app/lib/7zip -# Stage 2: Runtime stage -FROM ghcr.io/linuxserver/baseimage-ubuntu:noble +# ============================================================================ +# Stage: runtime +# ============================================================================ +FROM base AS runtime # env variables ENV APPNAME="YACReaderLibraryServer" @@ -88,7 +113,7 @@ ENV HOME="/config" LABEL maintainer="luisangelsm" # Copy the built application from the builder stage -COPY --from=builder /app /app +COPY --from=yacreader-builder /app /app # runtime packages RUN apt-get update && \ @@ -96,8 +121,9 @@ RUN apt-get update && \ libqt6core5compat6 \ libpoppler-qt6-3t64 \ qt6-image-formats-plugins \ - libqt6network6t64 \ - libqt6sql6-sqlite && \ + libqt6network6 \ + libqt6sql6-sqlite \ + kimageformat6-plugins && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* @@ -106,7 +132,7 @@ ENV LC_ALL="en_US.UTF-8" \ PATH="/app/bin:${PATH}" # copy files -COPY root.tar.gz / +COPY docker/root.tar.gz / # Extract the contents of root.tar.gz into the / directory RUN tar -xvpzf /root.tar.gz -C / From 13636420980b92b91cf89babf06367f8c35f8bcb Mon Sep 17 00:00:00 2001 From: Nick Vance Date: Sun, 10 May 2026 23:39:45 -0700 Subject: [PATCH 2/4] fix(docker): Revert COPY root.tar.gz path to match upstream build context Upstream builds with the docker/ directory as the build context, so root.tar.gz is referenced without the docker/ prefix. Co-Authored-By: Claude Sonnet 4.6 --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 3f0e43af2..7d204806a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -132,7 +132,7 @@ ENV LC_ALL="en_US.UTF-8" \ PATH="/app/bin:${PATH}" # copy files -COPY docker/root.tar.gz / +COPY root.tar.gz / # Extract the contents of root.tar.gz into the / directory RUN tar -xvpzf /root.tar.gz -C / From a1e1d562c7be90a705ff24b24d244867b20f5149 Mon Sep 17 00:00:00 2001 From: Nick Vance Date: Mon, 11 May 2026 14:21:00 -0700 Subject: [PATCH 3/4] feat(docker): Apply resolute + kimageformats to Dockerfile.aarch64 Mirror the amd64 changes onto the arm64 image: rebase both stages onto ghcr.io/linuxserver/baseimage-ubuntu:resolute (Ubuntu 26.04), drop the noble-era t64 package suffixes for libqt6gui6/libqt6network6, and add kimageformat6-plugins to the runtime stage for AVIF/JXL. Verified natively on arm64: image builds, server starts on Qt 6.10.2, kimg_avif.so/kimg_jxl.so load, and avif.cbz / jxl.cbz pages render end-to-end through the HTTP API. Co-Authored-By: Claude Opus 4.7 --- docker/Dockerfile.aarch64 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index b3afa44a4..4179f8889 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -1,4 +1,4 @@ -FROM ghcr.io/linuxserver/baseimage-ubuntu:arm64v8-noble AS builder +FROM ghcr.io/linuxserver/baseimage-ubuntu:resolute AS builder # repository URL and version, which can be a tag, branch, or commit SHA ARG YACR_REPOSITORY="https://github.com/YACReader/yacreader.git" @@ -31,9 +31,9 @@ RUN \ qt6-declarative-dev \ libqt6svg6-dev \ libqt6core5compat6-dev \ - libqt6gui6t64 \ + libqt6gui6 \ libqt6multimedia6 \ - libqt6network6t64 \ + libqt6network6 \ libqt6qml6 \ libqt6quickcontrols2-6 \ qt6-image-formats-plugins \ @@ -76,7 +76,7 @@ RUN echo "Building and installing 7z.so with RAR support..." && \ mkdir -p /app/lib/7zip && \ cp ./_o/7z.so /app/lib/7zip -FROM ghcr.io/linuxserver/baseimage-ubuntu:arm64v8-noble +FROM ghcr.io/linuxserver/baseimage-ubuntu:resolute # env variables ENV APPNAME="YACReaderLibraryServer" @@ -92,8 +92,9 @@ RUN apt-get update && \ libqt6core5compat6 \ libpoppler-qt6-3t64 \ qt6-image-formats-plugins \ - libqt6network6t64 \ - libqt6sql6-sqlite && \ + libqt6network6 \ + libqt6sql6-sqlite \ + kimageformat6-plugins && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* From a616dd3006f3b837a9b5834651502ba908fad838 Mon Sep 17 00:00:00 2001 From: Nick Vance Date: Mon, 11 May 2026 14:23:53 -0700 Subject: [PATCH 4/4] refactor(docker): Split 7zip build into its own stage for aarch64 Mirror the amd64 layout: extract the 7z.so build into a dedicated sevenzip-builder stage that fetches the prebuilt source archive, so yacreader-builder no longer reaches into the cloned tree to compile RAR support. The two builder stages now share a 'base' image and run in parallel. After this change docker/Dockerfile and docker/Dockerfile.aarch64 are byte-identical. Verified natively on arm64: 7z.so is present in the final image and avif.cbz / jxl.cbz pages render end-to-end. Co-Authored-By: Claude Opus 4.7 --- docker/Dockerfile.aarch64 | 57 +++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index 4179f8889..7d204806a 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -1,4 +1,34 @@ -FROM ghcr.io/linuxserver/baseimage-ubuntu:resolute AS builder +FROM ghcr.io/linuxserver/baseimage-ubuntu:resolute AS base + +# ============================================================================ +# Stage: sevenzip-builder +# ============================================================================ +FROM base AS sevenzip-builder + +# get 7zip source +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + 7zip \ + build-essential \ + make \ + wget && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN cd /tmp && \ + wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O 7z2301-src.7z && \ + 7z x 7z2301-src.7z -o/tmp/lib7zip + +# install 7z.so with RAR support +RUN cd "/tmp/lib7zip/CPP/7zip/Bundles/Format7zF" && \ + make -f makefile.gcc && \ + mkdir -p /app/lib/7zip && \ + cp ./_o/7z.so /app/lib/7zip + +# ============================================================================ +# Stage: yacreader-builder +# ============================================================================ +FROM base AS yacreader-builder # repository URL and version, which can be a tag, branch, or commit SHA ARG YACR_REPOSITORY="https://github.com/YACReader/yacreader.git" @@ -31,6 +61,9 @@ RUN \ qt6-declarative-dev \ libqt6svg6-dev \ libqt6core5compat6-dev \ + libbz2-dev \ + libglu1-mesa-dev \ + liblzma-dev \ libqt6gui6 \ libqt6multimedia6 \ libqt6network6 \ @@ -39,17 +72,14 @@ RUN \ qt6-image-formats-plugins \ libqt6sql6 \ libqt6sql6-sqlite \ - libpoppler-qt6-dev \ - libsqlite3-dev \ - libbz2-dev \ - libglu1-mesa-dev \ - liblzma-dev \ make \ sqlite3 \ + libsqlite3-dev \ unzip \ wget \ 7zip \ 7zip-rar \ + libpoppler-qt6-dev \ zlib1g-dev && \ ldconfig @@ -69,14 +99,13 @@ RUN cd /src/git && \ cmake --build build --parallel && \ cmake --install build -# install 7z.so with RAR support -RUN echo "Building and installing 7z.so with RAR support..." && \ - cd "/src/git/compressed_archive/lib7zip/CPP/7zip/Bundles/Format7zF" && \ - make -f makefile.gcc && \ - mkdir -p /app/lib/7zip && \ - cp ./_o/7z.so /app/lib/7zip +# Use pre-built 7z.so from sevenzip-builder (provides RAR support) +COPY --from=sevenzip-builder /app/lib/7zip /app/lib/7zip -FROM ghcr.io/linuxserver/baseimage-ubuntu:resolute +# ============================================================================ +# Stage: runtime +# ============================================================================ +FROM base AS runtime # env variables ENV APPNAME="YACReaderLibraryServer" @@ -84,7 +113,7 @@ ENV HOME="/config" LABEL maintainer="luisangelsm" # Copy the built application from the builder stage -COPY --from=builder /app /app +COPY --from=yacreader-builder /app /app # runtime packages RUN apt-get update && \