mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
Feel free to correct me if I'm wrong but it seems the telemetry id is not longer used in Firezone 1.x Removing this uuid generation would allow me to put the folder `/var/firezone` as readonly instead of mounting a [volume](367a46a5c8/firezone/values.yaml (L157)) to allow firezone to write inside. The folder `/var/firezone` seems to be used only for this purpose Maybe I should also remove [this](49a965a686/elixir/Dockerfile (L293)) ? PS: I cannot find the contrib branch, but don't hesite to create it and change the target branch of this PR Co-authored-by: Antoine <antoinelabarussias@gmail.com>
321 lines
9.7 KiB
Docker
321 lines
9.7 KiB
Docker
ARG ALPINE_VERSION="3.19.1"
|
|
ARG ERLANG_VERSION="26.2.2"
|
|
ARG ERLANG_DOWNLOAD_SHA256="d537ff4ac5d8c1cb507aedaf7198fc1f155ea8aa65a8d83edb35c2802763cc28"
|
|
ARG ELIXIR_VERSION="1.16.2"
|
|
ARG ELIXIR_DOWNLOAD_SHA256="f53d06f3e4041c50e65b750e5d56fec9cc7c6a44510786937c6a5bb0666a7207"
|
|
|
|
FROM alpine:${ALPINE_VERSION} as base
|
|
|
|
# Important! Update this no-op ENV variable when this Dockerfile
|
|
# is updated with the current date. It will force refresh of all
|
|
# of the base images and things like `apk add` won't be using
|
|
# old cached versions when the Dockerfile is built.
|
|
ENV REFRESHED_AT=2023-10-05 \
|
|
LANG=C.UTF-8 \
|
|
HOME=/app/ \
|
|
TERM=xterm
|
|
|
|
# Add tagged repos as well as the edge repo so that we can selectively install edge packages
|
|
ARG ALPINE_VERSION
|
|
RUN set -xe \
|
|
&& ALPINE_MINOR_VERSION=$(echo ${ALPINE_VERSION} | cut -d'.' -f1,2) \
|
|
&& echo "@main http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_MINOR_VERSION}/main" >> /etc/apk/repositories \
|
|
&& echo "@community http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_MINOR_VERSION}/community" >> /etc/apk/repositories \
|
|
&& echo "@edge http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories
|
|
|
|
RUN set -xe \
|
|
# Upgrade Alpine and base packages
|
|
&& apk --no-cache --update-cache --available upgrade \
|
|
# Install bash, Erlang/OTP and Elixir runtime dependencies
|
|
&& apk add --no-cache --update-cache \
|
|
bash \
|
|
libstdc++ \
|
|
ca-certificates \
|
|
ncurses \
|
|
openssl \
|
|
pcre \
|
|
unixodbc \
|
|
zlib \
|
|
# Update ca certificates
|
|
&& update-ca-certificates --fresh
|
|
|
|
FROM base AS build_erlang
|
|
|
|
# Install bash and Erlang/OTP deps
|
|
RUN set -xe \
|
|
&& apk add --no-cache --update-cache --virtual .fetch-deps \
|
|
curl \
|
|
libgcc \
|
|
lksctp-tools \
|
|
zlib-dev
|
|
|
|
# Install Erlang/OTP build deps
|
|
RUN set -xe \
|
|
&& apk add --no-cache --virtual .build-deps \
|
|
dpkg-dev \
|
|
dpkg \
|
|
gcc \
|
|
g++ \
|
|
libc-dev \
|
|
linux-headers \
|
|
make \
|
|
autoconf \
|
|
ncurses-dev \
|
|
openssl-dev \
|
|
unixodbc-dev \
|
|
lksctp-tools-dev \
|
|
tar
|
|
|
|
# Download OTP
|
|
ARG ERLANG_VERSION
|
|
ARG ERLANG_DOWNLOAD_SHA256
|
|
WORKDIR /tmp/erlang-build
|
|
RUN set -xe \
|
|
&& curl -fSL -o otp-src.tar.gz "https://github.com/erlang/otp/releases/download/OTP-${ERLANG_VERSION}/otp_src_${ERLANG_VERSION}.tar.gz" \
|
|
&& tar -xzf otp-src.tar.gz -C /tmp/erlang-build --strip-components=1 \
|
|
# && sha256sum otp-src.tar.gz && exit 1 \
|
|
&& echo "${ERLANG_DOWNLOAD_SHA256} otp-src.tar.gz" | sha256sum -c -
|
|
|
|
# Configure & Build
|
|
RUN set -xe \
|
|
&& export ERL_TOP=/tmp/erlang-build \
|
|
&& export CPPFLAGS="-D_BSD_SOURCE $CPPFLAGS" \
|
|
&& export gnuArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)" \
|
|
&& ./configure \
|
|
--build="$gnuArch" \
|
|
--prefix=/usr/local \
|
|
--sysconfdir=/etc \
|
|
--mandir=/usr/share/man \
|
|
--infodir=/usr/share/info \
|
|
--without-javac \
|
|
--without-jinterface \
|
|
--without-wx \
|
|
--without-debugger \
|
|
--without-observer \
|
|
--without-cosEvent \
|
|
--without-cosEventDomain \
|
|
--without-cosFileTransfer \
|
|
--without-cosNotification \
|
|
--without-cosProperty \
|
|
--without-cosTime \
|
|
--without-cosTransactions \
|
|
--without-et \
|
|
--without-gs \
|
|
--without-ic \
|
|
--without-megaco \
|
|
--without-orber \
|
|
--without-percept \
|
|
--without-odbc \
|
|
--without-typer \
|
|
--enable-threads \
|
|
--enable-shared-zlib \
|
|
--enable-dynamic-ssl-lib \
|
|
--enable-ssl=dynamic-ssl-lib \
|
|
$(if [[ "${TARGET}" != *"amd64"* ]]; then echo "--disable-jit"; fi) \
|
|
&& $( \
|
|
if [[ "${TARGETARCH}" == *"amd64"* ]]; \
|
|
then export CFLAGS="-g -O2 -fstack-clash-protection -fcf-protection=full"; \
|
|
else export CFLAGS="-g -O2 -fstack-clash-protection"; fi \
|
|
) \
|
|
&& make -j$(getconf _NPROCESSORS_ONLN)
|
|
|
|
# Install to temporary location, strip the install, install runtime deps and copy to the final location
|
|
RUN set -xe \
|
|
&& make DESTDIR=/tmp install \
|
|
&& cd /tmp && rm -rf /tmp/erlang-build \
|
|
&& find /tmp/usr/local -regex '/tmp/usr/local/lib/erlang/\(lib/\|erts-\).*/\(man\|doc\|obj\|c_src\|emacs\|info\|examples\)' | xargs rm -rf \
|
|
&& find /tmp/usr/local -name src | xargs -r find | grep -v '\.hrl$' | xargs rm -v || true \
|
|
&& find /tmp/usr/local -name src | xargs -r find | xargs rmdir -vp || true \
|
|
# Strip install to reduce size
|
|
&& scanelf --nobanner -E ET_EXEC -BF '%F' --recursive /tmp/usr/local | xargs -r strip --strip-all \
|
|
&& scanelf --nobanner -E ET_DYN -BF '%F' --recursive /tmp/usr/local | xargs -r strip --strip-unneeded \
|
|
&& runDeps="$( \
|
|
scanelf --needed --nobanner --format '%n#p' --recursive /tmp/usr/local \
|
|
| tr ',' '\n' \
|
|
| sort -u \
|
|
| awk 'system("[ -e /tmp/usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
|
)" \
|
|
&& ln -s /tmp/usr/local/lib/erlang /usr/local/lib/erlang \
|
|
&& /tmp/usr/local/bin/erl -eval "beam_lib:strip_release('/tmp/usr/local/lib/erlang/lib')" -s init stop > /dev/null \
|
|
&& (/usr/bin/strip /tmp/usr/local/lib/erlang/erts-*/bin/* || true) \
|
|
&& apk add --no-cache --virtual .erlang-runtime-deps $runDeps lksctp-tools ca-certificates
|
|
|
|
# Cleanup after Erlang install
|
|
RUN set -xe \
|
|
&& apk del .fetch-deps .build-deps \
|
|
&& rm -rf /var/cache/apk/*
|
|
|
|
WORKDIR ${HOME}
|
|
|
|
CMD ["erl"]
|
|
|
|
FROM base AS build_elixir
|
|
|
|
# Install Elixir build deps
|
|
RUN set -xe \
|
|
&& apk add --no-cache --virtual .build-deps \
|
|
make \
|
|
curl \
|
|
tar \
|
|
git
|
|
|
|
# Download Elixir
|
|
ARG ELIXIR_VERSION
|
|
ARG ELIXIR_DOWNLOAD_SHA256
|
|
WORKDIR /tmp/elixir-build
|
|
RUN set -xe \
|
|
&& curl -fSL -o elixir-src.tar.gz "https://github.com/elixir-lang/elixir/archive/refs/tags/v${ELIXIR_VERSION}.tar.gz" \
|
|
&& mkdir -p /tmp/usr/local/src/elixir \
|
|
&& tar -xzC /tmp/usr/local/src/elixir --strip-components=1 -f elixir-src.tar.gz \
|
|
# && sha256sum elixir-src.tar.gz && exit 1 \
|
|
&& echo "${ELIXIR_DOWNLOAD_SHA256} elixir-src.tar.gz" | sha256sum -c - \
|
|
&& rm elixir-src.tar.gz
|
|
|
|
COPY --from=build_erlang /tmp/usr/local /usr/local
|
|
|
|
# Compile Elixir
|
|
RUN set -xe \
|
|
&& cd /tmp/usr/local/src/elixir \
|
|
&& make DESTDIR=/tmp install clean \
|
|
&& find /tmp/usr/local/src/elixir/ -type f -not -regex "/tmp/usr/local/src/elixir/lib/[^\/]*/lib.*" -exec rm -rf {} + \
|
|
&& find /tmp/usr/local/src/elixir/ -type d -depth -empty -delete \
|
|
&& rm -rf /tmp/elixir-build \
|
|
&& apk del .build-deps
|
|
|
|
# Cleanup apk cache
|
|
RUN rm -rf /var/cache/apk/*
|
|
|
|
WORKDIR ${HOME}
|
|
|
|
CMD ["iex"]
|
|
|
|
FROM base as elixir
|
|
|
|
WORKDIR ${HOME}
|
|
|
|
# Copy Erlang/OTP and Elixir installations
|
|
COPY --from=build_erlang /tmp/usr/local /usr/local
|
|
COPY --from=build_elixir /tmp/usr/local /usr/local
|
|
|
|
# Install hex + rebar
|
|
RUN set -xe \
|
|
&& mix local.hex --force \
|
|
&& mix local.rebar --force
|
|
|
|
CMD ["bash"]
|
|
|
|
FROM elixir as compiler
|
|
|
|
WORKDIR /app
|
|
|
|
# Install build deps
|
|
RUN apk add --update --no-cache \
|
|
make \
|
|
git \
|
|
nodejs \
|
|
npm \
|
|
build-base
|
|
|
|
# Add pnpm
|
|
RUN npm i -g pnpm
|
|
|
|
# Copy only the files needed to fetch the dependencies,
|
|
# to leverage Docker layer cache for them
|
|
RUN echo "0.0.0" > VERSION
|
|
COPY mix.exs mix.lock ./
|
|
COPY apps/domain/mix.exs ./apps/domain/mix.exs
|
|
COPY apps/web/mix.exs ./apps/web/mix.exs
|
|
COPY apps/api/mix.exs ./apps/api/mix.exs
|
|
COPY config config
|
|
|
|
# Fetch and compile the dependencies
|
|
ARG MIX_ENV="prod"
|
|
RUN mix deps.get --only ${MIX_ENV}
|
|
RUN mix deps.compile --skip-umbrella-children
|
|
|
|
# Copy the files needed to fetch asset deps
|
|
COPY apps/web/assets/package.json ./apps/web/assets/
|
|
COPY apps/web/assets/pnpm-lock.yaml ./apps/web/assets/
|
|
|
|
# Install npm deps and assets pipeline
|
|
RUN cd apps/web \
|
|
&& mix assets.setup
|
|
|
|
# Tailwind needs assets and app directories to look for used classes,
|
|
# so we can't optimize further at this stage
|
|
COPY VERSION ./
|
|
COPY priv priv
|
|
COPY apps apps
|
|
|
|
# Install pipeline and compile assets for Web app
|
|
RUN cd apps/web \
|
|
&& mix assets.deploy
|
|
|
|
# Copy the rest of the application files and compile them
|
|
RUN mix compile
|
|
|
|
FROM elixir as builder
|
|
|
|
# Install build deps
|
|
RUN apk add --update --no-cache \
|
|
git
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy the compiled dependencies from the previous step
|
|
# leveraging the possible layer cache
|
|
COPY --from=compiler /app /app
|
|
|
|
COPY rel rel
|
|
|
|
ARG APPLICATION_NAME
|
|
ARG MIX_ENV="prod"
|
|
RUN mix release ${APPLICATION_NAME}
|
|
|
|
# start a new build stage so that the final image will only contain
|
|
# the compiled release and other runtime necessities
|
|
|
|
FROM base AS runtime
|
|
|
|
RUN set -xe \
|
|
# Install Firezone runtime deps
|
|
&& apk add --no-cache --update-cache \
|
|
curl \
|
|
tini
|
|
|
|
# Create default user and home directory, set owner to default
|
|
RUN set -xe \
|
|
&& mkdir -p /app \
|
|
&& adduser -s /bin/sh -u 1001 -G root -h /app -S -D default \
|
|
&& chown -R 1001:0 /app
|
|
|
|
WORKDIR /app
|
|
|
|
ARG APPLICATION_NAME
|
|
ENV APPLICATION_NAME=$APPLICATION_NAME
|
|
|
|
# Only copy the final release from the build stage
|
|
ARG MIX_ENV="prod"
|
|
COPY --from=builder /app/_build/${MIX_ENV}/rel/${APPLICATION_NAME} ./
|
|
|
|
# Change user to "default" to limit runtime privileges
|
|
USER default
|
|
|
|
# This is critical when you run this container in containers where
|
|
# running process would get a PID 1.
|
|
#
|
|
# BEAM is usually not started by itself but via some shell script (eg. the one generated by
|
|
# Elixir 1.9 releases or Distillery) and this script is not designed to become an init script
|
|
# for a Docker container and it DOES NOT reap zombie processes.
|
|
#
|
|
# So whenever a child process runs and terminates inside the same container it would result in memory and
|
|
# PID leak to a point where host VM would get unresponsive.
|
|
#
|
|
# A good example why you would start a process within container is the `ping` command for liveness probes.
|
|
# It starts a VM to issue an RPC command to a live node and then terminates, but would never be reaped.
|
|
#
|
|
# Tini would become an entrypoin script and would take care of zombie reaping no matter how you start the VM.
|
|
ENTRYPOINT ["/sbin/tini", "--"]
|
|
|
|
CMD bin/server
|