Skip to content

GUACAMOLE-1374: Migrate to LOG_LEVEL and modular Docker build. #575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 185 additions & 59 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,46 +25,24 @@
# NOTE: Using 3.18 because the required openssl1.1-compat-dev package was
# removed in more recent versions.
ARG ALPINE_BASE_IMAGE=3.18
FROM alpine:${ALPINE_BASE_IMAGE} AS builder

# FreeRDP version (default to version 3)
ARG FREERDP_VERSION=3
# The target architecture of the build. Valid values are "ARM" and "X86". By
# default, this is detected automatically.
ARG BUILD_ARCHITECTURE

# Install build dependencies
RUN apk add --no-cache \
autoconf \
automake \
build-base \
cairo-dev \
cjson-dev \
cmake \
cunit-dev \
git \
grep \
krb5-dev \
libjpeg-turbo-dev \
libpng-dev \
libtool \
libwebp-dev \
make \
openssl1.1-compat-dev \
pango-dev \
pulseaudio-dev \
sdl2-dev \
sdl2_ttf-dev \
util-linux-dev \
webkit2gtk-dev
# The number of processes that may run simultaneously during the build. By
# default, this is detected automatically.
ARG BUILD_JOBS

# Copy source to container for sake of build
# The directory that will house the guacamole-server source during the build
ARG BUILD_DIR=/tmp/guacamole-server
COPY . ${BUILD_DIR}

#
# Base directory for installed build artifacts.
#
# NOTE: Due to limitations of the Docker image build process, this value is
# duplicated in an ARG in the second stage of the build.
#
# FreeRDP version (default to version 3)
ARG FREERDP_VERSION=3

# The final install location for guacamole-server and all dependencies. NOTE:
# This value is hard-coded in the entrypoint. Any change to this value must be
# propagated there.
ARG PREFIX_DIR=/opt/guacamole

#
Expand All @@ -84,6 +62,8 @@ ARG WITH_LIBWEBSOCKETS='v\d+(\.\d+)+'
# options are needed)
#

ARG FREERDP_ARM_OPTS=""

ARG FREERDP_OPTS="\
-DBUILTIN_CHANNELS=OFF \
-DCHANNEL_URBDRC=OFF \
Expand Down Expand Up @@ -112,7 +92,6 @@ ARG FREERDP_OPTS="\
-DWITH_SERVER_INTERFACE=OFF \
-DWITH_SHADOW_MAC=OFF \
-DWITH_SHADOW_X11=OFF \
-DWITH_SSE2=ON \
-DWITH_SWSCALE=OFF \
-DWITH_WAYLAND=OFF \
-DWITH_X11=OFF \
Expand All @@ -127,19 +106,40 @@ ARG FREERDP_OPTS="\
-DWITH_XV=OFF \
-DWITH_ZLIB=ON"

ARG FREERDP_X86_OPTS=""

ARG GUACAMOLE_SERVER_ARM_OPTS=""

ARG GUACAMOLE_SERVER_OPTS="\
--disable-guaclog"
--disable-guaclog \
CPPFLAGS=-Wno-error=deprecated-declarations"

ARG GUACAMOLE_SERVER_X86_OPTS=""

ARG LIBSSH2_ARM_OPTS=""

ARG LIBSSH2_OPTS="\
-DBUILD_EXAMPLES=OFF \
-DBUILD_SHARED_LIBS=ON"

ARG LIBSSH2_X86_OPTS=""

ARG LIBTELNET_ARM_OPTS=""

ARG LIBTELNET_OPTS="\
--disable-static \
--disable-util"

ARG LIBTELNET_X86_OPTS=""

ARG LIBVNCCLIENT_ARM_OPTS=""

ARG LIBVNCCLIENT_OPTS=""

ARG LIBVNCCLIENT_X86_OPTS=""

ARG LIBWEBSOCKETS_ARM_OPTS=""

ARG LIBWEBSOCKETS_OPTS="\
-DDISABLE_WERROR=ON \
-DLWS_WITHOUT_SERVER=ON \
Expand All @@ -150,8 +150,143 @@ ARG LIBWEBSOCKETS_OPTS="\
-DLWS_WITHOUT_TEST_SERVER_EXTPOLL=ON \
-DLWS_WITH_STATIC=OFF"

# Build guacamole-server and its core protocol library dependencies
RUN ${BUILD_DIR}/src/guacd-docker/bin/build-all.sh
ARG LIBWEBSOCKETS_X86_OPTS=""

#
# Base builder image that will be used by subsequent build stages, including
# for building dependencies of guacamole-server.
#

FROM alpine:${ALPINE_BASE_IMAGE} AS builder
ARG BUILD_DIR

# Install build dependencies
RUN apk add --no-cache \
autoconf \
automake \
build-base \
cairo-dev \
cjson-dev \
cmake \
cunit-dev \
git \
grep \
krb5-dev \
libjpeg-turbo-dev \
libpng-dev \
libtool \
libwebp-dev \
make \
openssl1.1-compat-dev \
pango-dev \
pulseaudio-dev \
sdl2-dev \
sdl2_ttf-dev \
util-linux-dev \
webkit2gtk-dev

# Copy generic, automatic build script
COPY ./src/guacd-docker/bin/autobuild.sh ${BUILD_DIR}/src/guacd-docker/bin/

#
# Build dependency: libssh2
#

FROM builder AS libssh2
ARG BUILD_DIR
ARG LIBSSH2_ARM_OPTS
ARG LIBSSH2_OPTS
ARG LIBSSH2_X86_OPTS
ARG PREFIX_DIR
ARG WITH_LIBSSH2

RUN ${BUILD_DIR}/src/guacd-docker/bin/autobuild.sh "LIBSSH2" \
"https://github.com/libssh2/libssh2"

