chore(deploy): build rust binaries in a podman container

Workstation runs Fedora 44 (glibc 2.43); servers are still on F42 and
F43. A native release build produces ELFs the older glibc can't load
(GLIBC_2.43 not found), and the api/worker units fail-loop on every
deploy. Build inside docker.io/library/rust:1-bookworm (glibc 2.36)
so the artifacts are forward-compatible with every Fedora target.
Output goes to target/deploy/ to keep separate from native dev
builds, and the cargo registry/git index are cached in named podman
volumes so subsequent builds are incremental. podman is a hard
requirement; no docker fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-17 16:05:13 +03:00
parent 8a7177a54a
commit acb061baca

View File

@@ -64,6 +64,20 @@ command -v yq >/dev/null 2>&1 || die "yq is required"
command -v pass >/dev/null 2>&1 || die "pass is required" command -v pass >/dev/null 2>&1 || die "pass is required"
command -v rsync >/dev/null 2>&1 || die "rsync is required" command -v rsync >/dev/null 2>&1 || die "rsync is required"
command -v cargo >/dev/null 2>&1 || die "cargo is required" command -v cargo >/dev/null 2>&1 || die "cargo is required"
command -v podman >/dev/null 2>&1 || die "podman is required (used for the deploy build container)"
# Rust binaries are built inside a Debian container so the resulting ELF
# links against an older glibc than this workstation's. Building natively
# on f44 (glibc 2.43) produces binaries that won't load on f42 / f43
# servers — the dynamic loader refuses them outright. Debian bookworm's
# glibc 2.36 is older than every Fedora release we deploy to, so its
# binaries are forward-compatible.
#
# The artifacts land in target/deploy/release/ so a native `cargo build`
# in this checkout (for tests, clippy, dev runs) doesn't compete with
# the container for incremental state, and vice-versa.
rust_build_image="docker.io/library/rust:1-bookworm"
rust_target_dir="${repo_root}/target/deploy"
# Resolve component list ---------------------------------------------------- # Resolve component list ----------------------------------------------------
@@ -93,8 +107,20 @@ for c in "${components[@]}"; do
done done
if (( needs_rust )); then if (( needs_rust )); then
log "cargo build --release (api, worker)" log "cargo build --release in ${rust_build_image} (api, worker)"
run cargo build --release --bin moments-api --bin moments-worker --manifest-path "${repo_root}/Cargo.toml" install --directory "$rust_target_dir"
# Named volumes cache the cargo registry and git index across runs so
# subsequent builds don't re-fetch every crate. CARGO_TARGET_DIR
# redirects build output into the host-mounted target/deploy.
# :Z relabels the bind mount for SELinux on Fedora hosts.
run podman run --rm \
--volume "${repo_root}:/workspace:Z" \
--volume moments-deploy-cargo-registry:/usr/local/cargo/registry \
--volume moments-deploy-cargo-git:/usr/local/cargo/git \
--workdir /workspace \
--env CARGO_TARGET_DIR=/workspace/target/deploy \
"$rust_build_image" \
cargo build --release --bin moments-api --bin moments-worker
fi fi
if (( needs_web )); then if (( needs_web )); then
@@ -156,7 +182,7 @@ deploy_api() {
install --mode=0644 "${repo_root}/asset/systemd/moments-api.service" "$stage/etc/systemd/system/" install --mode=0644 "${repo_root}/asset/systemd/moments-api.service" "$stage/etc/systemd/system/"
install --mode=0644 "${repo_root}/asset/systemd/moments-api-cert-reload.service" "$stage/etc/systemd/system/" install --mode=0644 "${repo_root}/asset/systemd/moments-api-cert-reload.service" "$stage/etc/systemd/system/"
install --mode=0644 "${repo_root}/asset/systemd/moments.sysusers.conf" "$stage/etc/sysusers.d/moments.conf" install --mode=0644 "${repo_root}/asset/systemd/moments.sysusers.conf" "$stage/etc/sysusers.d/moments.conf"
install --mode=0755 "${repo_root}/target/release/moments-api" "$stage/usr/local/bin/moments-api" install --mode=0755 "${rust_target_dir}/release/moments-api" "$stage/usr/local/bin/moments-api"
chmod 0640 "$stage/etc/moments/api.env" chmod 0640 "$stage/etc/moments/api.env"
@@ -310,7 +336,7 @@ deploy_worker() {
install --mode=0644 "${repo_root}/asset/systemd/moments-worker.service" "$stage/etc/systemd/system/" install --mode=0644 "${repo_root}/asset/systemd/moments-worker.service" "$stage/etc/systemd/system/"
install --mode=0644 "${repo_root}/asset/systemd/moments-worker-cert-reload.service" "$stage/etc/systemd/system/" install --mode=0644 "${repo_root}/asset/systemd/moments-worker-cert-reload.service" "$stage/etc/systemd/system/"
install --mode=0644 "${repo_root}/asset/systemd/moments.sysusers.conf" "$stage/etc/sysusers.d/moments.conf" install --mode=0644 "${repo_root}/asset/systemd/moments.sysusers.conf" "$stage/etc/sysusers.d/moments.conf"
install --mode=0755 "${repo_root}/target/release/moments-worker" "$stage/usr/local/bin/moments-worker" install --mode=0755 "${rust_target_dir}/release/moments-worker" "$stage/usr/local/bin/moments-worker"
chmod 0640 "$stage/etc/moments/worker.env" chmod 0640 "$stage/etc/moments/worker.env"