Skip to content

Commit ebcdf9b

Browse files
committed
Add Qt image plugins for AVIF, JXL, and HEIC/HEIF support in Docker
- Add multi-stage Docker build with 7 optimized stages - Build and install Qt image plugins: qt-avif-image-plugin, qt-jpegxl-image-plugin, qt-heic-image-plugin - Build libjxl 0.10.2 from source (required version not in Ubuntu noble) - Use system packages for AVIF (libavif16) and HEIC (libheif1) - No YACReader source code changes - uses Qt's dynamic plugin loading - Improves build caching and reduces rebuild times Enables support for modern image formats without code modifications, following YACReader's Qt plugin architecture as suggested in YACReader#498
1 parent 8685290 commit ebcdf9b

1 file changed

Lines changed: 253 additions & 80 deletions

File tree

docker/Dockerfile

Lines changed: 253 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,288 @@
1-
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS builder
1+
# ============================================================================
2+
# Stage 1: 7zip builder
3+
# ============================================================================
4+
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS sevenzip-builder
25

3-
# version, it can be a TAG or a branch
4-
ARG YACR_VERSION="develop"
6+
ARG DEBIAN_FRONTEND="noninteractive"
7+
8+
# Install minimal build packages for 7z compilation
9+
RUN apt-get update && \
10+
apt-get install -y --no-install-recommends \
11+
build-essential \
12+
gcc \
13+
g++ \
14+
make \
15+
unzip \
16+
wget \
17+
7zip && \
18+
apt-get clean && \
19+
rm -rf /var/lib/apt/lists/*
20+
21+
# Download and extract 7z source
22+
RUN mkdir -p /src/7zip && \
23+
cd /src/7zip && \
24+
wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O 7z2301-src.7z && \
25+
7z x 7z2301-src.7z -o/src/7zip/lib7zip && \
26+
rm 7z2301-src.7z
27+
28+
# Build 7z.so with RAR support
29+
RUN cd "/src/7zip/lib7zip/CPP/7zip/Bundles/Format7zF" && \
30+
make -f makefile.gcc -j$(nproc) && \
31+
mkdir -p /app/lib/7zip && \
32+
cp ./_o/7z.so /app/lib/7zip
33+
34+
# ============================================================================
35+
# Stage 2: HEIC/HEIF plugin builder
36+
# ============================================================================
37+
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS heic-plugin-builder
38+
39+
ARG DEBIAN_FRONTEND="noninteractive"
40+
41+
RUN apt-get update && \
42+
apt-get install -y --no-install-recommends \
43+
build-essential \
44+
cmake \
45+
git \
46+
qt6-base-dev \
47+
qt6-base-private-dev \
48+
libheif-dev \
49+
extra-cmake-modules \
50+
pkg-config && \
51+
apt-get clean && \
52+
rm -rf /var/lib/apt/lists/*
53+
54+
WORKDIR /tmp/qt-heic
55+
RUN git clone https://github.com/novomesk/qt-heic-image-plugin.git . && \
56+
mkdir build && cd build && \
57+
cmake .. \
58+
-DCMAKE_BUILD_TYPE=Release \
59+
-DCMAKE_INSTALL_PREFIX=/usr \
60+
-DQT_MAJOR_VERSION=6 && \
61+
make -j$(nproc) && \
62+
make install DESTDIR=/output
63+
64+
# ============================================================================
65+
# Stage 3: libjxl builder (0.10.2 required for JxlEncoderDistanceFromQuality)
66+
# ============================================================================
67+
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS libjxl-builder
68+
69+
ARG DEBIAN_FRONTEND="noninteractive"
70+
71+
RUN apt-get update && \
72+
apt-get install -y --no-install-recommends \
73+
build-essential \
74+
cmake \
75+
git \
76+
pkg-config && \
77+
apt-get clean && \
78+
rm -rf /var/lib/apt/lists/*
79+
80+
WORKDIR /tmp/libjxl
81+
RUN git clone --depth 1 --branch v0.10.2 https://github.com/libjxl/libjxl.git . && \
82+
./deps.sh && \
83+
mkdir build && cd build && \
84+
cmake .. \
85+
-DCMAKE_BUILD_TYPE=Release \
86+
-DBUILD_TESTING=OFF \
87+
-DJPEGXL_ENABLE_BENCHMARK=OFF \
88+
-DJPEGXL_ENABLE_EXAMPLES=OFF \
89+
-DJPEGXL_ENABLE_MANPAGES=OFF \
90+
-DJPEGXL_ENABLE_PLUGINS=OFF \
91+
-DJPEGXL_ENABLE_TOOLS=OFF \
92+
-DCMAKE_INSTALL_PREFIX=/usr && \
93+
make -j$(nproc) && \
94+
make install DESTDIR=/output
95+
96+
# ============================================================================
97+
# Stage 4: JXL plugin builder (depends on libjxl 0.10.2)
98+
# ============================================================================
99+
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS jxl-plugin-builder
100+
101+
ARG DEBIAN_FRONTEND="noninteractive"
102+
103+
RUN apt-get update && \
104+
apt-get install -y --no-install-recommends \
105+
build-essential \
106+
cmake \
107+
git \
108+
qt6-base-dev \
109+
qt6-base-private-dev \
110+
extra-cmake-modules \
111+
pkg-config && \
112+
apt-get clean && \
113+
rm -rf /var/lib/apt/lists/*
114+
115+
# Copy libjxl 0.10.2 from previous stage
116+
COPY --from=libjxl-builder /output/usr /usr
117+
118+
WORKDIR /tmp/qt-jxl
119+
RUN git clone https://github.com/novomesk/qt-jpegxl-image-plugin.git . && \
120+
mkdir build && cd build && \
121+
cmake .. \
122+
-DCMAKE_BUILD_TYPE=Release \
123+
-DCMAKE_INSTALL_PREFIX=/usr \
124+
-DQT_MAJOR_VERSION=6 && \
125+
make -j$(nproc) && \
126+
make install DESTDIR=/output
127+
128+
# ============================================================================
129+
# Stage 5: AVIF plugin builder
130+
# ============================================================================
131+
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS avif-plugin-builder
5132

6-
# env variables
133+
ARG DEBIAN_FRONTEND="noninteractive"
134+
135+
RUN apt-get update && \
136+
apt-get install -y --no-install-recommends \
137+
build-essential \
138+
cmake \
139+
git \
140+
qt6-base-dev \
141+
qt6-base-private-dev \
142+
libavif-dev \
143+
extra-cmake-modules \
144+
pkg-config && \
145+
apt-get clean && \
146+
rm -rf /var/lib/apt/lists/*
147+
148+
WORKDIR /tmp/qt-avif
149+
RUN git clone https://github.com/novomesk/qt-avif-image-plugin.git . && \
150+
mkdir build && cd build && \
151+
cmake .. \
152+
-DCMAKE_BUILD_TYPE=Release \
153+
-DCMAKE_INSTALL_PREFIX=/usr \
154+
-DQT_MAJOR_VERSION=6 && \
155+
make -j$(nproc) && \
156+
make install DESTDIR=/output
157+
158+
# ============================================================================
159+
# Stage 6: YACReader builder
160+
# ============================================================================
161+
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble AS yacreader-builder
162+
163+
ARG YACR_VERSION="develop"
7164
ARG DEBIAN_FRONTEND="noninteractive"
8165
ENV APPNAME="YACReaderLibraryServer"
9166
ENV HOME="/config"
10167
LABEL maintainer="luisangelsm"
11168

12-
# install build packages
13-
RUN \
14-
apt-get update && \
169+
# Install build packages
170+
RUN apt-get update && \
15171
apt-get install -y --no-install-recommends \
16-
build-essential \
17-
desktop-file-utils \
18-
gcc \
19-
g++ \
20-
git \
21-
qt6-tools-dev \
22-
qt6-base-dev-tools \
23-
qmake6 \
24-
qmake6-bin \
25-
qt6-base-dev \
26-
qt6-multimedia-dev \
27-
qt6-tools-dev-tools \
28-
libgl-dev \
29-
qt6-l10n-tools \
30-
libqt6opengl6-dev \
31-
libunarr-dev \
32-
qt6-declarative-dev \
33-
libqt6svg6-dev \
34-
libqt6core5compat6-dev \
35-
libbz2-dev \
36-
libglu1-mesa-dev \
37-
liblzma-dev \
38-
libqt6gui6 \
39-
libqt6multimedia6 \
40-
libqt6network6 \
41-
libqt6qml6 \
42-
libqt6quickcontrols2-6 \
43-
qt6-image-formats-plugins \
44-
libqt6sql6 \
45-
libqt6sql6-sqlite \
46-
make \
47-
sqlite3 \
48-
libsqlite3-dev \
49-
unzip \
50-
wget \
51-
7zip \
52-
7zip-rar \
53-
libpoppler-qt6-dev \
54-
zlib1g-dev && \
172+
build-essential \
173+
desktop-file-utils \
174+
gcc \
175+
g++ \
176+
git \
177+
cmake \
178+
qt6-tools-dev \
179+
qt6-base-dev-tools \
180+
qmake6 \
181+
qmake6-bin \
182+
qt6-base-dev \
183+
qt6-multimedia-dev \
184+
qt6-tools-dev-tools \
185+
libgl-dev \
186+
qt6-l10n-tools \
187+
libqt6opengl6-dev \
188+
libunarr-dev \
189+
qt6-declarative-dev \
190+
libqt6svg6-dev \
191+
libqt6core5compat6-dev \
192+
libbz2-dev \
193+
libglu1-mesa-dev \
194+
liblzma-dev \
195+
libqt6gui6 \
196+
libqt6multimedia6 \
197+
libqt6network6 \
198+
libqt6qml6 \
199+
libqt6quickcontrols2-6 \
200+
qt6-image-formats-plugins \
201+
libqt6sql6 \
202+
libqt6sql6-sqlite \
203+
make \
204+
sqlite3 \
205+
libsqlite3-dev \
206+
unzip \
207+
wget \
208+
libavif-dev \
209+
7zip \
210+
7zip-rar \
211+
libpoppler-qt6-dev \
212+
zlib1g-dev && \
213+
apt-get clean && \
214+
rm -rf /var/lib/apt/lists/* && \
55215
ldconfig
56216

57-
58-
# clone YACReader repo
217+
# Clone YACReader repository
59218
RUN git clone https://github.com/YACReader/yacreader.git /src/git && \
60219
cd /src/git && \
61220
git checkout $YACR_VERSION
62221

63-
# get 7zip source
64-
RUN cd /src/git/compressed_archive && \
65-
wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O /src/git/compressed_archive/7z2301-src.7z && \
66-
7z x /src/git/compressed_archive/7z2301-src.7z -o/src/git/compressed_archive/lib7zip
222+
# Copy pre-built 7z library and headers
223+
COPY --from=sevenzip-builder /src/7zip/lib7zip /src/git/compressed_archive/lib7zip
224+
COPY --from=sevenzip-builder /app/lib/7zip /app/lib/7zip
225+
226+
# Copy Qt image format plugins from separate stages
227+
COPY --from=avif-plugin-builder /output/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/ \
228+
/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/
229+
COPY --from=jxl-plugin-builder /output/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/ \
230+
/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/
231+
COPY --from=heic-plugin-builder /output/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/ \
232+
/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/
67233

68-
# build yacreaderlibraryserver
234+
# Build YACReaderLibraryServer
69235
RUN cd /src/git/YACReaderLibraryServer && \
70236
qmake6 PREFIX=/app CONFIG+="7zip server_standalone" YACReaderLibraryServer.pro && \
71237
qmake6 -v && \
72-
make && \
238+
make -j$(nproc) && \
73239
make install
74240

75-
# install 7z.so with RAR support
76-
RUN echo "Building and installing 7z.so with RAR support..." && \
77-
cd "/src/git/compressed_archive/lib7zip/CPP/7zip/Bundles/Format7zF" && \
78-
make -f makefile.gcc && \
79-
mkdir -p /app/lib/7zip && \
80-
cp ./_o/7z.so /app/lib/7zip
81-
82-
# Stage 2: Runtime stage
241+
# ============================================================================
242+
# Stage 7: Final runtime image (minimal, no build assets)
243+
# ============================================================================
83244
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble
84245

85-
# env variables
86246
ENV APPNAME="YACReaderLibraryServer"
87247
ENV HOME="/config"
248+
ENV LC_ALL="en_US.UTF-8"
249+
ENV PATH="/app/bin:${PATH}"
88250
LABEL maintainer="luisangelsm"
89251

90-
# Copy the built application from the builder stage
91-
COPY --from=builder /app /app
92-
93-
# runtime packages
252+
# Install only runtime dependencies (no build tools)
94253
RUN apt-get update && \
95254
apt-get install -y --no-install-recommends \
96-
libqt6core5compat6 \
97-
libpoppler-qt6-3t64 \
98-
qt6-image-formats-plugins \
99-
libqt6network6t64 \
100-
libqt6sql6-sqlite && \
255+
libqt6core5compat6 \
256+
libpoppler-qt6-3t64 \
257+
qt6-image-formats-plugins \
258+
libqt6network6t64 \
259+
libqt6sql6-sqlite \
260+
libavif16 \
261+
libheif1 && \
101262
apt-get clean && \
102263
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
103264

104-
# set ENV
105-
ENV LC_ALL="en_US.UTF-8" \
106-
PATH="/app/bin:${PATH}"
265+
# Copy YACReaderLibraryServer application from builder
266+
COPY --from=yacreader-builder /app /app
267+
268+
# Copy Qt image format plugins from plugin builders
269+
COPY --from=avif-plugin-builder /output/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/ \
270+
/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/
271+
COPY --from=jxl-plugin-builder /output/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/ \
272+
/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/
273+
COPY --from=heic-plugin-builder /output/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/ \
274+
/usr/lib/x86_64-linux-gnu/qt6/plugins/imageformats/
275+
276+
# Copy libjxl 0.10.2 runtime libraries (not available in Ubuntu noble)
277+
COPY --from=libjxl-builder /output/usr/lib/ /usr/lib/
278+
279+
# Refresh dynamic linker cache
280+
RUN ldconfig
107281

108-
# copy files
109-
COPY root.tar.gz /
110-
# Extract the contents of root.tar.gz into the / directory
111-
RUN tar -xvpzf /root.tar.gz -C /
282+
# Copy linuxserver.io configuration
283+
COPY docker/root.tar.gz /
284+
RUN tar -xvpzf /root.tar.gz -C / && rm /root.tar.gz
112285

113-
# ports and volumes
286+
# Expose server port and define volumes
114287
EXPOSE 8080
115288
VOLUME ["/config", "/comics"]

0 commit comments

Comments
 (0)