125 lines
4.9 KiB
Docker
125 lines
4.9 KiB
Docker
# syntax=docker/dockerfile:1
|
|
#
|
|
# Custom guacd image built against FreeRDP 3.8.0+ on Ubuntu 24.04.
|
|
#
|
|
# Why FreeRDP from source: Ubuntu 24.04 ships freerdp3-dev 3.5.1.
|
|
# guacamole-server git main (1.7-dev) targets FreeRDP 3.8.0+:
|
|
# - gdi.c's GUAC_ASSERT(current_context == NULL) is gated #if MINOR < 8
|
|
# so with 3.5.x it fires when GFX calls begin_paint before desktop_resize
|
|
# - gdi_resize() in 3.8.0+ calls EndPaint internally, which guacamole relies on
|
|
# - GFX pipeline surface synchronisation is fixed in 3.8.0+
|
|
# Building 3.x HEAD from source (always >= 3.8.0 by now) gives us the
|
|
# correct FreeRDP that guacamole-server git main was developed against.
|
|
#
|
|
# Build notes:
|
|
# - CPPFLAGS=-DHAVE_FREERDP_VERIFYCERTIFICATEEX=1 fixes a macro name mismatch
|
|
# in guacamole-server: configure.ac generates HAVE_STRUCT_FREERDP_VERIFYCERTIFICATEEX
|
|
# (AC_CHECK_MEMBERS adds STRUCT_ prefix) but rdp.c checks
|
|
# HAVE_FREERDP_VERIFYCERTIFICATEEX (no STRUCT_). Without this the VerifyCertificateEx
|
|
# callback is never registered, causing a silent drop ~430ms after keymap load.
|
|
# - display-flush.c / display-plan.c patch: loop over layers doesn't advance
|
|
# `current` before `continue` when pending_frame.buffer is NULL → infinite loop
|
|
# or GUAC_ASSERT abort. Fixed by replacing the GUAC_ASSERT with a pointer advance.
|
|
# - gdi.c patch: GUAC_ASSERT(current_context == NULL) in desktop_resize fires on
|
|
# FreeRDP 3.5.x because the GFX pipeline calls begin_paint then gdi_resize before
|
|
# end_paint. Replaced with a guard that calls end_paint if context is still open.
|
|
# With FreeRDP 3.8.0+ this code is inside #if MINOR < 8 so the patch is harmless.
|
|
# - user.c patch: guac_user_supports_webp() dereferences image_mimetypes without
|
|
# NULL check → SIGSEGV when client didn't send image MIME types.
|
|
|
|
FROM ubuntu:24.04
|
|
|
|
COPY docker/patch-display-flush.py /patch-display-flush.py
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
# Build dependencies for guacamole-server AND FreeRDP source build
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
autoconf \
|
|
automake \
|
|
build-essential \
|
|
ca-certificates \
|
|
cmake \
|
|
curl \
|
|
git \
|
|
libcairo2-dev \
|
|
libjpeg-turbo8-dev \
|
|
libossp-uuid-dev \
|
|
libpango1.0-dev \
|
|
libpng-dev \
|
|
libpulse-dev \
|
|
libssl-dev \
|
|
libssh2-1-dev \
|
|
libtelnet-dev \
|
|
libtool \
|
|
libvncserver-dev \
|
|
libwebp-dev \
|
|
libwebsockets-dev \
|
|
libkrb5-dev \
|
|
libavcodec-dev \
|
|
libavutil-dev \
|
|
libswscale-dev \
|
|
libusb-1.0-0-dev \
|
|
pkgconf \
|
|
zlib1g-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Build FreeRDP 3.x from source (3.8.0+ required for guacamole-server git main).
|
|
# We install to /usr with lib under lib/ (not lib/x86_64-linux-gnu/) so that
|
|
# pkg-config --variable=libdir freerdp3 returns /usr/lib cleanly.
|
|
# Optional features (audio, printing, X11 display, H264, Kerberos) are disabled
|
|
# since guacd runs headless and we have disable-audio: true.
|
|
RUN git clone --depth=1 --branch 3.22.0 https://github.com/FreeRDP/FreeRDP.git /tmp/freerdp \
|
|
&& cmake -S /tmp/freerdp -B /tmp/freerdp-build \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
|
-DCMAKE_INSTALL_LIBDIR=lib \
|
|
-DWITH_X11=OFF \
|
|
-DWITH_WAYLAND=OFF \
|
|
-DWITH_PULSEAUDIO=OFF \
|
|
-DWITH_ALSA=OFF \
|
|
-DWITH_OSS=OFF \
|
|
-DWITH_CUPS=OFF \
|
|
-DWITH_FFMPEG=OFF \
|
|
-DWITH_OPENH264=OFF \
|
|
-DWITH_JPEG=ON \
|
|
-DWITH_CAIRO=ON \
|
|
-DWITH_CHANNELS=ON \
|
|
-DWITH_CLIENT=ON \
|
|
-DWITH_CLIENT_COMMON=ON \
|
|
-DWITH_SERVER=OFF \
|
|
-DWITH_SAMPLE=OFF \
|
|
-DBUILD_TESTING=OFF \
|
|
-DWITH_GSSAPI=OFF \
|
|
-DWITH_FUSE=OFF \
|
|
&& cmake --build /tmp/freerdp-build -j"$(nproc)" \
|
|
&& cmake --install /tmp/freerdp-build \
|
|
&& ldconfig \
|
|
&& rm -rf /tmp/freerdp /tmp/freerdp-build
|
|
|
|
# Build guacamole-server from git main against our newly installed FreeRDP 3.x.
|
|
RUN FREERDP_PLUGIN_DIR=$(pkg-config --variable=libdir freerdp3 2>/dev/null)/freerdp3 \
|
|
&& echo "Building guacamole-server (git main) with FreeRDP plugin dir: ${FREERDP_PLUGIN_DIR}" \
|
|
&& echo "FreeRDP version: $(pkg-config --modversion freerdp3)" \
|
|
&& git clone --depth=1 https://github.com/apache/guacamole-server.git \
|
|
&& cd guacamole-server \
|
|
&& python3 /patch-display-flush.py \
|
|
&& autoreconf -fi \
|
|
&& CPPFLAGS="-Wno-error=deprecated-declarations -DHAVE_FREERDP_VERIFYCERTIFICATEEX=1" \
|
|
CFLAGS="-O2 -Wno-error=unused-variable" \
|
|
./configure \
|
|
--prefix=/usr \
|
|
--sysconfdir=/etc \
|
|
--with-freerdp-plugin-dir="${FREERDP_PLUGIN_DIR}" \
|
|
&& make -j"$(nproc)" \
|
|
&& make install \
|
|
&& ldconfig \
|
|
&& cd / && rm -rf guacamole-server
|
|
|
|
# guacd log level is passed via -L flag; exposed as env var for docker-compose
|
|
ENV GUACD_LOG_LEVEL=info
|
|
|
|
EXPOSE 4822
|
|
|
|
CMD sh -c "exec /usr/sbin/guacd -b 0.0.0.0 -f -L \"${GUACD_LOG_LEVEL}\""
|