#
# Build dependency: libtelnet
#

FROM builder AS libtelnet
ARG BUILD_DIR
ARG LIBTELNET_ARM_OPTS
ARG LIBTELNET_OPTS
ARG LIBTELNET_X86_OPTS
ARG PREFIX_DIR
ARG WITH_LIBTELNET

RUN ${BUILD_DIR}/src/guacd-docker/bin/autobuild.sh "LIBTELNET" \
"https://github.com/seanmiddleditch/libtelnet"

#
# Build dependency: libvncclient
#

FROM builder AS libvncclient
ARG BUILD_DIR
ARG LIBVNCCLIENT_ARM_OPTS
ARG LIBVNCCLIENT_OPTS
ARG LIBVNCCLIENT_X86_OPTS
ARG PREFIX_DIR
ARG WITH_LIBVNCCLIENT

RUN ${BUILD_DIR}/src/guacd-docker/bin/autobuild.sh "LIBVNCCLIENT" \
"https://github.com/LibVNC/libvncserver"

#
# Build dependency: libwebsockets
#

FROM builder AS libwebsockets
ARG BUILD_DIR
ARG LIBWEBSOCKETS_ARM_OPTS
ARG LIBWEBSOCKETS_OPTS
ARG LIBWEBSOCKETS_X86_OPTS
ARG PREFIX_DIR
ARG WITH_LIBWEBSOCKETS

RUN ${BUILD_DIR}/src/guacd-docker/bin/autobuild.sh "LIBWEBSOCKETS" \
"https://github.com/warmcat/libwebsockets"

#
# Build dependency: FreeRDP
#

FROM builder AS freerdp
ARG BUILD_DIR
ARG FREERDP_ARM_OPTS
ARG FREERDP_OPTS
ARG FREERDP_X86_OPTS
ARG PREFIX_DIR
ARG WITH_FREERDP

RUN ${BUILD_DIR}/src/guacd-docker/bin/autobuild.sh "FREERDP" \
"https://github.com/FreeRDP/FreeRDP"

#
# STAGE 7: Collect dependencies built by previous stages and build
# guacamole-server.
#

FROM builder AS guacamole-server
ARG BUILD_DIR
ARG FREERDP_VERSION
ARG GUACAMOLE_SERVER_ARM_OPTS
ARG GUACAMOLE_SERVER_OPTS
ARG GUACAMOLE_SERVER_X86_OPTS
ARG PREFIX_DIR

# Copy dependencies built in previous stages
COPY --from=freerdp ${PREFIX_DIR} ${PREFIX_DIR}
COPY --from=libssh2 ${PREFIX_DIR} ${PREFIX_DIR}
COPY --from=libtelnet ${PREFIX_DIR} ${PREFIX_DIR}
COPY --from=libvncclient ${PREFIX_DIR} ${PREFIX_DIR}
COPY --from=libwebsockets ${PREFIX_DIR} ${PREFIX_DIR}

# Use guacamole-server source from build context
COPY . ${BUILD_DIR}

RUN ${BUILD_DIR}/src/guacd-docker/bin/autobuild.sh "GUACAMOLE_SERVER" "${BUILD_DIR}"

# Determine location of the FREERDP library based on the version.
ARG FREERDP_LIB_PATH=${PREFIX_DIR}/lib/freerdp${FREERDP_VERSION}
Expand All @@ -163,25 +298,16 @@ RUN ${BUILD_DIR}/src/guacd-docker/bin/list-dependencies.sh \
${FREERDP_LIB_PATH}/*guac*.so \
> ${PREFIX_DIR}/DEPENDENCIES

# Use same Alpine version as the base for the runtime image
FROM alpine:${ALPINE_BASE_IMAGE}

#
# Base directory for installed build artifacts. See also the
# CMD directive at the end of this build stage.
#
# NOTE: Due to limitations of the Docker image build process, this value is
# duplicated in an ARG in the first stage of the build.
# STAGE 8: Final, runtime image.
#
ARG PREFIX_DIR=/opt/guacamole

# Runtime environment
ENV LC_ALL=C.UTF-8
ENV LD_LIBRARY_PATH=${PREFIX_DIR}/lib
ENV GUACD_LOG_LEVEL=info
# Use same Alpine version as the base for the runtime image
FROM alpine:${ALPINE_BASE_IMAGE} AS runtime
ARG PREFIX_DIR

# Copy build artifacts into this stage
COPY --from=builder ${PREFIX_DIR} ${PREFIX_DIR}
COPY --from=guacamole-server ${PREFIX_DIR} ${PREFIX_DIR}

# Bring runtime environment up to date and install runtime dependencies
RUN apk add --no-cache \
Expand All @@ -196,6 +322,10 @@ RUN apk add --no-cache \
util-linux-login && \
xargs apk add --no-cache < ${PREFIX_DIR}/DEPENDENCIES

# Runtime environment
ENV LC_ALL=C.UTF-8
ENV LD_LIBRARY_PATH=${PREFIX_DIR}/lib

# Checks the operating status every 5 minutes with a timeout of 5 seconds
HEALTHCHECK --interval=5m --timeout=5s CMD nc -z 127.0.0.1 4822 || exit 1

Expand All @@ -211,9 +341,5 @@ USER guacd
# Expose the default listener port
EXPOSE 4822

# Start guacd, listening on port 0.0.0.0:4822
#
# Note the path here MUST correspond to the value specified in the
# PREFIX_DIR build argument.
#
CMD /opt/guacamole/sbin/guacd -b 0.0.0.0 -L $GUACD_LOG_LEVEL -f
COPY ./src/guacd-docker/bin/entrypoint.sh /opt/guacamole/
ENTRYPOINT [ "/opt/guacamole/entrypoint.sh" ]
Loading