Files
stack/infra/images/zotero.Dockerfile
kert 19537deb11 fix(zotero): reinstall yq as static binary so KasmVNC entrypoint isn't FATAL
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.
2026-07-08 09:28:45 -04:00

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