Repository navigation
Expand file tree
/
Copy pathDockerfile.debug
More file actions
326 lines (306 loc) · 14.6 KB
/
Copy pathDockerfile.debug
File metadata and controls
326 lines (306 loc) · 14.6 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
# syntax=docker/dockerfile:1
# Debug Dockerfile: builds with debug symbols and includes GDB in the final image.
# Usage:
# docker buildx build -f Dockerfile.debug -t mumble-server:debug \
# --build-context mumble-src=<path-to-repo> .
#
# Then run interactively:
# docker run -it --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
# mumble-server:debug
FROM ubuntu:24.04 AS base
ARG DEBIAN_FRONTEND=noninteractive
RUN sed -i 's|http://security.ubuntu.com|http://archive.ubuntu.com|g' /etc/apt/sources.list.d/ubuntu.sources \
&& apt-get -o Acquire::Check-Date=false update && apt-get install --no-install-recommends -y \
ca-certificates \
gdb \
libavahi-compat-libdnssd1 \
libcap2 \
libqt6core6t64 \
libqt6dbus6t64 \
libqt6gui6t64 \
libqt6network6t64 \
libqt6sql6t64 \
libqt6sql6-sqlite \
libqt6xml6t64 \
libzeroc-ice3.7t64 \
'^libprotobuf[0-9]+t?64?$' \
libsqlite3-0 \
'^libmysqlclient[0-9]+$' \
libpq5 \
'^libpocofoundation[0-9]+t?64?$' \
'^libpocodata[0-9]+t?64?$' \
'^libpocojson[0-9]+t?64?$' \
'^libpocoxml[0-9]+t?64?$' \
'^libpoconet[0-9]+t?64?$' \
'^libpoconetssl[0-9]+t?64?$' \
'^libpococrypto[0-9]+t?64?$' \
'^libpocojwt[0-9]+t?64?$' \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Build the Rust WebRTC SFU shared library in its own stage.
FROM ubuntu:24.04 AS sfu-build
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install --no-install-recommends -y \
curl ca-certificates build-essential pkg-config libssl-dev \
&& rm -rf /var/lib/apt/lists/*
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
ENV PATH="/root/.cargo/bin:${PATH}"
COPY --from=mumble-src 3rdparty/webrtc-sfu /sfu
WORKDIR /sfu
# Persist the cargo registry/git caches and the target dir across builds so
# only changed crates recompile. Artefacts are copied out of the (ephemeral)
# target cache mount into /sfu/out so the later COPY --from can read them.
RUN --mount=type=cache,target=/root/.cargo/registry,id=sfu-cargo-registry \
--mount=type=cache,target=/root/.cargo/git,id=sfu-cargo-git \
--mount=type=cache,target=/sfu/target,id=sfu-target \
cargo build --release \
&& mkdir -p /sfu/out \
&& cp target/release/libwebrtc_sfu.so /sfu/out/ \
&& strip /sfu/out/libwebrtc_sfu.so
# Build the Rust mumble-plugin-host cdylib in its own stage. This produces
# libmumble_plugin_host.so plus the cbindgen-generated C header consumed by
# the C++ server build.
FROM ubuntu:24.04 AS plugin-host-build
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install --no-install-recommends -y \
curl ca-certificates build-essential pkg-config libssl-dev patchelf \
&& rm -rf /var/lib/apt/lists/*
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
ENV PATH="/root/.cargo/bin:${PATH}"
# Node.js 22 LTS (NodeSource): Ubuntu 24.04 ships Node 18, which is too old for
# the file-server web frontend's Vite build.
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install --no-install-recommends -y nodejs \
&& rm -rf /var/lib/apt/lists/*
COPY --from=mumble-src 3rdparty/mumble-plugin-host /plugin-host
WORKDIR /plugin-host
# Build the embedded file-server web pages (React + MUI -> file-server/web/dist/
# password.html, embedded by the crate via include_str!) before the Rust build.
# MUMBLE_FILESERVER_SKIP_WEB_BUILD then tells the crate's build.rs to reuse this
# artifact instead of invoking npm a second time.
RUN --mount=type=cache,target=/root/.npm,id=plugin-host-npm \
npm --prefix file-server/web ci \
&& npm --prefix file-server/web run build
ENV MUMBLE_FILESERVER_SKIP_WEB_BUILD=1
RUN --mount=type=cache,target=/root/.cargo/registry,id=plugin-host-cargo-registry \
--mount=type=cache,target=/root/.cargo/git,id=plugin-host-cargo-git \
--mount=type=cache,target=/plugin-host/target,id=plugin-host-target \
cargo build --release \
-p mumble-plugin-host \
-p mumble-file-server \
-p mumble-live-doc \
-p mumble-link-preview \
&& mkdir -p /plugin-host/out /plugin-host/plugins \
&& cp target/release/libmumble_plugin_host.so /plugin-host/out/ \
&& patchelf --set-soname libmumble_plugin_host.so /plugin-host/out/libmumble_plugin_host.so \
&& cp target/release/libmumble_file_server.so /plugin-host/plugins/ \
&& cp target/release/libmumble_live_doc.so /plugin-host/plugins/ \
&& cp target/release/libmumble_link_preview.so /plugin-host/plugins/
# ------------------------------------------------------------------
# Build the local fancy-plugin-example workspace (4 example plugin
# cdylibs) from a named build context.
#
# Requires `--build-context fancy-plugins-src=<path>` to point at the
# repo root of the fancy-plugin-example checkout. The workspace's
# Cargo.toml path-deps assume a sibling `mumble-server/` directory, so
# we stage the mumble-plugin-host subtree of the local mumble-server
# checkout (`--from=mumble-src`) at the expected sibling location
# inside the builder.
# ------------------------------------------------------------------
FROM ubuntu:24.04 AS fancy-plugins-build
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install --no-install-recommends -y \
curl ca-certificates build-essential pkg-config libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# Node.js 20 LTS via NodeSource: ubuntu 24.04 ships v18 which is too old for
# @bytecodealliance/jco + componentize-js (oxc-parser requires node >= 20).
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install --no-install-recommends -y nodejs \
&& rm -rf /var/lib/apt/lists/*
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
ENV PATH="/root/.cargo/bin:${PATH}"
# wasm-tools is needed to wrap the greeter-wasm core module as a component.
# Installed before the source COPY so this layer is cached independently of
# source changes.
RUN cargo install wasm-tools
# Python + componentize-py for the quiz-py example (pure no-WASI component via
# --stub-wasi). Ubuntu 24.04 is PEP-668 "externally managed", so install the
# build tool with --break-system-packages.
RUN apt-get update && apt-get install --no-install-recommends -y \
python3 python3-pip \
&& rm -rf /var/lib/apt/lists/* \
&& pip3 install --break-system-packages componentize-py
# Go + TinyGo + Binaryen (wasm-opt) for the lights-out-go example. TinyGo emits
# a wasip2 component; Binaryen's wasm-opt is required by the TinyGo build.
ARG GO_VERSION=1.23.6
RUN curl -fsSL https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz | tar -C /usr/local -xz
ENV PATH="/usr/local/go/bin:${PATH}"
ARG TINYGO_VERSION=0.41.1
RUN apt-get update && apt-get install --no-install-recommends -y binaryen \
&& rm -rf /var/lib/apt/lists/* \
&& curl -fsSL -o /tmp/tinygo.deb \
https://github.com/tinygo-org/tinygo/releases/download/v${TINYGO_VERSION}/tinygo_${TINYGO_VERSION}_amd64.deb \
&& dpkg -i /tmp/tinygo.deb \
&& rm /tmp/tinygo.deb
# Sibling layout: fancy-plugin-example/Cargo.toml declares
# mumble-plugin-api = { path = "../mumble-server/3rdparty/mumble-plugin-host/api" }
# so from /fancy-plugin-example, `..` must resolve to a directory that
# contains `mumble-server/3rdparty/mumble-plugin-host/`.
COPY --from=mumble-src 3rdparty/mumble-plugin-host /mumble-server/3rdparty/mumble-plugin-host
COPY --from=fancy-plugins-src . /fancy-plugin-example
WORKDIR /fancy-plugin-example
# Native cdylib plugins.
RUN --mount=type=cache,target=/root/.cargo/registry,id=fancy-cargo-registry \
--mount=type=cache,target=/root/.cargo/git,id=fancy-cargo-git \
--mount=type=cache,target=/fancy-plugin-example/target,id=fancy-target \
cargo build --release --workspace \
&& mkdir -p /fancy-plugins \
&& cp target/release/libfancy_greeter.so \
target/release/libfancy_gallery_showcase.so \
target/release/libfancy_info_card.so \
target/release/libfancy_feedback_form.so \
target/release/libfancy_quick_poll.so \
target/release/libfancy_chat_card.so \
/fancy-plugins/
# greeter-wasm: Rust WASM component plugin built for wasm32-unknown-unknown,
# then wrapped as a component by wasm-tools.
# `rustup target add` is done here (not in a pre-COPY layer) so the target is
# always added to the current active toolchain immediately before the build.
RUN --mount=type=cache,target=/root/.cargo/registry,id=fancy-cargo-registry \
--mount=type=cache,target=/root/.cargo/git,id=fancy-cargo-git \
--mount=type=cache,target=/fancy-plugin-example/target,id=fancy-target \
rustup target add wasm32-unknown-unknown \
&& cargo build --release -p fancy-greeter-wasm --target wasm32-unknown-unknown \
&& wasm-tools component new \
target/wasm32-unknown-unknown/release/fancy_greeter_wasm.wasm \
-o /fancy-plugins/greeter-wasm.wasm
# tic-tac-toe-js: JavaScript WASM component plugin built with jco componentize.
# The --wit path in package.json resolves relative to the examples/ subdir back
# to /mumble-server/3rdparty/mumble-plugin-host/wit (already staged above).
RUN --mount=type=cache,target=/root/.npm,id=fancy-npm \
cd examples/tic-tac-toe-js \
&& npm install \
&& npm run build \
&& cp tic-tac-toe.wasm /fancy-plugins/
# quiz-py: Python WASM component plugin built with componentize-py. build.py
# resolves the WIT dir relative to the example (../../../mumble-server/... staged
# above) and emits a pure component via --stub-wasi.
RUN cd examples/quiz-py \
&& python3 build.py \
&& cp quiz.wasm /fancy-plugins/
# lights-out-go: Go WASM component plugin built with TinyGo (wasip2). build.py
# assembles a combined WIT package (mumble interfaces + TinyGo's wasi-cli deps)
# and runs the TinyGo build; the committed Go bindings live under libraries/go.
RUN --mount=type=cache,target=/root/.cache/go-build,id=fancy-go-build \
--mount=type=cache,target=/root/go/pkg/mod,id=fancy-go-mod \
cd examples/lights-out-go \
&& python3 build.py \
&& cp lights-out.wasm /fancy-plugins/
FROM base AS build
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get -o Acquire::Check-Date=false update && apt-get install --no-install-recommends -y \
build-essential \
ca-certificates \
ccache \
cmake \
curl \
ninja-build \
gdb \
git \
libavahi-compat-libdnssd-dev \
libboost-dev \
libcap-dev \
libprotoc-dev \
libprotobuf-dev \
libssl-dev \
libxi-dev \
libzeroc-ice-dev \
libsqlite3-dev \
libmysqlclient-dev \
libpq-dev \
libpoco-dev \
pkg-config \
protobuf-compiler \
python3 \
qt6-base-dev \
qt6-tools-dev \
qt6-tools-dev-tools \
qt6-svg-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
COPY --from=mumble-src . /mumble/repo
WORKDIR /mumble/repo
# Update submodules only when the source is a usable standalone git repo. When
# MUMBLE_SRC is itself a git *submodule* checkout (e.g. the e2e harness'
# vendor/server), its .git is a dangling gitdir pointer and the submodules are
# already vendored in the copied tree, so an in-container update would fail with
# "not a git repository". In that case we rely on the vendored submodules.
RUN if git rev-parse --git-dir >/dev/null 2>&1; then \
git submodule update --init && git submodule update --depth 1; \
else \
echo "Skipping submodule update: source is not a standalone git repo; using vendored submodules."; \
fi
# Drop the prebuilt mumble-plugin-host artefacts where CMake expects them so
# the C++ link step can resolve the cdylib symbols.
COPY --from=plugin-host-build /plugin-host/out/libmumble_plugin_host.so \
/mumble/repo/3rdparty/mumble-plugin-host/lib/libmumble_plugin_host.so
COPY --from=plugin-host-build /plugin-host/host/include/mumble_plugin_host.h \
/mumble/repo/3rdparty/mumble-plugin-host/include/mumble_plugin_host.h
# Build with RelWithDebInfo for debug symbols + optimizations.
RUN --mount=type=cache,target=/root/.ccache,id=mumble-ccache-debug \
--mount=type=cache,target=/mumble/repo/build-debug,id=mumble-cmake-build-debug \
cd /mumble/repo && \
mkdir -p build-debug && cd build-debug && \
cmake -G Ninja \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DBUILD_NUMBER=0 \
-Dclient=OFF \
-Dserver=ON \
-Dice=ON \
-Dtests=ON \
-Dwarnings-as-errors=ON \
-Dzeroconf=OFF \
-Dwebrtc-sfu=OFF \
-DCMAKE_UNITY_BUILD=ON \
.. && \
cmake --build . -j $(nproc) && \
cp /mumble/repo/build-debug/mumble-server /mumble/mumble-server && \
(cp /mumble/repo/build-debug/src/murmur/fcm/libmumble_push_fcm.so /mumble/ 2>/dev/null || true)
RUN cp -f /mumble/repo/auxiliary_files/mumble-server.ini /mumble/default_config.ini 2>/dev/null \
|| cp -f /mumble/repo/scripts/murmur.ini /mumble/default_config.ini
FROM base
ARG MUMBLE_UID=1000
ARG MUMBLE_GID=1000
RUN getent group $MUMBLE_GID && groupdel $(getent group $MUMBLE_GID | cut -d: -f1) || true \
&& getent passwd $MUMBLE_UID && userdel $(getent passwd $MUMBLE_UID | cut -d: -f1) || true \
&& groupadd --gid $MUMBLE_GID mumble \
&& useradd --uid $MUMBLE_UID --gid $MUMBLE_GID mumble
# Do NOT strip - keep debug symbols in the binary.
COPY --from=build /mumble/mumble-server /usr/bin/mumble-server
# FCM push module is optional - only copied if built.
COPY --from=build /mumble/libmumble_push_fcm.so* /usr/bin/
# WebRTC SFU Rust module - built in the sfu-build stage.
COPY --from=sfu-build /sfu/out/libwebrtc_sfu.so /usr/bin/
# Mumble plugin host Rust cdylib - built in the plugin-host-build stage.
# Installed under the multiarch lib dir so the dynamic linker finds it via DT_NEEDED.
COPY --from=plugin-host-build /plugin-host/out/libmumble_plugin_host.so \
/usr/lib/x86_64-linux-gnu/libmumble_plugin_host.so
# Built-in dynamic plugins (file-server, live-doc) - loaded at runtime via
# MUMBLE_PLUGIN_DIRS. Operators may drop additional plugins into the mounted
# /etc/mumble/plugins directory.
COPY --from=plugin-host-build /plugin-host/plugins/ /usr/lib/mumble-server/plugins/
# Locally-built fancy-plugin-example cdylibs (greeter, gallery-showcase,
# info-card, feedback-form, quick-poll, chat-card). Kept unstripped to
# preserve debug symbols.
COPY --from=fancy-plugins-build /fancy-plugins/ /usr/lib/mumble-server/plugins/
COPY --from=build /mumble/default_config.ini /etc/mumble/bare_config.ini
RUN mkdir -p /data /etc/mumble/plugins \
&& chown -R mumble:mumble /data \
&& chown -R mumble:mumble /etc/mumble
ENV MUMBLE_PLUGIN_DIRS="/usr/lib/mumble-server/plugins:/etc/mumble/plugins"
EXPOSE 64738/tcp 64738/udp 64739/tcp 10000/udp
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/mumble-server", "-fg", "-v", "--ini", "/data/mumble_server_config.ini"]