The CVE-hardening pass purged yq (vulnerable Go stdlib in the base copy), but kasmvnc-entrypoint.sh hard-depends on it to render kasmvnc.yaml. With yq gone, the kasmvnc supervisor program went FATAL on every fresh container, leaving a blank :21 desktop that container/nginx/Xvnc liveness all miss. Reinstall yq (mikefarah v4) as a current static binary after the purge — a recent release carries the patched Go stdlib that motivated the removal. yq is only needed at container runtime, so purge-then-reinstall ordering is safe; `yq --version` validates the download at build time.
80 lines
3.8 KiB
Docker
80 lines
3.8 KiB
Docker
# syntax=docker/dockerfile:1
|
|
FROM ghcr.io/selkies-project/nvidia-egl-desktop:latest
|
|
|
|
USER root
|
|
|
|
# Security patches: upgrade all OS packages + remove vulnerable binaries
|
|
# we don't need in a Zotero-only container.
|
|
# ipp-usb — IPP-over-USB printer daemon (Go stdlib CVEs)
|
|
# yq — vulnerable base copy removed here, then REPLACED below with a
|
|
# current static binary. kasmvnc-entrypoint.sh requires yq to
|
|
# render kasmvnc.yaml; purging it outright left the kasmvnc
|
|
# supervisor program FATAL on every fresh container (blank :21).
|
|
# firefox — base image browser; Zotero ships its own (expat CVEs)
|
|
RUN apt-get update \
|
|
&& apt-get upgrade -y \
|
|
&& apt-get purge -y --auto-remove ipp-usb firefox yq 2>/dev/null || true \
|
|
&& rm -f /usr/sbin/ipp-usb /usr/bin/yq \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Zotero
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl \
|
|
ca-certificates \
|
|
&& curl -sL https://raw.githubusercontent.com/retorquere/zotero-deb/master/install.sh | bash \
|
|
&& apt-get update && apt-get install -y --no-install-recommends \
|
|
zotero \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Reinstall yq as a current static binary (replaces the vulnerable base copy
|
|
# purged above). KasmVNC's entrypoint hard-depends on it (mikefarah v4 syntax);
|
|
# a recent release carries the patched Go stdlib that motivated the removal.
|
|
ARG YQ_VERSION=4.53.3
|
|
RUN arch="$(dpkg --print-architecture)" \
|
|
&& curl -fsSL "https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/yq_linux_${arch}" -o /usr/bin/yq \
|
|
&& chmod +x /usr/bin/yq \
|
|
&& yq --version
|
|
|
|
# Patch Python packages with known CVEs from base image
|
|
RUN pip install --no-cache-dir --break-system-packages --upgrade "pillow>=12.1.1"
|
|
|
|
# Create desktop shortcut for Zotero
|
|
RUN mkdir -p /home/ubuntu/Desktop \
|
|
&& cp /usr/share/applications/zotero.desktop /home/ubuntu/Desktop/ \
|
|
&& chmod +x /home/ubuntu/Desktop/zotero.desktop \
|
|
&& chown -R ubuntu:ubuntu /home/ubuntu/Desktop
|
|
|
|
# Desktop-bridge watchdog + healthcheck deps.
|
|
# x11-utils → xdpyinfo (probe X reachability of :20/:21)
|
|
# procps → pgrep (detect kasmxproxy / plasmashell)
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
x11-utils \
|
|
procps \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# otel-cli: enables OTLP span emission from the bridge watchdog. Dormant by
|
|
# default (the guard only emits when OTEL_EXPORTER_OTLP_ENDPOINT is set and
|
|
# this container is attached to the `observability` network — see compose.yml).
|
|
# Best-effort install so a release-asset hiccup never breaks the image build.
|
|
ARG OTEL_CLI_VERSION=0.4.5
|
|
RUN arch="$(dpkg --print-architecture | sed -e 's/amd64/amd64/' -e 's/arm64/arm64/')" \
|
|
&& curl -fsSL "https://github.com/equinix-labs/otel-cli/releases/download/v${OTEL_CLI_VERSION}/otel-cli_${OTEL_CLI_VERSION}_linux_${arch}.tar.gz" \
|
|
-o /tmp/otel-cli.tgz \
|
|
&& tar -xzf /tmp/otel-cli.tgz -C /usr/local/bin otel-cli \
|
|
&& chmod +x /usr/local/bin/otel-cli \
|
|
&& rm -f /tmp/otel-cli.tgz \
|
|
|| echo 'WARN: otel-cli install failed; OTLP tracing will be unavailable'
|
|
|
|
# Desktop-bridge watchdog (fixes the kasmxproxy startup race) + healthcheck.
|
|
COPY infra/images/zotero/kasmxproxy-guard.sh /usr/local/bin/kasmxproxy-guard.sh
|
|
COPY infra/images/zotero/zotero-healthcheck.sh /usr/local/bin/zotero-healthcheck
|
|
COPY infra/images/zotero/kasmxproxy-guard.conf /etc/supervisor/conf.d/kasmxproxy-guard.conf
|
|
RUN chmod +x /usr/local/bin/kasmxproxy-guard.sh /usr/local/bin/zotero-healthcheck
|
|
|
|
# Detect a blank desktop (dead :20->:21 bridge), which container/nginx/Xvnc
|
|
# liveness all miss. Compose overrides interval/start_period as needed.
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=180s --retries=5 \
|
|
CMD /usr/local/bin/zotero-healthcheck
|
|
|
|
USER ubuntu
|