Skip to content

Commit

Permalink
Rebuild image using wolfi
Browse files Browse the repository at this point in the history
This brings glibc and much improved performance.
  • Loading branch information
sando38 committed Apr 27, 2024
1 parent 820b3c9 commit c2c8173
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 97 deletions.
139 changes: 43 additions & 96 deletions image/24.02/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
#' Define default build variables
## specifc ARGs for METHOD='direct'
ARG OTP_VSN='25.3'
ARG ELIXIR_VSN='1.14.4'
## specifc ARGs for METHOD='package'
ARG ALPINE_VSN='3.17'
## specifc ARGs for elector
## source ARGs
ARG GO_VSN='1.22'
ARG ERLANG_VSN='25'
ARG ELIXIR_VSN='1.14.4'
## general ARGs
ARG VARIANT='hardened'
ARG UID='9000'
ARG USER='ejabberd'
ARG HOME="opt/$USER"
ARG METHOD='direct'
ARG BUILD_DIR="/$USER"
ARG VERSION='master'

################################################################################
#' METHOD='direct' - build and install ejabberd directly from source
#' build elector
FROM docker.io/golang:${GO_VSN}-alpine AS elector
RUN apk -U add --no-cache \
build-base \
Expand All @@ -29,33 +24,40 @@ RUN git clone https://github.com/sando38/k8s-elector \
RUN make build-linux

################################################################################
#' METHOD='direct' - build and install ejabberd directly from source
FROM docker.io/erlang:${OTP_VSN}-alpine AS direct
#' Build and prepare ejabberd
FROM cgr.dev/chainguard/wolfi-base AS build
ARG ERLANG_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 \
curl \
erlang-$ERLANG_VSN \
erlang-$ERLANG_VSN-dev \
expat-dev \
file \
gd-dev \
git \
jpeg-dev \
libjpeg-dev \
libpng-dev \
libwebp-dev \
linux-pam-dev \
pax-utils \
openssl-dev \
sqlite-dev \
wget \
yaml-dev \
zlib-dev

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 \
Expand All @@ -75,7 +77,6 @@ RUN git clone https://github.com/processone/ejabberd-contrib --depth 1 . \
&& rm -rf mod_ecaptcha mod_http_redirect mod_s3_upload

WORKDIR $BUILD_DIR

RUN mv .github/container/ejabberdctl.template . \
&& ./autogen.sh \
&& ./configure --with-rebar=mix --enable-all \
Expand All @@ -86,7 +87,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
Expand All @@ -99,28 +100,6 @@ RUN wget -O "$HOME/conf/cacert.pem" 'https://curl.se/ca/cacert.pem' \
\nca_file: /opt/ejabberd/conf/cacert.pem \
\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/
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

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

WORKDIR /rootfs
ARG HOME
RUN mkdir -p usr/local/bin $HOME/conf $HOME/database $HOME/logs $HOME/upload

ARG BUILD_DIR
Expand Down Expand Up @@ -153,86 +132,54 @@ 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 "$home_root_dir" \
| 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|" \
> /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) \
gettext \
jq \
so:libcap.so.2 \
so:libtdsodbc.so.0 \
tini \
&& ln -fs /usr/lib/libtdsodbc.so.0 /usr/lib/libtdsodbc.so
#' Get AlpineÄs busybox for ejabberdctl script
FROM cgr.dev/chainguard/wolfi-base AS runtime
RUN apk -U upgrade --available --no-cache

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

COPY --from=runtime / /
COPY --from=ejabberd /rootfs /
COPY --from=elector /elector/elector /usr/local/bin/elector
COPY --from=build /tmp/runDeps /tmp/runDeps
RUN apk add --no-cache -t .ejabberd-rundeps \
$(cat /tmp/runDeps) \
busybox \
ca-certificates-bundle \
gettext \
jq \
tini

################################################################################
#' Remove unneccessary packages from runtime environment
FROM runtime AS runtime-hardened
# we need busybox' 'ash', which became a sub-package in alpine 3.17
RUN check=$(printf "$(cat /etc/alpine-release)\n3.17" | sort -V | head -n1) \
&& if [ "$check" = '3.17' ]; then sub='-binsh'; fi \
&& apk add --no-cache \
busybox${sub} \
ca-certificates
RUN apk del --repositories-file /dev/null \
alpine-baselayout \
alpine-keys \
wolfi-base \
wolfi-keys \
apk-tools \
libc-utils \
&& rm -rf /var/cache/apk /etc/apk /tmp \
&& rm -rf /var/cache/apk /etc/apk /tmp/* \
&& find /lib/apk/db -type f -not -name 'installed' -delete

################################################################################
#' Build together hardened production image
FROM scratch AS hardened

COPY --from=runtime-hardened / /
COPY --from=ejabberd /rootfs /
COPY --from=elector /elector/elector /usr/local/bin/elector

################################################################################
#' Build together production image
FROM ${VARIANT} AS final
#' Forge release image
FROM scratch AS release
ARG USER
ARG HOME
ENV ERL_DIST_PORT='5210' \
LC_ALL='C.UTF-8' \
LANG='C.UTF-8'

COPY --from=runtime / /
COPY --from=build /rootfs /
COPY --from=elector /elector/elector /usr/local/bin/elector

HEALTHCHECK \
--interval=1m \
Expand All @@ -244,7 +191,7 @@ HEALTHCHECK \
WORKDIR /$HOME
USER $USER
VOLUME ["/$HOME"]
EXPOSE 1883 4369-4399 5210 5222 5269 5280 5443
EXPOSE 5210 5222 5223 5280

ENTRYPOINT ["/sbin/tini","--","ejabberdctl"]
CMD ["foreground"]
2 changes: 1 addition & 1 deletion image/tag
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# -k8sX specifies the image release, new releases have a higher ordinal number
# changes in this file trigger a rebuild of the container image

24.02-k8s2
24.02-k8s3

0 comments on commit c2c8173

Please sign in to comment.