# syntax=docker/dockerfile:1 # ───────────────────────────────────────────────────────────────────────────── # Stage 1 — Build # ───────────────────────────────────────────────────────────────────────────── FROM ubuntu:24.04 AS builder ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ cmake \ ninja-build \ git \ curl \ zip \ unzip \ tar \ pkg-config \ ca-certificates \ autoconf \ autoconf-archive \ automake \ libtool \ nasm \ python3 \ && rm -rf /var/lib/apt/lists/* # Fetch vcpkg at the exact commit pinned in vcpkg.json builtin-baseline. # vcpkg resolves baselines via `git show :versions/baseline.json`, so it # needs a real .git repo — not a tarball. A single shallow fetch is fast (~30 MB) # and gives vcpkg exactly what it needs. ARG VCPKG_COMMIT=d46283cf33cf5de7bd88e12156ce03882be1f179 RUN git init /vcpkg \ && git -C /vcpkg remote add origin https://github.com/microsoft/vcpkg.git \ && git -C /vcpkg fetch --depth=1 origin "${VCPKG_COMMIT}" \ && git -C /vcpkg checkout FETCH_HEAD \ && /vcpkg/bootstrap-vcpkg.sh -disableMetrics ENV VCPKG_ROOT=/vcpkg ENV VCPKG_DISABLE_METRICS=1 WORKDIR /src COPY . . ARG TARGETARCH # Three cache mounts: # downloads — source tarballs (~200 MB); safe to share across arches # vcpkg-cache — vcpkg binary cache (pre-built .zip archives per package ABI); # restores packages in seconds on subsequent builds instead of # recompiling. Scoped by arch so amd64/arm64 don't collide. # buildtrees — NOT cached; deleted at end of layer so neither the Docker # image nor the BuildKit cache accumulates several GB of # intermediate build artifacts. ENV VCPKG_BINARY_SOURCES="clear;files,/vcpkg-cache,readwrite" RUN --mount=type=cache,target=/vcpkg/downloads \ --mount=type=cache,target=/vcpkg-cache,id=vc-bin-${TARGETARCH} \ cmake --preset server-release \ && cmake --build --preset server-release \ && rm -rf /vcpkg/buildtrees # ───────────────────────────────────────────────────────────────────────────── # Stage 2 — Export (binary-only, used by scripts/build-linux-binaries.sh) # docker buildx build --target export --output type=local,dest=./dist/linux-amd64 . # ───────────────────────────────────────────────────────────────────────────── FROM scratch AS export COPY --from=builder /src/build/server-release/bin/voicecat-server /voicecat-server COPY --from=builder /src/build/server-release/bin/voicecat-admin /voicecat-admin # ───────────────────────────────────────────────────────────────────────────── # Stage 3 — Runtime (default stage — must be last) # ───────────────────────────────────────────────────────────────────────────── FROM ubuntu:24.04 AS runtime ENV DEBIAN_FRONTEND=noninteractive # ca-certificates is useful if the server ever makes outbound TLS calls; also # satisfies any mbedTLS system-CA lookup at runtime. RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ && rm -rf /var/lib/apt/lists/* RUN groupadd -r voicecat && useradd -r -g voicecat -s /sbin/nologin voicecat COPY --from=builder /src/build/server-release/bin/voicecat-server /usr/local/bin/voicecat-server COPY --from=builder /src/build/server-release/bin/voicecat-admin /usr/local/bin/voicecat-admin RUN mkdir -p /data && chown voicecat:voicecat /data USER voicecat # Persistent state: Ed25519 identity key, self-signed TLS cert, SQLite database. VOLUME ["/data"] # Control (TLS 1.3) and media (ChaCha20-Poly1305) share one port number on TCP+UDP. EXPOSE 8384/tcp EXPOSE 8384/udp ENTRYPOINT ["/usr/local/bin/voicecat-server"] CMD ["--data-dir", "/data"]