Add shared Erlang builder/runtime base images from registry.
CI / test (push) Successful in 7m42s

Publish erlang-builder and erlang-runtime as :latest, use them in prod and API test builds, auto-collect NIF libs, and sync CI to pull/push bases before eventhub build.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-11 12:25:42 +03:00
parent 14c0ac9220
commit e8464b3a8b
9 changed files with 228 additions and 42 deletions
+5 -11
View File
@@ -1,21 +1,15 @@
# ============================================================
# Одноэтапный Dockerfile
# ============================================================
FROM erlang:28-alpine
# API common_test — только builder-стадия (полный OTP + компиляторы).
ARG ERLANG_BUILDER_IMAGE=git.sabilin.com/eventhub/erlang-builder:latest
FROM ${ERLANG_BUILDER_IMAGE}
# Устанавливаем инструменты для сборки и runtime-зависимости
RUN apk add \
make musl-dev \
rust cargo openssl-dev libsodium-dev
WORKDIR /app
# Копируем конфигурацию и исходники
COPY rebar.config ./
COPY include/ include/
COPY src/ src/
COPY test/api_*_SUITE.erl test/
COPY test/api/ test/api/
# Компилируем и запускаем тесты
RUN rebar3 compile
CMD rebar3 ct --sname ci_api_test -v
CMD ["rebar3", "ct", "--sname", "ci_api_test", "-v"]
+19 -22
View File
@@ -1,12 +1,12 @@
# EventHub production image (multi-stage).
# Требует erlang-builder / erlang-runtime — см. scripts/build-erlang-base-images.sh
ARG ERLANG_BUILDER_IMAGE=git.sabilin.com/eventhub/erlang-builder:latest
ARG ERLANG_RUNTIME_IMAGE=git.sabilin.com/eventhub/erlang-runtime:latest
# ============================================================
# Этап 1: Сборка
# ============================================================
FROM erlang:28-alpine AS builder
# RUN apk add --no-cache \
RUN apk add \
git curl make gcc musl-dev \
rust cargo openssl-dev libsodium-dev
FROM ${ERLANG_BUILDER_IMAGE} AS builder
WORKDIR /app
COPY rebar.config ./
@@ -16,38 +16,35 @@ RUN rebar3 get-deps
COPY include/ include/
COPY src/ src/
# Копируем sys.config из src/config/ в config/
COPY src/config/sys.config ./config/sys.config
COPY src/config/vm.args ./config/vm.args
COPY docker/scripts/collect-runtime-libs.sh /usr/local/bin/collect-runtime-libs.sh
RUN chmod +x /usr/local/bin/collect-runtime-libs.sh
RUN rebar3 as prod release
RUN rebar3 as prod tar
RUN mkdir -p /app/release && \
tar -xzf _build/prod/rel/eventhub/eventhub-*.tar.gz -C /app/release
# NIF (argon2 → libsodium/openssl): ldd + копия .so с builder (ABI = Alpine builder)
RUN collect-runtime-libs.sh /app/release /opt/runtime-libs
# ============================================================
# Этап 2: Финальный образ
# ============================================================
FROM alpine:3.20
FROM ${ERLANG_RUNTIME_IMAGE}
# RUN apk add --no-cache \
RUN apk add \
openssl libstdc++ libgcc ncurses-libs libsodium
COPY --from=builder /app/release /app
COPY --from=builder /usr/lib/libcrypto.* /usr/lib/
COPY --from=builder /usr/lib/libssl.* /usr/lib/
# Доп. .so, если версия apk-openssl на runtime не совпала с builder (страховка)
COPY --from=builder /opt/runtime-libs/ /
RUN mkdir -p /app/data && chmod 777 /app/data
COPY docker/scripts/verify-native-libs.sh /usr/local/bin/verify-native-libs.sh
RUN chmod +x /usr/local/bin/verify-native-libs.sh \
&& verify-native-libs.sh /app
WORKDIR /app
EXPOSE 8080 8081 8445 8446
ENV PATH="/app/erts-16.3.1/bin:$PATH"
ENV RELX_REPLACE_OS_VARS=true
CMD /app/bin/eventhub foreground
# COPY docker/entrypoint.sh /app/entrypoint.sh
# RUN chmod +x /app/entrypoint.sh
#
# ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["/app/bin/eventhub", "foreground"]
+3
View File
@@ -1,3 +1,6 @@
# Базовые Erlang-образы из registry (:latest) или локальная сборка
bash scripts/build-erlang-base-images.sh
# Основной образ EventHub (единственный для нод)
docker build -t eventhub:latest -f docker/Dockerfile .
+11
View File
@@ -0,0 +1,11 @@
# EventHub — builder: OTP 28 + toolchain для rebar3 release и CT.
# erlang:28-alpine ≈ Alpine 3.23 — версия должна совпадать с Dockerfile.runtime (ALPINE_VERSION).
# Публикуется как git.sabilin.com/eventhub/erlang-builder:latest
FROM erlang:28-alpine
RUN apk add --no-cache \
git curl make gcc musl-dev \
rust cargo openssl-dev libsodium-dev \
file
WORKDIR /build
+13
View File
@@ -0,0 +1,13 @@
# EventHub — runtime: libs для relx-release (ERTS внутри release).
# ALPINE_VERSION MUST match erlang:28-alpine (сейчас 3.23).
# Публикуется как git.sabilin.com/eventhub/erlang-runtime:latest
ARG ALPINE_VERSION=3.23
FROM alpine:${ALPINE_VERSION}
RUN apk add --no-cache \
openssl libstdc++ libgcc ncurses-libs libsodium \
file \
&& mkdir -p /app/data \
&& chmod 777 /app/data
WORKDIR /app
+48
View File
@@ -0,0 +1,48 @@
#!/bin/sh
# Собирает .so, нужные NIF/priv из release (ldd), для runtime-слоя.
# Исключает musl/libc — их даёт базовый alpine-образ.
# Usage: collect-runtime-libs.sh <release_dir> <output_root>
set -eu
RELEASE="${1:?release_dir}"
OUT="${2:?output_root}"
mkdir -p "${OUT}"
is_base_lib() {
case "$1" in
/lib/ld-musl-*|*/ld-musl-*|*/libc.musl-*) return 0 ;;
esac
return 1
}
copy_lib() {
lib="$1"
[ -e "${lib}" ] || return 0
is_base_lib "${lib}" && return 0
dest="${OUT}${lib}"
mkdir -p "$(dirname "${dest}")"
if [ -L "${lib}" ]; then
cp -a "${lib}" "${dest}"
else
cp -L "${lib}" "${dest}" 2>/dev/null || cp "${lib}" "${dest}"
fi
}
# shellcheck disable=SC2044
for so in $(find "${RELEASE}" -name '*.so' 2>/dev/null); do
ldd "${so}" 2>/dev/null | while read -r line; do
case "${line}" in
*'=>'*)
lib=$(echo "${line}" | awk '{print $3}')
[ -n "${lib}" ] && copy_lib "${lib}"
;;
/lib/*|/usr/lib/*)
lib=$(echo "${line}" | awk '{print $1}')
copy_lib "${lib}"
;;
esac
done
done
echo "collect-runtime-libs: $(find "${OUT}" -name '*.so*' 2>/dev/null | wc -l) files under ${OUT}"
+23
View File
@@ -0,0 +1,23 @@
#!/bin/sh
# Падает, если у .so из release есть unresolved ldd-зависимости.
# Usage: verify-native-libs.sh <release_dir>
set -eu
RELEASE="${1:?release_dir}"
failed=0
# shellcheck disable=SC2044
for so in $(find "${RELEASE}" -name '*.so' 2>/dev/null); do
if ldd "${so}" 2>/dev/null | grep -q 'not found'; then
echo "ERROR: missing libs for ${so}:"
ldd "${so}" 2>/dev/null | grep 'not found' || true
failed=1
fi
done
if [ "${failed}" -ne 0 ]; then
echo "verify-native-libs: FAILED"
exit 1
fi
echo "verify-native-libs: OK"