# Build on the same Debian release as the runtime image. This pins glibc, # libssl and libopus, so a binary built on a rolling-release host (Arch, etc.) # no longer fails on Debian due to newer toolchain/glibc symbols. FROM rust:1-trixie AS builder ENV DEBIAN_FRONTEND=noninteractive # Build dependencies: # - cmake + clang + libclang-dev: espeak-rs-sys (pulled in by piper-rs) builds # espeak-ng and runs bindgen # - pkg-config + libopus-dev: libopus_sys # - libssl-dev: native-tls / openssl-sys RUN apt-get update \ && apt-get install -y --no-install-recommends \ cmake \ clang \ libclang-dev \ pkg-config \ libopus-dev \ libssl-dev \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # Compile the dependency graph once with a dummy main so source edits do not # invalidate the expensive piper/espeak/onnxruntime build. COPY Cargo.toml Cargo.lock build.rs ./ RUN mkdir src \ && printf 'fn main() {}\n' > src/main.rs \ && cargo build --release \ && rm -rf src COPY src ./src RUN cargo build --release # espeak-rs-sys installs the espeak-ng data into the build directory and # compiles that path in as the default. Without this the runtime image has no # data files and TTS fails with "phontab: No such file or directory". RUN cp -a target/release/build/espeak-rs-sys-*/out/share/espeak-ng-data /app/espeak-ng-data # ── Runtime ─────────────────────────────────────────────────────────── FROM debian:trixie-slim ENV DEBIAN_FRONTEND=noninteractive # Runtime libraries reported by `readelf -d`: libstdc++, libopus, libssl, # libcrypto. ffmpeg/qalc/yt-dlp are invoked as subprocesses. # Full python3 (not python3-minimal) is required by the yt-dlp zipapp. RUN apt-get update \ && apt-get install -y --no-install-recommends \ ca-certificates \ ffmpeg \ imagemagick \ libopus0 \ libssl3t64 \ libstdc++6 \ passwd \ python3 \ qalc \ tzdata \ && rm -rf /var/lib/apt/lists/* # yt-dlp is distributed as a self-contained Python zipapp. Pin a release that # is at least a week old (and verify its checksum) so a compromised or broken # upstream release cannot silently enter the image. ARG YTDLP_VERSION=2026.10.26 ADD https://github.com/yt-dlp/yt-dlp/releases/download/${YTDLP_VERSION}/yt-dlp /usr/local/bin/yt-dlp ADD https://github.com/yt-dlp/yt-dlp/releases/download/${YTDLP_VERSION}/SHA2-256SUMS /tmp/yt-dlp-sums RUN cd /usr/local/bin \ && grep ' yt-dlp$' /tmp/yt-dlp-sums | sha256sum -c - \ && chmod 755 yt-dlp \ && rm /tmp/yt-dlp-sums RUN useradd --create-home --uid 1000 --shell /usr/sbin/nologin bot \ && mkdir -p /app/data /app/piper /tmp/senator_sperma \ && chown -R bot:bot /app /tmp/senator_sperma WORKDIR /app COPY --from=builder /app/target/release/senator-sperma /usr/local/bin/senator-sperma # espeak looks for /espeak-ng-data. COPY --from=builder /app/espeak-ng-data /usr/share/espeak-ng-data USER bot ENV TZ=Europe/Warsaw \ TTS_MODEL_PATH=/app/piper \ PIPER_ESPEAKNG_DATA_DIRECTORY=/usr/share \ RUST_LOG=info \ HOME=/home/bot ENTRYPOINT ["/usr/local/bin/senator-sperma"]