From fd21e09923e7fbb2ebbd9a28ee8f9ff409c5c928 Mon Sep 17 00:00:00 2001 From: Zoran Regvart Date: Tue, 1 Sep 2026 16:07:10 +0200 Subject: [PATCH 1/2] Leave shell as PID 1 When rustguac replaces the PID 1 the shell will never invoke the trap on exit. This leaves the shell as PID 1 for the trap to be invoked on exit. --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 45e7f54..e4e7790 100644 --- a/Dockerfile +++ b/Dockerfile @@ -224,11 +224,13 @@ fi echo "guacd started (pid=$GUACD_PID)" # Trap signals to shut down both processes -trap 'kill $GUACD_PID 2>/dev/null; wait; exit 0' TERM INT +trap 'kill $GUACD_PID 2>/dev/null; kill $RUSTGUAC_PID 2>/dev/null; wait; exit 0' TERM INT # Run rustguac in foreground echo "Starting rustguac..." -exec /opt/rustguac/bin/rustguac --config "$CONFIG_PATH" serve +/opt/rustguac/bin/rustguac --config "$CONFIG_PATH" serve +RUSTGUAC_PID=$! +wait $RUSTGUAC_PID SCRIPT RUN chmod +x /opt/rustguac/entrypoint.sh From 221631709545b0dd0df162f93b8ead7f4d293c46 Mon Sep 17 00:00:00 2001 From: Zoran Regvart Date: Tue, 22 Sep 2026 10:29:48 +0200 Subject: [PATCH 2/2] Refine startup/shutdown Adds tini to manage processes launched from entrypoint.sh, namely guacd and rustguac. --- Dockerfile | 53 +++++---------------------------------------------- entrypoint.sh | 44 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 48 deletions(-) create mode 100644 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index e4e7790..f74b79e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -105,6 +105,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ x11-utils \ # Minimal runtime utilities ca-certificates \ + tini \ && rm -rf /var/lib/apt/lists/* # Install guacd @@ -185,53 +186,7 @@ RUN chown rustguac:rustguac /opt/rustguac && \ /opt/rustguac/tls /opt/rustguac/certs /opt/rustguac/drives \ /opt/rustguac/scripts /opt/rustguac/vdi-homes /opt/rustguac/config.toml.default -# Entrypoint script: starts guacd in background, then rustguac in foreground -RUN cat > /opt/rustguac/entrypoint.sh <<'SCRIPT' -#!/bin/sh -set -e - -# Copy default config on first run (if no config file is mounted/present) -CONFIG_PATH="/opt/rustguac/config.toml" -if [ ! -f "$CONFIG_PATH" ]; then - echo "No config.toml found — copying default configuration." - cp /opt/rustguac/config.toml.default "$CONFIG_PATH" -fi - -# Create admin API key on first run (if no DB exists yet) -DB_PATH="/opt/rustguac/data/rustguac.db" -if [ ! -f "$DB_PATH" ]; then - echo "First run detected — creating admin API key..." - /opt/rustguac/bin/rustguac --config "$CONFIG_PATH" add-admin --name docker-admin - echo "" - echo "==> SAVE THE API KEY ABOVE — it is only shown once! <==" - echo "" -fi - -# Start guacd in background -echo "Starting guacd..." -LD_LIBRARY_PATH=/opt/rustguac/lib FREERDP_ADDIN_PATH=/opt/rustguac/lib/freerdp3 \ - /opt/rustguac/sbin/guacd \ - -b 127.0.0.1 -l 4822 -L "${GUACD_LOG_LEVEL:-info}" -f \ - -C /opt/rustguac/tls/cert.pem -K /opt/rustguac/tls/key.pem & -GUACD_PID=$! - -# Wait briefly to confirm guacd started -sleep 0.5 -if ! kill -0 "$GUACD_PID" 2>/dev/null; then - echo "ERROR: guacd failed to start" - exit 1 -fi -echo "guacd started (pid=$GUACD_PID)" - -# Trap signals to shut down both processes -trap 'kill $GUACD_PID 2>/dev/null; kill $RUSTGUAC_PID 2>/dev/null; wait; exit 0' TERM INT - -# Run rustguac in foreground -echo "Starting rustguac..." -/opt/rustguac/bin/rustguac --config "$CONFIG_PATH" serve -RUSTGUAC_PID=$! -wait $RUSTGUAC_PID -SCRIPT +COPY entrypoint.sh /opt/rustguac/entrypoint.sh RUN chmod +x /opt/rustguac/entrypoint.sh WORKDIR /opt/rustguac @@ -243,4 +198,6 @@ ENV GUACD_LOG_LEVEL=info ENV HOME=/home/rustguac USER rustguac -ENTRYPOINT ["/opt/rustguac/entrypoint.sh"] +ENV TINI_KILL_PROCESS_GROUP=1 +ENTRYPOINT ["/usr/bin/tini", "--"] +CMD ["/opt/rustguac/entrypoint.sh"] \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..b04c437 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# Entrypoint script: starts guacd in background, then rustguac in background, waiting on both to exit +set -e + +# Copy default config on first run (if no config file is mounted/present) +CONFIG_PATH="/opt/rustguac/config.toml" +if [ ! -f "$CONFIG_PATH" ]; then + echo "No config.toml found — copying default configuration." + cp /opt/rustguac/config.toml.default "$CONFIG_PATH" +fi + +# Create admin API key on first run (if no DB exists yet) +DB_PATH="/opt/rustguac/data/rustguac.db" +if [ ! -f "$DB_PATH" ]; then + echo "First run detected — creating admin API key..." + /opt/rustguac/bin/rustguac --config "$CONFIG_PATH" add-admin --name docker-admin + echo "" + echo "==> SAVE THE API KEY ABOVE — it is only shown once! <==" + echo "" +fi + +# Start guacd in background +echo "Starting guacd..." +LD_LIBRARY_PATH=/opt/rustguac/lib FREERDP_ADDIN_PATH=/opt/rustguac/lib/freerdp3 \ + /opt/rustguac/sbin/guacd \ + -b 127.0.0.1 -l 4822 -L "${GUACD_LOG_LEVEL:-info}" -f \ + -C /opt/rustguac/tls/cert.pem -K /opt/rustguac/tls/key.pem & +GUACD_PID=$! + +# Wait briefly to confirm guacd started +sleep 0.5 +if ! kill -0 "$GUACD_PID" 2>/dev/null; then + echo "ERROR: guacd failed to start" + exit 1 +fi +echo "guacd started (pid=$GUACD_PID)" + + +# Run rustguac in foreground +echo "Starting rustguac..." +/opt/rustguac/bin/rustguac --config "$CONFIG_PATH" serve & +RUSTGUAC_PID=$! + +wait $GUACD_PID $RUSTGUAC_PID