114 lines · 5.2 KB · Dockerfile
RawDownload
# syntax=docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e## Container image for the `aspen` binary, and (target `place`) for the# `place` demo's back end with its built page.## Build from the repository root (the build context must be the whole# workspace):##   docker build -f deploy/docker/Dockerfile -t aspen .#   docker run --rm aspen --version#   docker run --rm aspen serve --help##   docker build -f deploy/docker/Dockerfile --target place -t aspen-place .## The runtime image is Debian slim with CA certificates, runs as an# unprivileged user (uid 10001) and contains only the `aspen` binary. It runs# `aspen serve` by default, configured from the environment# (deploy/README.md); `aspen healthcheck` is its health check, since the# image has no curl or wget. # Matches rust-toolchain.toml (deploy/scripts/check-rust-version.sh).ARG RUST_VERSION=1.99.1# The base images, each pinned to the digest of its multi-arch index, so a# build of the same commit always starts from the same bytes (issue #125).# The tag before each digest says what it is; deploy/scripts/check-image-pins.py# (required CI) checks every FROM, and that the tags agree with RUST_VERSION,# demo/place/.nvmrc and one Debian release. To bump one, change its tag and# take the new digest from `docker buildx imagetools inspect <image>:<tag>`.ARG RUST_IMAGE=rust:1.99.1-slim-trixie@sha256:ea0999ff67355d958b8799b6751c879a6d770076d26047dca66f6e51e77930d3ARG DEBIAN_IMAGE=debian:trixie-slim@sha256:f6b08b09a05725f9431502d3b5714f5c4576e82c1a84fa1debe0c24a7e0c3ec4ARG NODE_IMAGE=node:22.23.3-trixie-slim@sha256:28d03803f09ba76560e273af33beb7eda4ed68fa0698bc9bd15e9a6e35693923 FROM ${RUST_IMAGE} AS build# Use the image's toolchain as-is instead of letting rust-toolchain.toml pull# in extra components (clippy, rustfmt) that a release build does not need.ARG RUST_VERSIONENV RUSTUP_TOOLCHAIN=${RUST_VERSION} \    CARGO_TERM_COLOR=neverWORKDIR /srcCOPY . .RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \    --mount=type=cache,target=/src/target,sharing=locked \    cargo build --release --locked --package aspen-cli --bin aspen \ && install -D -m 0755 target/release/aspen /out/aspen # What every Aspen image ships: Debian slim with CA certificates, an# unprivileged user and a spool directory, but no binary yet.FROM ${DEBIAN_IMAGE} AS baseRUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates \ && rm -rf /var/lib/apt/lists/* \ && useradd --system --uid 10001 --user-group --home-dir /var/lib/aspen --create-home \      --shell /usr/sbin/nologin aspen \ && install -d -o 10001 -g 10001 -m 0750 /var/lib/aspen/spool# The push spool must be a real disk (never tmpfs): mount a volume here.# /-/metrics stays on the binary's default, 127.0.0.1:9464, inside the# container: a deployment that scrapes it sets ASPEN_METRICS_LISTEN to# 0.0.0.0:9464 itself (compose and the Helm chart do) and keeps the port off# any public load balancer (docs/OBSERVABILITY.md).ENV ASPEN_LISTEN=0.0.0.0:7070 \    ASPEN_SPOOL_DIR=/var/lib/aspen/spoolUSER 10001:10001WORKDIR /var/lib/aspen# 7070: Git over HTTP. 2222: Git over SSH, when ASPEN_SSH_LISTEN and a host# key are set (docs/SSH.md).EXPOSE 7070 2222ENTRYPOINT ["/usr/local/bin/aspen"]CMD ["serve"] # The place demo (demo/place): the page, built with Node, and aspen-place,# which serves it beside its API and canvas.git (PLACE_WEB_DIR).FROM ${NODE_IMAGE} AS place-webWORKDIR /src/demo/placeCOPY demo/place/package.json demo/place/package-lock.json ./RUN --mount=type=cache,target=/root/.npm,sharing=locked \    npm ci --no-audit --no-fundCOPY demo/place/ ./RUN npm run build FROM build AS place-buildRUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \    --mount=type=cache,target=/src/target,sharing=locked \    cargo build --release --locked --package aspen-place --bin aspen-place \ && install -D -m 0755 target/release/aspen-place /out/aspen-place # The canvas lives in PostgreSQL and an S3 bucket in production# (PLACE_DATABASE_URL, PLACE_BLOB_URL); without them, under# /var/lib/aspen/place. Pushes spool under /var/lib/aspen/spool.FROM base AS placeCOPY --from=place-build /out/aspen-place /usr/local/bin/aspen-placeCOPY --from=place-web /src/demo/place/dist /usr/share/aspen-place/webENV PLACE_LISTEN=0.0.0.0:7080 \    PLACE_WEB_DIR=/usr/share/aspen-place/web \    PLACE_DATA_DIR=/var/lib/aspen/place \    PLACE_SPOOL_DIR=/var/lib/aspen/spoolEXPOSE 7080ENTRYPOINT ["/usr/local/bin/aspen-place"]CMD ["serve"] # Release images (.github/workflows/release.yml): the binary was built and# tested per architecture before, and is passed in as a named build context,# so a multi-arch image needs no emulated compile:##   docker buildx build -f deploy/docker/Dockerfile --target release \#     --build-context dist=dist --platform linux/amd64,linux/arm64 .## where dist/linux-amd64/aspen and dist/linux-arm64/aspen are the binaries.FROM base AS releaseARG TARGETARCHCOPY --from=dist --chmod=0755 linux-${TARGETARCH}/aspen /usr/local/bin/aspen # The default target: compile from this checkout (compose, local builds, CI).FROM base AS runtimeCOPY --from=build /out/aspen /usr/local/bin/aspen