diff --git a/.github/container/Dockerfile b/.github/container/Dockerfile index f9a97e0afdb..38199550074 100644 --- a/.github/container/Dockerfile +++ b/.github/container/Dockerfile @@ -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' @@ -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/ @@ -59,7 +79,7 @@ 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 @@ -67,30 +87,43 @@ 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 @@ -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) \ @@ -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 \ diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index 33ae16960a6..b5a72ab71a2 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -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 @@ -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 diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml index b820dd6d9e4..8891d08ff6a 100644 --- a/.github/workflows/installers.yml +++ b/.github/workflows/installers.yml @@ -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