diff --git a/.dockerignore b/.dockerignore index 69bcc6f3..dc38c528 100644 --- a/.dockerignore +++ b/.dockerignore @@ -83,3 +83,5 @@ data/ configs/ k8s/ setup.sh +!scripts/fetch-cartridges.sh +!schemas/cartridge-v1.json diff --git a/container/Containerfile b/container/Containerfile index e457847a..0d8e32e5 100644 --- a/container/Containerfile +++ b/container/Containerfile @@ -24,7 +24,11 @@ ARG BOJ_CARTRIDGES_REPO=https://github.com/hyperpolymath/boj-server-cartridges.g FROM cgr.dev/chainguard/wolfi-base:latest AS zig-builder -RUN apk add --no-cache zig build-base git bash +RUN apk add --no-cache build-base git bash curl xz +# Pin Zig to the repo-declared version (.tool-versions: 0.15.1); wolfi apk zig rolls forward and breaks the build +RUN curl -fsSL https://ziglang.org/download/0.15.1/zig-x86_64-linux-0.15.1.tar.xz -o /tmp/zig.tar.xz \ + && mkdir -p /opt/zig && tar -xJf /tmp/zig.tar.xz -C /opt/zig --strip-components=1 +ENV PATH=/opt/zig:${PATH} WORKDIR /build @@ -59,7 +63,10 @@ RUN for ffi_dir in /build/cartridges/*/ffi; do \ # Stage 2: Elixir Release Builder # ============================================================================ -FROM cgr.dev/chainguard/elixir:latest AS mix-builder +# Strip Zig build caches (multi-GB, runtime-irrelevant) so the cartridge COPY into the runtime stage stays small +RUN find /build/cartridges -type d -name .zig-cache -prune -exec rm -rf {} + 2>/dev/null || true + +FROM docker.io/elixir:1.18.4-otp-25 AS mix-builder WORKDIR /build @@ -77,7 +84,7 @@ RUN mix release boj_rest # Stage 3: Runtime Image # ============================================================================ -FROM cgr.dev/chainguard/wolfi-base:latest +FROM docker.io/debian:bullseye-slim # OCI labels LABEL org.opencontainers.image.title="Bundle of Joy Server" \ @@ -90,10 +97,10 @@ LABEL org.opencontainers.image.title="Bundle of Joy Server" \ dev.stapeln.compose="container/compose.toml" # Minimal runtime deps: OpenSSL (Elixir TLS), ncurses (Erlang), glibc (boj-invoke + .so) -RUN apk add --no-cache ca-certificates openssl ncurses-libs libstdc++ gcompat +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates openssl libncurses6 libstdc++6 && rm -rf /var/lib/apt/lists/* # Non-root user -RUN addgroup -S appuser && adduser -S appuser -G appuser +RUN groupadd -r appuser && useradd -r -g appuser -d /app appuser WORKDIR /app @@ -144,6 +151,10 @@ ENV PORT=7700 ENV MIX_ENV=prod VOLUME ["/data"] +# Cartridge schema mirror (Catalog validates cartridges against /schemas/cartridge-v1.json) +COPY schemas/cartridge-v1.json /app/schemas/cartridge-v1.json +COPY schemas/cartridge-v1.json /schemas/cartridge-v1.json + USER appuser EXPOSE 7700 diff --git a/elixir/config/runtime.exs b/elixir/config/runtime.exs new file mode 100644 index 00000000..99de7cd3 --- /dev/null +++ b/elixir/config/runtime.exs @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) Jonathan D.A. Jewell +import Config + +# Runtime configuration — evaluated at release BOOT, not compile time. Without this, +# a `mix release` bakes config.exs's env lookups at build time, so BOJ_BIND_IP / +# BOJ_PORT / BOJ_CARTRIDGES_ROOT set at `podman run` are ignored (the release keeps +# the build-time values: bind 127.0.0.1 unreachable via port-map, and a build-path +# cartridges_root that yields cartridges_loaded:0). Re-reading them here fixes both. +config :boj_rest, + port: String.to_integer(System.get_env("BOJ_PORT") || "7700"), + bind_ip: System.get_env("BOJ_BIND_IP") || "127.0.0.1", + cartridges_root: + System.get_env("BOJ_CARTRIDGES_ROOT") || + System.get_env("BOJ_CARTRIDGES_PATH") || + Path.expand("../../cartridges", __DIR__), + data_dir: System.get_env("BOJ_DATA_DIR") || "/data"