Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dockerfile] Switch to wolfi/glibc based image #4261

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
133 changes: 72 additions & 61 deletions .github/container/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#' Define default build variables
## specifc ARGs for METHOD='direct'
ARG OTP_VSN='26.2'
ARG ELIXIR_VSN='1.16.2'
## specifc ARGs for METHOD='package'
ARG ALPINE_VSN='3.19'
## source ARGs
ARG OTP_VSN='27'
ARG ELIXIR_VSN='1.17.2'
## general ARGs
ARG UID='9000'
ARG USER='ejabberd'
Expand All @@ -13,38 +11,60 @@ ARG BUILD_DIR="/$USER"
ARG VERSION='master'

################################################################################
#' METHOD='direct' - build and install ejabberd directly from source
FROM docker.io/erlang:${OTP_VSN}-alpine AS direct
#' Build and base image
FROM cgr.dev/chainguard/wolfi-base AS erlang
ARG OTP_VSN
ENV LC_ALL='C.UTF-8' \
LANG='C.UTF-8'

RUN apk -U add --no-cache \
RUN apk -U upgrade --available && apk add --no-cache \
autoconf \
automake \
bash \
build-base \
ca-certificates-bundle \
curl \
expat-dev \
erlang-$OTP_VSN \
erlang-$OTP_VSN-dev \
erlang-$OTP_VSN-odbc \
file \
freetds freetds-dev \
freetype-dev \
gd-dev \
git \
jpeg-dev \
libjpeg-dev \
libpng-dev \
libwebp-dev \
linux-pam-dev \
ncurses-dev \
pax-utils \
perl-dev \
openssl \
openssl-dev \
sqlite-dev \
unixodbc unixodbc-dev \
wget \
yaml-dev \
zlib-dev

WORKDIR /
ARG ELIXIR_VSN
RUN wget -O - https://github.com/elixir-lang/elixir/archive/v$ELIXIR_VSN.tar.gz \
RUN wget -O - https://github.com/elixir-lang/elixir/archive/v"$ELIXIR_VSN".tar.gz \
| tar -xzf -

WORKDIR elixir-$ELIXIR_VSN
WORKDIR /elixir-"$ELIXIR_VSN"
RUN make install clean

RUN mix local.hex --force \
&& mix local.rebar --force

################################################################################
#' Build and prepare ejabberd
FROM erlang AS direct
ENV LC_ALL='C.UTF-8' \
LANG='C.UTF-8'

ARG BUILD_DIR
COPY / $BUILD_DIR/

