Files
lms/Dockerfile-release
T
owen 6d0f8fcc5a Fix fresh-install schema gap and OIDC provider CA trust
- Session::prepareTablesIfNeeded(): Wt::Dbo's automatic createTables()
  silently fails to create 4 tables (share, starred_artist,
  starred_release, starred_track) on a genuinely fresh database, with
  no exception raised and no clear reason found in Wt::Dbo internals.
  These tables are otherwise only ever created via historical schema
  migrations, which never run for a fresh install (new DBs are stamped
  directly at LMS_DATABASE_VERSION). Reproduced consistently across
  multiple from-scratch database attempts. Added defensive
  CREATE TABLE IF NOT EXISTS statements for all 4 right after
  createTables() as a targeted workaround; harmless no-op on databases
  where they already exist correctly.

- Dockerfile-release / docker-entrypoint.sh: the OIDC token exchange
  (OAuthProcess::handleToken(), a server-to-server HTTPS call from LMS
  to the provider's token endpoint) has no way to trust a private/
  internal CA, so any OIDC provider behind non-publicly-trusted TLS
  fails with 'certificate verify failed' immediately after the user
  authenticates - the callback silently drops back to the login page
  with no user-visible error, and no account ever gets created (the
  auto-registration logic in OIDCAuth::OIDCAuth was already correct;
  it just never got a chance to run). Added ca-certificates + su-exec
  to the runtime image and a docker-entrypoint.sh that runs
  update-ca-certificates against anything mounted into
  /usr/local/share/ca-certificates before dropping privileges and
  exec'ing lms, so operators can trust a custom CA via a volume mount.
2026-08-20 01:00:37 -05:00

209 lines
5.8 KiB
Plaintext

FROM alpine:3.24 AS build
WORKDIR /tmp/workdir
ENV PREFIX="/tmp/install"
ARG BUILD_PACKAGES=" \
autoconf \
automake \
boost-dev \
bzip2 \
ca-certificates \
cmake \
coreutils \
curl \
g++ \
gtest-dev \
lame-dev \
libarchive-dev \
libconfig-dev \
libogg-dev \
libpng-dev \
libtool \
libvorbis-dev \
libwebp-dev \
make \
onnxruntime-dev \
openjpeg-dev \
openssl-dev \
opus-dev \
pkgconfig \
pugixml-dev \
pulseaudio-dev \
nasm \
sqlite-dev \
utfcpp \
xxhash-dev \
yasm \
zlib-dev"
RUN apk add --no-cache --update ${BUILD_PACKAGES}
# FFmpeg
ARG FFMPEG_VERSION=6.1.5
RUN \
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
curl -sLO https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \
tar -jx --strip-components=1 -f ffmpeg-${FFMPEG_VERSION}.tar.bz2
RUN \
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
./configure \
--prefix=${PREFIX} \
--disable-autodetect \
--disable-debug \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-openssl \
--disable-postproc \
--disable-pixelutils \
--disable-network \
--enable-shared \
--disable-static \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-libmp3lame \
--enable-libopenjpeg \
--enable-libopus \
--enable-libvorbis \
--enable-zlib \
--disable-everything \
--enable-decoder=aac*,ac3*,alac,als,ape,asf,dsd*,flac,libopus,pcm*,libvorbis,mp3*,mpc7,mpc8,shorten,tta,wavpack,wma*,libopenjpg,png \
--enable-encoder=flac,libmp3lame,libopus,libvorbis \
--enable-demuxer=aac,aiff,ape,asf,dsf,flac,m4a,mp3,mov,mpc,mpc8,ogg,shn,tta,wav,wv \
--enable-muxer=flac,mp3,ogg \
--enable-protocol=file,pipe \
--enable-filter=aresample \
--enable-lto \
--extra-libs=-ldl && \
make -j$(nproc) install
# WT
ARG WT_VERSION=4.13.3
ARG WT_DEBUG=OFF
RUN \
DIR=/tmp/wt && mkdir -p ${DIR} && cd ${DIR} && \
curl -sLO https://github.com/emweb/wt/archive/${WT_VERSION}.tar.gz && \
tar -x --strip-components=1 -f ${WT_VERSION}.tar.gz
RUN \
DIR=/tmp/wt && mkdir -p ${DIR} && cd ${DIR} && \
cmake -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DCMAKE_CXX_STANDARD=20 -DSHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} -DWT_CPP20_DATE_TZ_IMPLEMENTATION="std" -DWT_CPP17_FILESYSTEM_IMPLEMENTATION="std" -DWT_CPP17_ANY_IMPLEMENTATION="std" -DBUILD_EXAMPLES=OFF -DENABLE_LIBWTTEST=OFF -DCONNECTOR_FCGI=OFF -DUSE_SYSTEM_SQLITE3=ON -DDEBUG=${WT_DEBUG} && \
make -j$(nproc) install
# STB
ARG STB_VERSION=31c1ad37456438565541f4919958214b6e762fb4
RUN \
DIR=/tmp/stb && mkdir -p ${DIR} && cd ${DIR} && \
curl -sLO https://github.com/nothings/stb/archive/${STB_VERSION}.tar.gz && \
tar -x --strip-components=1 -f ${STB_VERSION}.tar.gz && \
mkdir -p ${PREFIX}/include/stb && \
cp ./*.h ${PREFIX}/include/stb
# TAGLIB
ARG TAGLIB_VERSION=v2.3
RUN \
DIR=/tmp/taglib && mkdir -p ${DIR} && cd ${DIR} && \
curl -sLO https://github.com/taglib/taglib/archive/${TAGLIB_VERSION}.tar.gz && \
tar -x --strip-components=1 -f ${TAGLIB_VERSION}.tar.gz
RUN \
DIR=/tmp/taglib && mkdir -p ${DIR} && cd ${DIR} && \
CXXFLAGS="-I/usr/include/utf8cpp" cmake -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} -DBUILD_SHARED_LIBS=ON -DBUILD_EXAMPLES=OFF -DBUILD_BINDINGS=OFF -DBUILD_TESTING=OFF -DTRACE_IN_RELEASE=OFF -DWITH_ZLIB=ON && \
make -j$(nproc) install
# LMS
COPY . /tmp/lms/
RUN \
DIR=/tmp/lms/build && mkdir -p ${DIR} && cd ${DIR} && \
PKG_CONFIG_PATH=/tmp/install/lib/pkgconfig CXXFLAGS="-I${PREFIX}/include" LDFLAGS="-L${PREFIX}/lib -Wl,--rpath-link=${PREFIX}/lib" cmake /tmp/lms/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DCMAKE_UNITY_BUILD=ON -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} && \
LD_LIBRARY_PATH=${PREFIX}/lib make -j$(nproc) install && \
LD_LIBRARY_PATH=${PREFIX}/lib LMS_MUSICNN_MODEL=/tmp/lms/src/libs/audio/models/MSD_musicnn_embedding.onnx make test && \
mkdir -p ${PREFIX}/etc/ && \
cp /tmp/lms/conf/lms.conf ${PREFIX}/etc
# Now copy all the stuff installed in a new folder (/tmp/fakeroot/)
RUN \
mkdir -p /tmp/fakeroot/bin && \
for bin in ${PREFIX}/bin/ffmpeg ${PREFIX}/bin/lms*; \
do \
strip --strip-all $bin && \
cp $bin /tmp/fakeroot/bin/; \
done && \
for lib in ${PREFIX}/lib/*.so; \
do \
strip --strip-all $lib; \
done && \
cp -r ${PREFIX}/lib /tmp/fakeroot/lib && \
cp -r ${PREFIX}/share /tmp/fakeroot/share && \
rm -rf /tmp/fakeroot/share/doc && \
rm -rf /tmp/fakeroot/share/man
# Remove useless stuff
RUN \
rm -rf /tmp/fakeroot/share/Wt/resources/jPlayer \
rm -rf /tmp/fakeroot/share/Wt/resources/themes
## Release Stage
FROM alpine:3.24 AS release
LABEL maintainer="Emeric Poupon <itmfr@yahoo.fr>"
ARG RUNTIME_PACKAGES=" \
boost-iostreams \
boost-program_options \
boost-thread \
ca-certificates \
lame-libs \
libarchive \
libconfig++ \
libcrypto3 \
libogg \
libpng \
libpulse \
libvorbis \
libwebp \
libssl3 \
onnxruntime \
openjpeg \
opus \
pugixml \
sqlite-libs \
su-exec \
zlib"
ARG LMS_USER=lms
ARG LMS_GROUP=lms
# Install packages and remove useless stuff brought by onnxruntime
RUN \
apk add --no-cache --update ${RUNTIME_PACKAGES} && \
rm -f \
/usr/bin/protoc* \
/usr/bin/onnx* \
/usr/lib/libprotoc*
RUN addgroup -S ${LMS_GROUP} && \
adduser -S -H ${LMS_USER} && \
adduser ${LMS_USER} ${LMS_GROUP} && \
mkdir -p /var/lms && chown -R ${LMS_USER}:${LMS_GROUP} /var/lms
VOLUME /var/lms
VOLUME /music
VOLUME /usr/local/etc
VOLUME /usr/local/share/ca-certificates
COPY --from=build /tmp/fakeroot/ /usr
COPY --from=build /tmp/fakeroot/share/lms/lms.conf /etc/lms.conf
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
EXPOSE 5082
# Stays root so the entrypoint can run update-ca-certificates; it drops to
# ${LMS_USER}:${LMS_GROUP} via su-exec before running lms itself.
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["/usr/bin/lms"]