-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContainerfile
More file actions
114 lines (105 loc) · 5.15 KB
/
Copy pathContainerfile
File metadata and controls
114 lines (105 loc) · 5.15 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
# Lyrion Music Server with avahi for ShairTunes2W and the philippe44 bridges.
#
# Upstream image lmscommunity/lyrionmusicserver does not ship avahi or dbus.
# Without them ShairTunes2W (the plugin that publishes squeeze players as
# AirPlay sinks) falls back to its bundled shairport_helper which has a
# broken CLI in 1.9.5 and exits with "Can't start server". RaopBridge,
# CastBridge and UPnPBridge are also unhappy because they want to publish
# or browse mDNS too.
#
# What is added:
# - avahi-daemon + avahi-utils + libnss-mdns (mDNS / Bonjour)
# - dbus (avahi talks D-Bus)
# - ffmpeg, symlinked into LMS bin dir for C-3PO
# - entrypoint wrapper that starts dbus and avahi before LMS
#
# Build:
# podman build -t lyrionmusicserver-avahi:local -f Containerfile .
# docker build -t lyrionmusicserver-avahi:local -f Containerfile .
#
# Run (host networking is required, see README):
# podman run --rm --network=host \
# -v ./config:/config -v ./music:/music:ro \
# lyrionmusicserver-avahi:local
ARG LYRION_VERSION=9.1.1
# nodejs is for yt-dlp. since late 2025 youtube needs a JS runtime to
# decipher signed urls for some formats. without it a growing share of
# videos come back as "Video unavailable" even though they play in the
# browser. yt-dlp 2025.11+ requires node 20 or newer, the debian bookworm
# default nodejs is 18 which yt-dlp rejects with "node-18.x (unsupported)".
# pull node 22 LTS from the official image instead.
#
# 22 is the current LTS line, supported by upstream through april 2027.
# the upstream image is pinned by tag so rebuilds are reproducible. if
# upstream is unreachable the build fails loudly which is what we want,
# silently falling back to debian's old node would put us back where we
# started.
FROM docker.io/library/node:22-bookworm-slim AS node-stage
FROM docker.io/lmscommunity/lyrionmusicserver:${LYRION_VERSION}
# copy the node 22 binary and its runtime over. node:22-bookworm-slim
# ships node statically enough that /usr/local/bin/node plus the include
# dir is all that's needed at runtime. npm/npx are not needed by yt-dlp
# so we don't copy /usr/local/lib/node_modules.
COPY --from=node-stage /usr/local/bin/node /usr/local/bin/node
# the YouTube plugin's default pref points yt-dlp at /usr/bin/node via
# --js-runtimes node:/usr/bin/node. keep that path working by symlinking
# to the new node, otherwise we'd silently fall back to apt's node 18 if
# it ever got installed alongside.
RUN ln -sf /usr/local/bin/node /usr/bin/node
# build-time sanity check. fail loud and early if node didn't land
# correctly, or the major version drifted from what yt-dlp needs.
RUN node --version | grep -E '^v(2[2-9]|[3-9][0-9])\.' \
|| (echo "node major version mismatch: $(node --version)" >&2 && exit 1)
# The upstream image inherits /etc/apt/apt.conf.d/docker-clean. Its
# Post-Invoke rm errors out under buildkit for unclear reasons. Remove it
# for this layer, install, restore is not needed because apt lists are
# wiped at the end anyway.
#
# ffmpeg is for C-3PO. The plugin's EnvironmentHelper calls
# findbin("ffmpeg") which only walks LMS bin dirs, not $PATH, so the
# apt-installed binary has to be symlinked into /lms/Bin/<arch>/ where
# the bundled sox, flac and faad already are. Without that some aac and
# mp4 streams fall back to the perl transcoding path with no audio.
RUN rm -f /etc/apt/apt.conf.d/docker-clean \
&& apt-get update \
&& apt-get install --no-install-recommends -y \
avahi-daemon avahi-utils dbus libnss-mdns \
ffmpeg \
&& rm -rf /var/lib/apt/lists/* \
&& ARCH="$(dpkg --print-architecture)" \
&& case "$ARCH" in \
amd64) LMS_ARCH=x86_64-linux ;; \
arm64) LMS_ARCH=aarch64-linux ;; \
armhf) LMS_ARCH=armhf-linux ;; \
*) LMS_ARCH= ;; \
esac \
&& if [ -n "$LMS_ARCH" ] && [ -d "/lms/Bin/$LMS_ARCH" ]; then \
ln -sf /usr/bin/ffmpeg "/lms/Bin/$LMS_ARCH/ffmpeg"; \
fi
# avahi-daemon defaults.
#
# By default avahi advertises on every interface it can see. Inside a
# container that often includes docker bridges, so the daemon happily
# tells the LAN that the host is reachable on 172.x. With host networking
# this is rarely what you want either, the lo and bridge nics still show
# up. The interface to advertise on is left as a build arg so the image
# stays generic. Set AVAHI_ALLOW_INTERFACES at build time to pin it, or
# leave empty to keep the upstream default (all interfaces).
#
# IPv6 is off by default because most squeeze and AirPlay clients use v4
# only and v6 just adds noise to avahi-browse.
ARG AVAHI_ALLOW_INTERFACES=
RUN sed -i \
-e 's/^#\?use-ipv6=.*/use-ipv6=no/' \
-e 's/^#\?publish-hinfo=.*/publish-hinfo=no/' \
-e 's/^#\?publish-workstation=.*/publish-workstation=no/' \
/etc/avahi/avahi-daemon.conf \
&& if [ -n "$AVAHI_ALLOW_INTERFACES" ]; then \
sed -i \
-e "s/^#\?allow-interfaces=.*/allow-interfaces=${AVAHI_ALLOW_INTERFACES}/" \
/etc/avahi/avahi-daemon.conf; \
fi
# Wrap the upstream entrypoint. Keep the original around for debug.
RUN mv /usr/bin/start-container /usr/bin/start-container.orig
COPY entrypoint.sh /usr/bin/start-container
RUN chmod +x /usr/bin/start-container