Files
buzz/Dockerfile
tornquist aef74600d4 Merge commit 'e76c81968b65b0755b83efdd59dc3375c59ddf40' into seiler/media-layout-migration
* commit 'e76c81968b65b0755b83efdd59dc3375c59ddf40': (159 commits)
  refactor(db): split channel membership store (#6782)
  feat(auth): add NIP-FI canonical assertion verifier and contracts (#6776)
  fix(desktop): resolve exact typed mentions on space (#6862)
  perf(desktop): restore project context during startup (#6939)
  fix(desktop): lift right auxiliary pane above shared header backdrop (#6966)
  fix(ci): bump Codex CLI to 0.150.1 to unhang security review jobs (#6962)
  feat(desktop): implement 30178 team catalog backend (#5112)
  feat(model-capabilities): humanize Databricks UC model families (#6955)
  feat(agent): discover Databricks Unity Catalog models (#6918)
  test(db): use canonical channel roster fixtures (#6819)
  preserve channel description paragraph breaks (#6946)
  fix(cli): enrich template cardinality error with per-candidate presence and profile hints (#4825)
  Fix Codex security review authorization (#6913)
  fix(db): disable heartbeat vacuum truncation (#6898)
  chore(deps): update rui314/setup-mold digest to 7e4f20a (#6663)
  chore(deps): update dependency vitest to v4.1.11 (#6667)
  chore(deps): update dependency @tanstack/react-virtual to v3.14.10 (#6666)
  chore(deps): update ubuntu:24.04 docker digest to 33ceb71 (#6664)
  fix(projects): allow owners to delete agent projects (#6533)
  Fade expanded video controls on hover (#6926)
  ...

# Conflicts:
#	crates/buzz-deletion/src/lib.rs
#	crates/buzz-media/Cargo.toml
#	crates/buzz-media/src/lib.rs
#	crates/buzz-media/src/storage.rs
2026-08-28 15:13:44 +00:00

195 lines
9.7 KiB
Docker

# syntax=docker/dockerfile:1.7
#
# Public Buzz relay image — published as ghcr.io/block/buzz:<tag>.
#
# Builds the `buzz-relay` binary (Rust 1.95) and the `buzz-web` static bundle
# (pnpm + vite), then assembles them into a small debian-slim runtime with
# `git` available (the relay shells out to git for repo hydrate / receive-pack
# / upload-pack — see crates/buzz-relay/src/api/git).
#
# Multi-arch is handled by running this same Dockerfile on native amd64 and
# native arm64 runners (see .github/workflows/docker.yml). The Dockerfile
# itself is platform-agnostic; do not add --platform pins.
ARG RUST_VERSION=1.95
ARG NODE_VERSION=24
ARG DEBIAN_VERSION=bookworm
# Optional extra CA bundle for builds behind a TLS-intercepting corporate proxy
# (e.g. a Cloudflare/Zscaler gateway that re-signs TLS). Empty by default, so
# public CI builds are unaffected. Point it at a PEM file in the build context:
# docker build --build-arg EXTRA_CA_CERTS=path/to/proxy-ca.pem ...
# Consumed by the network-touching stages below (cargo + pnpm).
ARG EXTRA_CA_CERTS=
# Optional npm registry for builds where the public registry is unreachable or
# policy-blocked (e.g. a corporate mirror / Artifactory). Empty default = public
# npmjs, so public CI builds are unaffected. Consumed by the web-builder stage.
ARG NPM_REGISTRY=
# ─── Stage 1: cargo-chef base ───────────────────────────────────────────────
FROM rust:${RUST_VERSION}-${DEBIAN_VERSION} AS chef
# Trust an optional corporate-proxy CA before any network fetch (no-op if unset).
ARG EXTRA_CA_CERTS
COPY --chmod=0644 ${EXTRA_CA_CERTS:-Dockerfile} /tmp/extra-ca/src
RUN if [ -n "${EXTRA_CA_CERTS}" ]; then \
cp /tmp/extra-ca/src /usr/local/share/ca-certificates/extra-proxy-ca.crt \
&& update-ca-certificates \
&& echo "CARGO_HTTP_CAINFO=/etc/ssl/certs/ca-certificates.crt" >> /etc/environment; \
fi
ENV CARGO_HTTP_CAINFO=/etc/ssl/certs/ca-certificates.crt
RUN cargo install cargo-chef --locked --version 0.1.71
WORKDIR /build
# ─── Stage 2: plan dependency graph ─────────────────────────────────────────
# Only the manifests are needed to compute the recipe; this layer rebuilds
# only when Cargo.{toml,lock} or crate manifests change, not on every source
# edit.
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
# ─── Stage 3: cook dependencies, then build the binary ──────────────────────
FROM chef AS builder
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
pkg-config \
libssl-dev \
ca-certificates \
git \
&& rm -rf /var/lib/apt/lists/*
# Keep enough DWARF for native profilers to resolve optimized code to source
# locations. The normal runtime strips it below; runtime-debug retains it.
ENV CARGO_PROFILE_RELEASE_DEBUG=line-tables-only
COPY --from=planner /build/recipe.json recipe.json
# Cook the full workspace recipe — relay deps include workspace siblings, so
# scoping to -p buzz-relay misses transitive deps and re-builds them later.
RUN cargo chef cook --release --recipe-path recipe.json
COPY . .
# Compile immutable artifact identity into the relay. Defaults preserve local
# and third-party builds that do not run in provenance-aware CI.
ARG BUZZ_SOURCE_SHA=unknown
ARG BUZZ_BUILD_ID=local
ARG BUZZ_BUILD_URL=unknown
ENV BUZZ_SOURCE_SHA=${BUZZ_SOURCE_SHA} \
BUZZ_BUILD_ID=${BUZZ_BUILD_ID} \
BUZZ_BUILD_URL=${BUZZ_BUILD_URL}
RUN cargo build --release --locked -p buzz-relay --bin buzz-relay \
-p buzz-admin --bin buzz-admin \
-p buzz-pair-relay --bin buzz-pair-relay \
-p buzz-media --bin buzz-media-layout-backfill \
--bin buzz-media-layout-delete-legacy
# Derive the normal release binaries from the same optimized ELF files as the
# debug image so the two variants cannot drift at code-generation time.
FROM builder AS stripped-binaries
RUN strip target/release/buzz-relay \
&& strip target/release/buzz-admin \
&& strip target/release/buzz-pair-relay \
&& strip target/release/buzz-media-layout-backfill \
&& strip target/release/buzz-media-layout-delete-legacy
# ─── Stage 4: web bundle (pnpm + vite) ──────────────────────────────────────
# Independent of the Rust layers so a CSS change doesn't bust Rust cache and
# vice versa.
FROM node:${NODE_VERSION}-${DEBIAN_VERSION}-slim AS web-builder
WORKDIR /build
# Trust an optional corporate-proxy CA so corepack + pnpm can fetch over an
# intercepting TLS gateway (no-op if EXTRA_CA_CERTS is unset).
ARG EXTRA_CA_CERTS
COPY --chmod=0644 ${EXTRA_CA_CERTS:-Dockerfile} /tmp/extra-ca/src
RUN if [ -n "${EXTRA_CA_CERTS}" ]; then \
apt-get update && apt-get install -y --no-install-recommends ca-certificates \
&& cp /tmp/extra-ca/src /usr/local/share/ca-certificates/extra-proxy-ca.crt \
&& update-ca-certificates \
&& rm -rf /var/lib/apt/lists/*; \
fi
ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
# Point npm + corepack at an optional mirror (no-op when NPM_REGISTRY is unset).
# corepack reads COREPACK_NPM_REGISTRY to fetch the pinned pnpm; pnpm/npm read
# the .npmrc registry for dependency installs.
ARG NPM_REGISTRY
ENV COREPACK_NPM_REGISTRY=${NPM_REGISTRY}
# When using a mirror, disable corepack's npmjs signature check: the mirror
# republishes tarballs without the public registry's provenance signatures, so
# strict verification fails ("No compatible signature found"). Only relaxed on
# the mirror path — public builds (NPM_REGISTRY unset) keep strict verification.
RUN if [ -n "${NPM_REGISTRY}" ]; then \
echo "registry=${NPM_REGISTRY}" > /build/.npmrc \
&& echo "COREPACK_INTEGRITY_KEYS=0" >> /etc/environment; \
fi
ENV COREPACK_INTEGRITY_KEYS=${NPM_REGISTRY:+0}
RUN corepack enable
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY patches/ patches/
COPY web/package.json web/
COPY admin-web/package.json admin-web/
RUN pnpm install --frozen-lockfile --filter buzz-web --filter buzz-admin-web
COPY web/ web/
COPY admin-web/ admin-web/
RUN pnpm -C web build && pnpm -C admin-web build
# ─── Stage 5: shared runtime ────────────────────────────────────────────────
FROM debian:${DEBIAN_VERSION}-slim AS runtime-base
# OCI annotations: required for GHCR to auto-link the image to this repo and
# inherit its visibility. org.opencontainers.image.source is the load-bearing
# one — without it GHCR keeps the image private even when the repo is public.
LABEL org.opencontainers.image.title="Buzz" \
org.opencontainers.image.description="WebSocket relay server for the Buzz communications platform" \
org.opencontainers.image.source="https://github.com/block/buzz" \
org.opencontainers.image.url="https://github.com/block/buzz" \
org.opencontainers.image.documentation="https://github.com/block/buzz#readme" \
org.opencontainers.image.licenses="Apache-2.0"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
openssl \
&& rm -rf /var/lib/apt/lists/* \
&& groupadd --system --gid 1000 buzz \
&& useradd --system --uid 1000 --gid 1000 --home-dir /var/lib/buzz \
--create-home --shell /usr/sbin/nologin buzz
COPY --from=web-builder /build/web/dist /srv/buzz/web
COPY --from=web-builder /build/admin-web/dist /srv/buzz/admin-web
# The invite landing page is always served from the bundled web UI. Repository
# browser routes require the separate BUZZ_SERVE_GIT_WEB_GUI=true opt-in. The
# admin bundle is inert until BUZZ_ADMIN_HOST is configured.
ENV BUZZ_WEB_DIR=/srv/buzz/web \
BUZZ_ADMIN_WEB_DIR=/srv/buzz/admin-web
# 3000: app (WS + REST) · 8080: /_liveness, /_readiness · 9102: /metrics
EXPOSE 3000 8080 9102
# deploy/compose mounts a volume here; pre-created so it inherits buzz:buzz.
RUN mkdir -p /data/git && chown buzz:buzz /data/git
USER buzz:buzz
WORKDIR /var/lib/buzz
ENTRYPOINT ["/usr/local/bin/buzz-relay"]
# Optimized binaries with line-table debug information for native profiling.
# Published under debug-* tags; runtime behavior otherwise matches the normal
# image exactly.
FROM runtime-base AS runtime-debug
COPY --from=builder /build/target/release/buzz-relay /usr/local/bin/buzz-relay
COPY --from=builder /build/target/release/buzz-admin /usr/local/bin/buzz-admin
COPY --from=builder /build/target/release/buzz-pair-relay /usr/local/bin/buzz-pair-relay
COPY --from=builder /build/target/release/buzz-media-layout-backfill /usr/local/bin/buzz-media-layout-backfill
COPY --from=builder /build/target/release/buzz-media-layout-delete-legacy /usr/local/bin/buzz-media-layout-delete-legacy
# Keep the stripped runtime as the final/default Dockerfile target so existing
# `docker build .` callers and release tags retain their current behavior.
FROM runtime-base AS runtime
COPY --from=stripped-binaries /build/target/release/buzz-relay /usr/local/bin/buzz-relay
COPY --from=stripped-binaries /build/target/release/buzz-admin /usr/local/bin/buzz-admin
COPY --from=stripped-binaries /build/target/release/buzz-pair-relay /usr/local/bin/buzz-pair-relay
COPY --from=stripped-binaries /build/target/release/buzz-media-layout-backfill /usr/local/bin/buzz-media-layout-backfill
COPY --from=stripped-binaries /build/target/release/buzz-media-layout-delete-legacy /usr/local/bin/buzz-media-layout-delete-legacy