Expand All @@ -59,38 +79,51 @@ WORKDIR /rootfs
ARG VERSION
ARG HOME
RUN mkdir -p $HOME $HOME-$VERSION \
&& cp -r $BUILD_DIR/_build/prod/rel/ejabberd/* $HOME-$VERSION \
&& cp -r $BUILD_DIR/_build/prod/rel/ejabberd/* $HOME-$VERSION \
&& mv $HOME-$VERSION/conf $HOME/conf

RUN cp -p $BUILD_DIR/tools/captcha*.sh $HOME-$VERSION/lib

RUN find "$HOME-$VERSION/bin" -name 'ejabberd' -delete \
&& find "$HOME-$VERSION/releases" -name 'COOKIE' -delete

RUN wget -O "$HOME/conf/cacert.pem" 'https://curl.se/ca/cacert.pem' \
&& sed -i '/^loglevel:/a \ \
\nca_file: /opt/ejabberd/conf/cacert.pem \
RUN sed -i '/^loglevel:/a \ \
\ncertfiles: \
\n - /opt/ejabberd/conf/server.pem' "$HOME/conf/ejabberd.yml"

################################################################################
#' METHOD='package' - install ejabberd from binary tarball package
FROM docker.io/alpine:${ALPINE_VSN} AS package
COPY tarballs/ejabberd-*-linux-musl-*.tar.gz /tmp/
FROM cgr.dev/chainguard/wolfi-base AS package
COPY tarballs/ejabberd-*-linux-gnu-*.tar.gz /tmp/
WORKDIR /rootfs
ARG HOME
RUN home_root_dir=$(echo $HOME | sed 's|\(.*\)/.*|\1 |') \
&& mkdir -p $home_root_dir \
&& ARCH=$(uname -m | sed -e 's/x86_64/x64/;s/aarch64/arm64/') \
&& tar -xzf /tmp/ejabberd-*-linux-musl-$ARCH.tar.gz -C $home_root_dir
&& tar -xzf /tmp/ejabberd-*-linux-gnu-$ARCH.tar.gz -C $home_root_dir

################################################################################
#' OpenSSL - Create server certificate for localhost,
# because wolfi misses openssl config file
FROM docker.io/library/alpine AS servercert
RUN apk -U add --no-cache openssl
RUN export PEM=/tmp/server.pem \
&& openssl req -x509 \
-batch \
-nodes \
-newkey rsa:4096 \
-keyout $PEM \
-out $PEM \
-days 3650 \
-subj "/CN=localhost"

################################################################################
#' Prepare ejabberd for runtime
FROM ${METHOD} AS ejabberd
RUN apk -U add --no-cache \
git \
libcap \
openssl
libcap-utils \
pax-utils

WORKDIR /rootfs
ARG HOME
Expand All @@ -106,15 +139,7 @@ RUN if [ ! -d $HOME/.ejabberd-modules ]; \
fi \
fi

RUN export PEM=$HOME/conf/server.pem \
&& openssl req -x509 \
-batch \
-nodes \
-newkey rsa:4096 \
-keyout $PEM \
-out $PEM \
-days 3650 \
-subj "/CN=localhost"
COPY --from=servercert /tmp/server.pem $HOME/conf/server.pem

RUN home_root_dir=$(echo $HOME | sed 's|\(.*\)/.*|\1 |') \
&& setcap 'cap_net_bind_service=+ep' $(find $home_root_dir -name beam.smp) \
Expand All @@ -127,55 +152,41 @@ RUN home_root_dir=$(echo $HOME | sed 's|\(.*\)/.*|\1 |') \
\nexec /$(find $home_root_dir -name ejabberdctl) \"\$@\"" \
> usr/local/bin/ejabberdctl \
&& chmod +x usr/local/bin/* \
&& scanelf --needed --nobanner --format '%n#p' --recursive $home_root_dir \
&& scanelf --needed --nobanner --format '%n#p' --recursive "$PWD" \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e $home_root_dir" $1 " ]") == 0 { next } { print "so:" $1 }' \
| sed -e "s|so:libc.so|so:libc.musl-$(uname -m).so.1|" \
| awk 'system("[ -e $PWD" $1 " ]") == 0 { next } { print "so:" $1 }' \
> /tmp/runDeps

ARG UID
RUN chown -R $UID:$UID $HOME

################################################################################
#' METHOD='direct' - Remove erlang/OTP & rebar3
FROM docker.io/erlang:${OTP_VSN}-alpine AS runtime-direct
RUN apk del .erlang-rundeps \
&& rm -f $(which rebar3) \
&& find /usr -type d -name 'erlang' -exec rm -rf {} + \
&& find /usr -type l -exec test ! -e {} \; -delete

################################################################################
#' METHOD='package' - define runtime base image
FROM docker.io/alpine:${ALPINE_VSN} AS runtime-package

################################################################################
#' Update alpine, finalize runtime environment
FROM runtime-${METHOD} AS runtime
COPY --from=ejabberd /tmp/runDeps /tmp/runDeps
RUN apk -U upgrade --available --no-cache \
&& apk add --no-cache \
$(cat /tmp/runDeps) \
so:libcap.so.2 \
so:libtdsodbc.so.0 \
tini \
&& ln -fs /usr/lib/libtdsodbc.so.0 /usr/lib/libtdsodbc.so

#' Build release image
FROM cgr.dev/chainguard/wolfi-base AS release
ARG USER
ARG UID
ARG HOME
RUN addgroup $USER -g $UID \
&& adduser -s /sbin/nologin -D -u $UID -h /$HOME -G $USER $USER

################################################################################
#' Build together production image
FROM scratch AS prod
ARG USER
ARG HOME
COPY --from=ejabberd /tmp/runDeps /tmp/runDeps
RUN apk -U upgrade --available --no-cache \
&& apk add --no-cache -t .ejabberd-rundeps \
$(cat /tmp/runDeps) \
freetds \
unixodbc \
libcap \
busybox \
ca-certificates-bundle \
tini

COPY --from=runtime / /
COPY --from=ejabberd /rootfs /

ENV ERL_DIST_PORT='5210' \
LC_ALL='C.UTF-8' \
LANG='C.UTF-8'

HEALTHCHECK \
--interval=1m \
--timeout=5s \
Expand Down
66 changes: 11 additions & 55 deletions .github/workflows/container.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
name: Container

on:
schedule:
- cron: '22 2 */6 * *' # every 6 days to avoid gha cache being evicted
push:
paths-ignore:
- '.devcontainer/**'
- 'examples/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
workflow_run:
workflows: [Installers]
types:
- completed
branches: [master]

