# syntax=docker/dockerfile:1 FROM ghcr.io/gleam-lang/gleam:v1.19.2-erlang AS build WORKDIR /build # Makes an amd64 build work on an arm64 host. BeamAsm dual-maps its JIT code # (executable + writable aliases of the same pages) and user-mode emulators # cannot track writes through the alias, so the BEAM crashes before it boots # (QEMU#1034; erlang/otp#10355 is the same thing reported against OTP 28 and # closed as unsupported, with this flag as the sanctioned answer). QEMU 8.1 # fixed the aarch64-guest direction only; amd64-on-arm64 stays broken, and # Rosetta has the same hole. Single-mapped RWX is a build-stage-only tradeoff; # the runtime stage keeps normal W^X. No effect on a native build. ENV ERL_FLAGS="+JMsingle true" RUN apt-get update \ && apt-get install -y --no-install-recommends make \ && rm -rf /var/lib/apt/lists/* # Keep this Bun tag matching lustre_dev_tools' pinned version. COPY --from=oven/bun:1.2.22 /usr/local/bin/bun /usr/local/bin/bun COPY web/package.json web/bun.lock web/ RUN cd web && bun install --frozen-lockfile COPY . . RUN make build RUN cd server && gleam export erlang-shipment FROM erlang:29-slim AS runtime WORKDIR /app # CA bundle for OTP ssl (outbound HTTPS to the PDS); curl for the healthcheck. RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl \ && rm -rf /var/lib/apt/lists/* COPY --from=build /build/server/build/erlang-shipment ./ COPY deploy/Caddyfile deploy/docker-compose.yml /app/deploy/ RUN useradd --system --no-create-home --uid 10001 app \ && chown -R app /app USER app EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD curl -fsS "http://localhost:${PORT:-8080}/readyz" || exit 1 # gleam's generated entrypoint puts SPDX headers above the shebang, so exec-form CMD gets ENOEXEC. CMD ["/bin/sh", "./entrypoint.sh", "run"]