balena-supervisor/Dockerfile.template
Felipe Lalanne 17aa625d3b Use single-arch in dockerfile
This is necessary since the builder no longer passes the platform flag
to the build. This would lead to dockerfiles that are mixing multi and single
arch stages to pull the wrong architecture images, particularly when
trying to build images in emulated builds (e.g. armv7hf built on aarch64).

Moving the full build to single-arch solves this as the docker engine is
capable of chosing the right architecture from the manifest. Once some
of the builder issues are fixed, we should move to 

Relates-to: 
Change-type: patch
2023-03-10 17:30:22 -03:00

211 lines
6.1 KiB
Docker

ARG ARCH=%%BALENA_ARCH%%
ARG FATRW_VERSION=0.2.9
FROM arm32v6/alpine:3.16 as alpine-rpi
FROM arm32v7/alpine:3.16 as alpine-armv7hf
FROM arm64v8/alpine:3.16 as alpine-aarch64
FROM amd64/alpine:3.16 as alpine-amd64
FROM i386/alpine:3.16 as alpine-i386
FROM arm32v6/alpine:3.11 as procmail-rpi
FROM arm32v7/alpine:3.11 as procmail-armv7hf
FROM arm64v8/alpine:3.11 as procmail-aarch64
FROM amd64/alpine:3.11 as procmail-amd64
FROM i386/alpine:3.11 as procmail-i386
###################################################
# Build the supervisor dependencies
###################################################
FROM balenalib/${ARCH}-alpine-node:16-run as build-base
ARG ARCH
ARG FATRW_VERSION
ARG FATRW_ARCHIVE="fatrw-${ARCH}.tar.gz"
ARG FATRW_LOCATION="https://github.com/balena-os/fatrw/releases/download/v${FATRW_VERSION}/${FATRW_ARCHIVE}"
WORKDIR /usr/src/app
RUN apk add --no-cache \
g++ \
make \
python3 \
libgcc \
libuv \
sqlite-dev \
dbus-dev
COPY package*.json ./
RUN strip /usr/local/bin/node
# Install fatrw
RUN curl -SLO "${FATRW_LOCATION}" && \
ls -la "${FATRW_ARCHIVE}" && \
tar -xzf "${FATRW_ARCHIVE}" -C /usr/local/bin && \
rm -f "${FATRW_ARCHIVE}"
# Just install dev dependencies first
RUN npm ci --build-from-source --sqlite=/usr/lib
###################################################################
# Journal access.
# The supervisor is built on an alpine image but still needs
# to use journalctl (from systemd) which cannot be built for
# musl. We hack around this by copying the binary and its library
# dependencies to the final image
###################################################################
FROM balenalib/${ARCH}-debian:bullseye-run as journal
RUN apt-get update && apt-get install -y --no-install-recommends systemd
COPY ./build-utils/setup-journal.sh /
RUN /setup-journal.sh
###################################################
# Extra dependencies. This uses alpine 3.11 as the
# procmail package was removed on 3.12
###################################################
FROM procmail-${ARCH} as extra
RUN apk add --update --no-cache procmail
###################################################
# Image with the final production dependencies.
# This image will also be be used for testing
###################################################
FROM alpine-${ARCH} as runtime-base
WORKDIR /usr/src/app
# We just need the node binary in the final image
COPY --from=build-base /usr/local/bin/node /usr/local/bin/node
# Also copy the fatrw binary
COPY --from=build-base /usr/local/bin/fatrw /usr/local/bin/fatrw
# Similarly, from the procmail package we just need the lockfile binary
COPY --from=extra /usr/bin/lockfile /usr/bin/lockfile
# Copy journalctl and library dependecies to the final image
COPY --from=journal /sysroot /
# Runtime dependencies
RUN apk add --no-cache \
ca-certificates \
iptables \
ip6tables \
rsync \
dbus \
libstdc++ \
dmidecode \
sqlite-libs
ARG ARCH
ARG VERSION=master
ENV CONFIG_MOUNT_POINT=/boot/config.json \
LED_FILE=/dev/null \
SUPERVISOR_IMAGE=balena/$ARCH-supervisor \
VERSION=$VERSION
###############################################################
# Use the base image to run integration tests and for livepush
###############################################################
FROM runtime-base as test
WORKDIR /usr/src/app
# Copy node install from the build folder
COPY --from=build-base /usr/local/bin /usr/local/bin
COPY --from=build-base /usr/local/lib/node_modules /usr/local/lib/node_modules
# Copy build dependencies
COPY --from=build-base /usr/src/app/package.json ./
COPY --from=build-base /usr/src/app/node_modules ./node_modules
# Run livepush here
#dev-copy=entry.sh .
#dev-cmd-live=LIVEPUSH=1 ./entry.sh
# Copy build files
COPY build-utils ./build-utils
COPY webpack.config.js tsconfig.json tsconfig.release.json tsconfig.js.json .mochapodrc.yml ./
COPY typings ./typings
COPY src ./src
COPY test ./test
# Run type checking and unit tests here
# to prevent setting up a test environment that will
# most likely fail.
RUN npm run test
# When running tests from a container built from this stage,
# skip the mocha-pod setup
ENV MOCHAPOD_SKIP_SETUP=1
# This command will be used by default when running integration tests
# from this stage
CMD npm run test:integration
###################################################
# Build the production package
###################################################
FROM build-base as build-prod
WORKDIR /usr/src/app
# Copy build files
COPY build-utils ./build-utils
COPY webpack.config.js tsconfig.json tsconfig.release.json ./
COPY src ./src
COPY typings ./typings
# Compile the sources using the dev
# dependencies
RUN npm run build
# Run the production install here, to avoid the npm dependency on
# the later stage
RUN npm ci \
--production \
--no-optional \
--unsafe-perm \
--build-from-source \
--sqlite=/usr/lib \
&& npm cache clean --force \
# For some reason this doesn't get cleared with the other
# cache
&& rm -rf node_modules/.cache \
# Remove various uneeded filetypes in order to reduce space
# We also remove the spurious node.dtps, see https://github.com/mapbox/node-sqlite3/issues/861
&& find . -path '*/coverage/*' -o -path '*/test/*' -o -path '*/.nyc_output/*' \
-o -name '*.tar.*' -o -name '*.in' -o -name '*.cc' \
-o -name '*.c' -o -name "*.ts" -o -name '*.eslintrc' \
-o -name '*.h' -o -name '*.html' -o -name '*.markdown' \
-o -name '*.md' -o -name '*.patch' -o -name '*.png' \
-o -name '*.yml' \
-delete \
&& find . -type f -path '*/node_modules/sqlite3/deps*' -delete \
&& find . -type f -path '*/node_modules/knex/build*' -delete \
&& rm -rf node_modules/sqlite3/node.dtps
###################################################
# Build the production image
###################################################
FROM runtime-base
WORKDIR /usr/src/app
COPY --from=build-prod /usr/src/app/dist ./dist
COPY --from=build-prod /usr/src/app/package.json ./
COPY --from=build-prod /usr/src/app/node_modules ./node_modules
COPY entry.sh .
VOLUME /data
HEALTHCHECK --interval=5m --start-period=1m --timeout=30s --retries=3 \
CMD wget http://127.0.0.1:${LISTEN_PORT:-48484}/v1/healthy -O - -q
CMD ["/usr/src/app/entry.sh"]