env:
REGISTRY: ghcr.io
Expand All @@ -27,52 +22,13 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Cache build directory
uses: actions/cache@v4
with:
path: ~/build/
key: ${{runner.os}}-ctr-ct-ng-1.26.0

- name: Get erlang/OTP version for bootstrapping
run: |
echo "OTP_VSN=$(awk '/^otp_vsn=/ {{gsub(/[^0-9.rc-]/, ""); print}}' tools/make-binaries)" >> $GITHUB_ENV
echo "ELIXIR_VSN=$(awk '/^elixir_vsn=/ {{gsub(/[^0-9.]/, ""); print}}' tools/make-binaries)" >> $GITHUB_ENV

- name: Install prerequisites
run: |
sudo apt-get -qq update
sudo apt-get -qq install makeself
# https://github.com/crosstool-ng/crosstool-ng/blob/master/testing/docker/ubuntu21.10/Dockerfile
sudo apt-get -qq install build-essential autoconf bison flex gawk
sudo apt-get -qq install help2man libncurses5-dev libtool libtool-bin
sudo apt-get -qq install python3-dev texinfo unzip

- name: Install erlang/OTP
uses: erlef/setup-beam@v1
-
name: Download digests
uses: actions/download-artifact@v4
with:
otp-version: ${{ env.OTP_VSN }}
elixir-version: ${{ env.ELIXIR_VSN }}
version-type: strict

- name: Remove Elixir Matchers
run: |
echo "::remove-matcher owner=elixir-mixCompileWarning::"
echo "::remove-matcher owner=elixir-credoOutputDefault::"
echo "::remove-matcher owner=elixir-mixCompileError::"
echo "::remove-matcher owner=elixir-mixTestFailure::"
echo "::remove-matcher owner=elixir-dialyzerOutputDefault::"

- name: Build musl-libc based binary archives
run: |
sed -i "s|targets='.*'|targets='x86_64-linux-musl aarch64-linux-musl'|" tools/make-binaries
mv .github/container/ejabberdctl.template .
CHECK_DEPS=false tools/make-binaries

- name: Collect packages
run: |
mkdir tarballs
mv ejabberd-*.tar.gz tarballs
path: tarballs
pattern: ejabberd-tarballs
merge-multiple: true

- name: Checkout ejabberd-contrib
uses: actions/checkout@v4
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/installers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ jobs:
#
path: ejabberd-packages*
retention-days: 14
- name: Collect binary tarballs
run: |
mkdir tarballs
mv ejabberd-*.tar.gz tarballs
- name: Upload binary tarballs
uses: actions/upload-artifact@v4
with:
name: ejabberd-tarballs
#
# Appending the wildcard character ("*") is a trick to make
# "ejabberd-packages" the root directory of the uploaded ZIP file:
#
# https://github.com/actions/upload-artifact#upload-using-multiple-paths-and-exclusions
#
path: tarballs*
retention-days: 14

release:
name: Release
Expand Down