-
Notifications
You must be signed in to change notification settings - Fork 203
Expand file tree
/
Copy pathDockerfile
More file actions
74 lines (69 loc) · 3.37 KB
/
Dockerfile
File metadata and controls
74 lines (69 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# syntax=docker/dockerfile:1
#
# Multi-stage build for the mhrv-tunnel-node service.
#
# Build stage compiles a release binary against rust 1.85 (matches MSRV in
# Cargo.toml). Cargo's incremental build cache is mounted via BuildKit
# `--mount=type=cache` so a `docker build` against an unchanged dependency
# tree skips re-downloading + re-compiling crates — first build ~6 min,
# warm builds ~30 s.
#
# Runtime stage is `debian:bookworm-slim` for libc compatibility (the
# binary dynamically links against glibc) plus `ca-certificates` so HTTPS
# upstream URLs from `data` ops can do TLS handshake. Image stays under
# 100 MB end-to-end.
#
# Runs as a dedicated non-root `tunnel` user (uid 1000) — the service
# never needs to write outside its own process state, so no reason to
# give it root.
#
# Required env vars:
# TUNNEL_AUTH_KEY shared secret matching `const TUNNEL_AUTH_KEY` in
# CodeFull.gs. The service refuses every request
# without a matching key.
# PORT HTTP listen port. Defaults to 8080 if unset.
#
# Health: the service responds to `GET /` with a small status JSON. Add
# `--health-cmd 'curl -fsS http://localhost:8080/ || exit 1'` on the
# `docker run` if you want compose-level health gating.
FROM rust:1.85-slim AS builder
WORKDIR /app
# Copy lockfile so cargo uses pinned versions identically to local builds.
COPY Cargo.toml Cargo.lock ./
COPY src/ ./src/
# BuildKit cache mounts: cargo's registry/git caches and the target/
# directory persist across builds, dramatically speeding up rebuilds when
# only application code changes.
#
# `id=...-$TARGETPLATFORM` is load-bearing on multi-arch builds. Without
# it, BuildKit defaults to a single shared cache across architectures
# and the `linux/amd64` + `linux/arm64` jobs race on the same on-disk
# `/usr/local/cargo/registry/src/.../<crate>/.cargo-ok` extraction. The
# second-arriving arch hits `File exists (os error 17)` mid-unpack and
# the whole multi-arch build fails. Per-platform cache id keeps each
# arch's cache isolated; warm-build speedup is preserved per-arch.
# `target` cache is also platform-scoped because target/ holds object
# files for one ABI and sharing them across arches would just produce
# misses or, worse, invalid linking.
ARG TARGETPLATFORM
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo-registry-${TARGETPLATFORM} \
--mount=type=cache,target=/usr/local/cargo/git,id=cargo-git-${TARGETPLATFORM} \
--mount=type=cache,target=/app/target,id=app-target-${TARGETPLATFORM} \
cargo build --release --bin tunnel-node && \
cp /app/target/release/tunnel-node /usr/local/bin/tunnel-node
FROM debian:bookworm-slim
# `ca-certificates` for HTTPS upstream targets; nothing else needed at
# runtime since the binary is statically linked against musl-equivalents
# only for the parts that don't touch glibc.
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Non-root runtime user. The service does no filesystem writes outside
# /tmp, so a static-uid unprivileged user is sufficient and prevents
# accidental host-FS writes if the container is volume-mounted.
RUN useradd --system --uid 1000 --no-create-home --shell /usr/sbin/nologin tunnel
COPY --from=builder /usr/local/bin/tunnel-node /usr/local/bin/tunnel-node
USER tunnel
ENV PORT=8080
EXPOSE 8080
ENTRYPOINT ["tunnel-node"]