Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/setup-runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fi
# ── Seed local Docker registry ───────────────────────────────────────────
# (Run before Python/Playwright so failures there don't block image seeding)
echo "Pushing CI images to local Docker registry (${DOCKER_REGISTRY})..."
ELIXIR_IMAGE="hexpm/elixir:1.17.3-erlang-27.1.2-debian-bookworm-20241202-slim"
ELIXIR_IMAGE="hexpm/elixir:1.17.3-erlang-27.3.4.14-debian-bookworm-20260623-slim"
RUNNER_IMAGE="debian:bookworm-20241202-slim"
for img in postgres:18.4 qdrant/qdrant:v1.17.1 node:20-slim "$ELIXIR_IMAGE" "$RUNNER_IMAGE"; do
local_tag="${DOCKER_REGISTRY}/${img}"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ jobs:
# GitHub Actions rejects the `env` context inside a job-level `env:`
# block, even referencing a workflow-level var (fails the whole run at
# parse time with zero jobs created, "workflow file issue").
MIX_BUILDER_IMAGE: "hexpm/elixir:1.17.3-erlang-27.1.2-debian-bookworm-20241202-slim"
MIX_BUILDER_IMAGE: "hexpm/elixir:1.17.3-erlang-27.3.4.14-debian-bookworm-20260623-slim"
outputs:
beam-tag: ${{ steps.beam.outputs.tag }}
deps-key: ${{ steps.keys.outputs.deps }}
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
# Multi-stage build: compile release in builder, run in minimal image
# cache-bust: 2026-04-18-encryption-auto-provision
ARG ELIXIR_VERSION=1.17.3
ARG OTP_VERSION=27.1.2
ARG DEBIAN_VERSION=bookworm-20241202-slim
ARG OTP_VERSION=27.3.4.14
ARG DEBIAN_VERSION=bookworm-20260623-slim

ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
Expand Down
2 changes: 1 addition & 1 deletion ci/compose.database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ services:
# Bare image refs; runner's HTTPS_PROXY config caches via FastRaid
# transparently (see docs/context/runner-vm-setup.md Gotcha #6).
NODE_IMAGE: node:20-slim
BUILDER_IMAGE: hexpm/elixir:1.17.3-erlang-27.1.2-debian-bookworm-20241202-slim
BUILDER_IMAGE: hexpm/elixir:1.17.3-erlang-27.3.4.14-debian-bookworm-20260623-slim
RUNNER_IMAGE: debian:bookworm-20241202-slim
ports:
- "${CI_ENGRAM_PORT:-8110}:4000"
Expand Down
2 changes: 1 addition & 1 deletion ci/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ services:
# ${LOCAL_REGISTRY} treats the proxy as a registry mirror, which it is
# not, and BuildKit fails with "unexpected media type / not found".
NODE_IMAGE: node:20-slim
BUILDER_IMAGE: hexpm/elixir:1.17.3-erlang-27.1.2-debian-bookworm-20241202-slim
BUILDER_IMAGE: hexpm/elixir:1.17.3-erlang-27.3.4.14-debian-bookworm-20260623-slim
RUNNER_IMAGE: debian:bookworm-20241202-slim
# LAN Hex pull-through (set by CI env; empty for local dev = upstream).
HEX_MIRROR: ${HEX_MIRROR:-}
Expand Down
2 changes: 1 addition & 1 deletion docs/context/ci-mix-compile-cache-runner-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Requires `fetch-depth: 0` on the checkout step — shallow clone (`fetch-depth:

**2. Docker-wrap the compile** (the fix that actually matters — addresses the absolute-path invalidation):

Run `mix local.hex`/`mix local.rebar`/`mix deps.get`/`mix deps.compile`/`mix compile` inside `MIX_BUILDER_IMAGE` (the same `hexpm/elixir:1.17.3-erlang-27.1.2-debian-bookworm-20241202-slim` the release Dockerfile pins), bind-mounted via `docker run -v "$PWD:/app" -w /app`. A bind mount is a real mountpoint (unlike a symlink, which Erlang's `getcwd()` resolves through to the real, unstable path) — `/app` resolves identically via `getcwd()` on every runner, so the compile manifest's embedded project root is always the same string regardless of which of the 7 runners lands the job. This is exactly the mechanism that already makes `prebuild-ci-image` immune to this bug.
Run `mix local.hex`/`mix local.rebar`/`mix deps.get`/`mix deps.compile`/`mix compile` inside `MIX_BUILDER_IMAGE` (the same `hexpm/elixir:1.17.3-erlang-27.3.4.14-debian-bookworm-20260623-slim` the release Dockerfile pins), bind-mounted via `docker run -v "$PWD:/app" -w /app`. A bind mount is a real mountpoint (unlike a symlink, which Erlang's `getcwd()` resolves through to the real, unstable path) — `/app` resolves identically via `getcwd()` on every runner, so the compile manifest's embedded project root is always the same string regardless of which of the 7 runners lands the job. This is exactly the mechanism that already makes `prebuild-ci-image` immune to this bug.

**Reference the bare Docker Hub tag, not the `:5001` LAN registry mirror.** The `:5001` `LOCAL_REGISTRY` only actually holds the `engram-ci` images this workflow builds and pushes itself — `hexpm/elixir` was never pushed there despite `.github/setup-runner.sh` appearing to do so (confirmed live: pulling `10.0.20.214:5001/hexpm/elixir:...` failed with `manifest unknown`). Docker Hub pulls on this runner pool already transparently route through a caching proxy at `:5000` (`docs/context/runner-vm-setup.md` Gotcha #6), so the bare tag is both correct and already cache-accelerated — it's the same tag `prebuild-ci-image` pulls successfully via the Dockerfile's own `BUILDER_IMAGE` arg.

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Engram.MixProject do
def project do
[
app: :engram,
version: "0.5.649",
version: "0.5.651",
elixir: "~> 1.15",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
Expand Down
16 changes: 15 additions & 1 deletion rel/env.sh.eex
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,21 @@ if [ -n "$ECS_ENABLE_CLUSTER" ]; then
# first on a dual-stack host, and `hostname -I` also lists the 169.254.x
# ECS task-metadata address — both would break node-name matching. Take the
# first non-link-local IPv4 from the full address list instead.
_eni_ipv4="$(hostname -I | awk '{for (i = 1; i <= NF; i++) if ($i ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ && $i !~ /^169\.254\./) { print $i; exit }}')"
# Under boot pressure `hostname -I` can transiently return nothing (#966:
# tasks booted undistributed during the Jul 3 churn window). Retry briefly,
# then fail loudly — an undistributed boot is invisible forever, a failed
# boot gets replaced by ECS.
_eni_ipv4=""
for _try in 1 2 3 4 5; do
_eni_ipv4="$(hostname -I | awk '{for (i = 1; i <= NF; i++) if ($i ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ && $i !~ /^169\.254\./) { print $i; exit }}')"
[ -n "$_eni_ipv4" ] && break
echo "rel/env.sh: no ENI IPv4 yet (attempt ${_try}/5), retrying" >&2
sleep 1
done
if [ -z "$_eni_ipv4" ]; then
echo "rel/env.sh: FATAL: no ENI IPv4 for RELEASE_NODE; refusing undistributed boot" >&2
exit 1
fi
export RELEASE_NODE="engram@${_eni_ipv4}"
fi

Expand Down
Loading