forked from jumpingmushroom/DiscEcho
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
330 lines (310 loc) · 16.7 KB
/
Copy pathDockerfile
File metadata and controls
330 lines (310 loc) · 16.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# syntax=docker/dockerfile:1.7
###############################################################################
# Stage 1 — build the SvelteKit UI
###############################################################################
FROM node:20-bookworm-slim AS webui-build
WORKDIR /webui
RUN corepack enable && corepack prepare pnpm@9 --activate
COPY webui/package.json webui/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY webui/ ./
RUN pnpm build
###############################################################################
# Stage 2 — build the Go daemon with the UI embedded
###############################################################################
FROM golang:1.25-bookworm AS daemon-build
WORKDIR /src
COPY daemon/go.mod daemon/go.sum ./daemon/
WORKDIR /src/daemon
RUN go mod download
COPY daemon/ ./
# Drop the placeholder UI and replace with the real build from stage 1.
RUN rm -rf embed/webui_build
COPY --from=webui-build /webui/build ./embed/webui_build
ARG VERSION=dev
ARG COMMIT=unknown
ARG BUILD_DATE=unknown
RUN CGO_ENABLED=0 go build \
-trimpath \
-ldflags "-s -w \
-X github.com/jumpingmushroom/DiscEcho/daemon/version.Version=${VERSION} \
-X github.com/jumpingmushroom/DiscEcho/daemon/version.Commit=${COMMIT} \
-X github.com/jumpingmushroom/DiscEcho/daemon/version.BuildDate=${BUILD_DATE}" \
-o /out/discecho ./cmd/discecho
###############################################################################
# Stage 3 — build MakeMKV from source
#
# MakeMKV has no apt package and depends on heavy build-time toolchains
# (qtbase5-dev, libgl1-mesa-dev) that we don't want shipped in the
# runtime image. We compile it in this isolated stage and the runtime
# stage copies only the resulting binary + shared libs.
###############################################################################
# Pulled from jlesage/makemkv rather than built from source. Our previous
# from-source build linked makemkvcon against Debian bookworm's libcrypto3
# / libssl3 / libavcodec59. The resulting binary saved + loaded purchased
# `M-` registration keys correctly (verified byte-perfect on disk) but
# MakeMKV's internal signature verification still rejected them with
# MSG:5021 ("application version is too old"). The same key + same upstream
# version (v1.18.3) worked on the user's desktop, so the divergence was in
# the build/linkage. jlesage/makemkv bundles its own complete library tree
# (including its own dynamic linker at /opt/makemkv/lib/ld-linux-x86-64.so.2)
# matched to MakeMKV's expectations, so we adopt that pre-built bundle
# wholesale.
FROM jlesage/makemkv:latest AS makemkv-build
###############################################################################
# Stage — build HandBrakeCLI from source on Debian bookworm
#
# Debian bookworm's `handbrake-cli` package (1.6.1) is compiled without
# NVENC support. We build HandBrake from source so the resulting binary
# links against bookworm's own libraries (no cross-distro ABI issues)
# and is compiled with --enable-nvenc (on by default for x86_64-linux).
# NVENC requires only the nv-codec-headers at build time; no GPU is
# needed during the build — the runtime driver is dlopen'd at job start.
###############################################################################
FROM debian:bookworm-slim AS handbrake-build
ARG HANDBRAKE_VERSION=1.11.1
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential cmake git nasm ninja-build meson m4 patch pkg-config \
python3 tar curl ca-certificates \
libtool libtool-bin autoconf automake \
libass-dev libbz2-dev libfontconfig-dev libfreetype6-dev \
libfribidi-dev libharfbuzz-dev libjansson-dev liblzma-dev \
libmp3lame-dev libnuma-dev libogg-dev libopus-dev \
libsamplerate0-dev libspeex-dev libtheora-dev \
libturbojpeg0-dev libvorbis-dev libx264-dev libxml2-dev \
libvpx-dev libdvdread-dev libdvdnav-dev libbluray-dev \
libva-dev libdrm-dev \
zlib1g-dev \
&& curl -fsSL "https://github.com/HandBrake/HandBrake/releases/download/${HANDBRAKE_VERSION}/HandBrake-${HANDBRAKE_VERSION}-source.tar.bz2" \
| tar xj -C /tmp \
&& cd "/tmp/HandBrake-${HANDBRAKE_VERSION}" \
&& ./configure --disable-gtk --launch-jobs="$(nproc)" --launch \
&& make --directory=build install \
&& rm -rf /tmp/HandBrake*
###############################################################################
# Stage — build chdman from MAME source
#
# Debian bookworm's mame-tools package ships chdman 0.251, which is missing
# the `createdvd` subcommand (added in MAME 0.252, April 2023). PS2 / Xbox
# rips use createdvd to produce DVD-typed CHD files that emulators expect.
# We build MAME's tools subset here (TOOLS=1 EMULATOR=0 skips the full
# emulator and its Qt deps) and copy out just the chdman binary.
# MAME does not ship source tarballs in its GitHub releases; we shallow-clone
# the tagged commit instead.
###############################################################################
FROM debian:bookworm-slim AS chdman-build
ARG MAME_VERSION=0.275
ARG MAME_TAG=mame0275
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential git python3 ca-certificates \
libsdl2-dev libsdl2-ttf-dev \
libxinerama-dev libxi-dev \
libfontconfig-dev libasound2-dev \
&& rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 --branch "${MAME_TAG}" \
https://github.com/mamedev/mame.git /src/mame
WORKDIR /src/mame
# USE_QTDEBUG=0: on Linux the Genie build system defaults USE_QTDEBUG=1
# which requires Qt5Widgets headers and moc. We have no use for the Qt
# debugger UI in a CHD-tools-only build, so disable it explicitly.
RUN make -j"$(nproc)" TOOLS=1 EMULATOR=0 USE_QTDEBUG=0 IGNORE_GIT=1
RUN strip /src/mame/chdman \
&& /src/mame/chdman --help 2>&1 | head -5
###############################################################################
# Stage — build loudgain from source
#
# loudgain (https://github.com/Moonbase59/loudgain) is the audiophile-grade
# EBU R128 ReplayGain 2.0 tagger DiscEcho uses for the audio-CD post-rip
# pass. It is not packaged in Debian bookworm (apt-cache returns nothing
# in either main or contrib), so we build it from a tagged release here
# and copy only the resulting binary into the runtime image. Runtime
# shared-lib deps (libebur128 + libavformat/swresample/avutil) are
# installed via apt in the runtime stage; this stage adds the matching
# -dev headers + cmake for the build.
###############################################################################
FROM debian:bookworm-slim AS loudgain-build
ARG LOUDGAIN_VERSION=v0.6.8
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential cmake pkg-config git ca-certificates \
libavformat-dev libavutil-dev libswresample-dev \
libebur128-dev libtag1-dev \
&& rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 --branch "${LOUDGAIN_VERSION}" \
https://github.com/Moonbase59/loudgain.git /src/loudgain
# Patch out the av_register_all() call in scan.c. loudgain v0.6.8 wraps
# it in a runtime version-check `if`, but the linker still needs the
# symbol — and FFmpeg 5.x (Debian bookworm) removed it entirely. The
# version-check has been "always false" since lavf 58.9.100 (FFmpeg 4.0,
# 2018), so replacing the call with a no-op is functionally equivalent
# and lets the link succeed against modern libavformat.
RUN sed -i 's/av_register_all();/(void)0;/' /src/loudgain/src/scan.c
WORKDIR /src/loudgain/build
RUN cmake -DCMAKE_BUILD_TYPE=Release .. \
&& make -j"$(nproc)" \
&& ( find . -maxdepth 3 -type f -name 'loudgain' -executable -exec cp {} /usr/local/bin/loudgain \; ) \
&& strip /usr/local/bin/loudgain \
&& /usr/local/bin/loudgain --version
###############################################################################
# Stage — build the PS3 dumper CLI wrapper (.NET)
#
# PS3 game discs are stock-mountable Blu-ray media (the protection is
# per-file content encryption, not a drive-level read lockout the way
# Wii/GameCube's non-standard format is) -- but the decryption itself
# needs a disc key (from Redump's own key database or the community IRD
# library), which is exactly what 13xforever/ps3-disc-dumper does.
# Upstream ships only an Avalonia GUI (UI.Avalonia) with no CLI/console
# project, so daemon/internal/thirdparty/ps3-disc-dumper vendors just
# the two library projects (Ps3DiscDumper + IrdLibraryClient, MIT
# licensed — see that directory's LICENSE) plus a small first-party Cli
# project (Cli/Program.cs) wrapping Dumper's public API into something
# the Go daemon can shell out to and parse stdout from, matching how it
# already drives redumper/HandBrake/MakeMKV. Self-contained publish so
# the runtime image needs no .NET runtime installed on its own behalf.
###############################################################################
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS ps3dumper-build
WORKDIR /src
COPY daemon/internal/thirdparty/ps3-disc-dumper/ ./
RUN dotnet publish Cli/Cli.csproj \
-c Release \
-r linux-x64 \
--self-contained true \
-p:PublishSingleFile=true \
-p:PublishTrimmed=false \
-o /out
###############################################################################
# Stage — build wudecrypt from source
#
# wudecrypt (https://github.com/maki-chan/wudecrypt, AGPL-3.0) decrypts a
# raw Wii U disc dump (.wud) given the platform-wide common key and a
# disc-specific key -- both files supplied by the user at runtime, never
# embedded or fetched by DiscEcho itself (see daemon/pipelines/wiiu's
# package doc). It is installed here as a separate binary and shelled out
# to at runtime, matching how this image already treats HandBrake/
# whipper/ffmpeg (all themselves copyleft-licensed) as external tools
# whose license stays scoped to themselves rather than DiscEcho's own
# MIT source -- see NOTICE.md. Upstream ships only a bakefile
# (wudecrypt.bkl); its handful of plain C files (no deps beyond libc)
# compile directly with gcc. Pinned to a commit SHA since upstream has
# no version tags (pre-alpha project).
###############################################################################
FROM debian:bookworm-slim AS wudecrypt-build
ARG WUDECRYPT_COMMIT=6ee75e13934f2e93b257557ceef172d92934c813
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN git clone https://github.com/maki-chan/wudecrypt.git /src/wudecrypt \
&& cd /src/wudecrypt \
&& git checkout "${WUDECRYPT_COMMIT}"
WORKDIR /src/wudecrypt
RUN gcc -O2 -o wudecrypt aes.c functions.c main.c sha1.c \
&& strip wudecrypt
###############################################################################
# Stage 4 — runtime: python slim + apprise + the daemon binary
###############################################################################
FROM python:3.12-slim-bookworm AS runtime
# whipper is not on PyPI, so install it from Debian apt. cdparanoia +
# libcdio-utils provide the lower-level rippers and cd-info that
# identify/classify use. libdvd-pkg + dvdbackup + genisoimage
# provide DVD ripping (libdvdcss CSS bypass, isoinfo for volume-label
# probe). HandBrakeCLI itself comes from the handbrake-build stage
# below — the Debian package lacks NVENC support. libdvd-pkg lives in
# Debian's `contrib` archive, which the python:slim base doesn't enable
# by default. libbluray-bin ships bd_info (UHD AACS2 detection).
# makemkvcon ships with its own bundled libraries under /opt/makemkv/lib/
# (its own ld-linux + libcrypto3 + libssl3 + libexpat + libavcodec) so
# the runtime image no longer needs to provide them on its behalf.
# libass9 + libturbojpeg0 are HandBrakeCLI runtime deps not pulled in
# transitively by anything else in this image. libsdl2-2.0-0 is the
# sole runtime dep of the chdman binary built from MAME source in the
# chdman-build stage above (chdman links ocore_sdl). mkvtoolnix ships
# mkvmerge (track identify, JSON) + mkvextract, used to pull text-based
# subtitle tracks (S_TEXT/*) out of MakeMKV's ripped .mkv as sidecar
# files -- lossless, no OCR needed, unlike bitmap PGS/VobSub tracks.
RUN echo "deb http://deb.debian.org/debian bookworm main contrib" \
> /etc/apt/sources.list.d/contrib.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates eject udev cdparanoia libcdio-utils whipper \
python3-cdio \
flac \
libdvd-pkg dvdbackup genisoimage \
gddrescue \
vcdimager \
libbluray-bdj libbluray2 libbluray-bin \
libass9 libturbojpeg0 \
libsdl2-2.0-0 \
libebur128-1 libavformat59 libswresample4 libavutil57 libtag1v5 \
mkvtoolnix \
util-linux \
&& DEBIAN_FRONTEND=noninteractive dpkg-reconfigure libdvd-pkg \
&& rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir apprise
# Copy the entire MakeMKV install tree from jlesage's image. The bundle
# at /opt/makemkv/{bin,lib} is self-contained (its own ld-linux,
# libcrypto, libssl, libexpat, libavcodec). Symlink the entry point
# to /usr/bin/makemkvcon so the daemon's exec.Command resolution via
# PATH keeps working unchanged.
COPY --from=makemkv-build /opt/makemkv /opt/makemkv
RUN ln -sf /opt/makemkv/bin/makemkvcon /usr/bin/makemkvcon
# mmgplsrv (MakeMKV's GPL/FFmpeg helper, forked by makemkvcon during a rip)
# is a *musl* binary in jlesage's Alpine bundle (interpreter
# /lib/ld-musl-x86_64.so.1), unlike makemkvcon which is glibc and uses the
# bundled /opt/makemkv/lib loader. Its musl loader + musl-built support libs
# live OUTSIDE /opt/makemkv, so the COPY above doesn't bring them and the
# glibc runtime has no musl loader at all — exec fails with MSG "Failed to
# execute external program 'mmgplsrv'". Pull the three artifacts it needs
# (DT_NEEDED: libc.musl, libstdc++.so.6, libgcc_s.so.1) from the same jlesage
# image. Isolate the support libs under /opt/makemkv/musl via
# /etc/ld-musl-x86_64.path so they can't shadow the glibc libstdc++/libgcc the
# rest of the runtime (HandBrake, loudgain, chdman) uses — Debian usrmerge
# makes /lib == /usr/lib, so a plain copy would collide.
COPY --from=makemkv-build /lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1
COPY --from=makemkv-build /usr/lib/libstdc++.so.6 /usr/lib/libgcc_s.so.1 /opt/makemkv/musl/
RUN ln -sf /lib/ld-musl-x86_64.so.1 /opt/makemkv/musl/libc.musl-x86_64.so.1 \
&& printf '/opt/makemkv/musl\n' > /etc/ld-musl-x86_64.path \
# Guard against future jlesage drift: mmgplsrv must actually launch. An exec
# failure (missing interpreter/lib) yields 127; timeout because it's a server
# that blocks on its control pipe. Any non-127 exit means it loaded fine.
&& sh -c 'timeout 5 /opt/makemkv/bin/mmgplsrv >/dev/null 2>&1; [ "$?" -ne 127 ]'
# HandBrake built from source on Debian bookworm. The binary links
# against the same bookworm shared libs already present in the runtime
# image, so no extra lib COPYs are needed.
COPY --from=handbrake-build /usr/local/bin/HandBrakeCLI /usr/bin/HandBrakeCLI
# chdman built from MAME source (see chdman-build stage). Replaces the
# bookworm mame-tools package (0.251) which predates the createdvd
# subcommand needed for PS2 / Xbox DVD-typed CHDs.
COPY --from=chdman-build /src/mame/chdman /usr/bin/chdman
# loudgain built from source (see loudgain-build stage). Not in Debian.
# Used for audio-CD post-rip ReplayGain 2.0 album-mode tagging.
COPY --from=loudgain-build /usr/local/bin/loudgain /usr/bin/loudgain
# ps3dumper-cli — self-contained single-file publish from the
# ps3dumper-build stage above (vendored + wrapped 13xforever/
# ps3-disc-dumper). No .NET runtime install needed in this image.
COPY --from=ps3dumper-build /out/ps3dumper-cli /usr/local/bin/ps3dumper-cli
RUN chmod +x /usr/local/bin/ps3dumper-cli
# wudecrypt — built from source in the wudecrypt-build stage above.
# AGPL-3.0, external tool, not vendored; see NOTICE.md.
COPY --from=wudecrypt-build /src/wudecrypt/wudecrypt /usr/local/bin/wudecrypt
RUN chmod +x /usr/local/bin/wudecrypt
# redumper — pre-built static Linux binary released on GitHub.
# Pinned via REDUMPER_VERSION build arg.
ARG REDUMPER_VERSION=b720
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl unzip ca-certificates \
&& curl -fsSLo /tmp/redumper.zip \
"https://github.com/superg/redumper/releases/download/${REDUMPER_VERSION}/redumper-${REDUMPER_VERSION}-linux-x64.zip" \
&& unzip /tmp/redumper.zip -d /tmp/redumper \
&& install -m 0755 /tmp/redumper/redumper-${REDUMPER_VERSION}-linux-x64/bin/redumper /usr/local/bin/redumper \
&& apt-get purge -y --auto-remove curl unzip \
&& rm -rf /var/lib/apt/lists/* /tmp/redumper /tmp/redumper.zip
WORKDIR /app
COPY --from=daemon-build /out/discecho /app/discecho
ENV DISCECHO_ADDR=":8088" \
DISCECHO_LIBRARY="/library" \
DISCECHO_DATA="/var/lib/discecho"
EXPOSE 8088
USER root
ENTRYPOINT ["/app/discecho"]