2021-10-19 04:06:08 +00:00
ARG ARCH = %%BALENA_ARCH%%
2024-03-08 14:42:53 +00:00
ARG FATRW_VERSION = 0 .2.21
2024-03-06 15:03:08 +00:00
ARG NODE = "nodejs~=20"
ARG NPM = "npm~=10"
ARG ALPINE_VERSION = "3.19"
2023-03-10 00:16:49 +00:00
2022-07-06 19:51:49 +00:00
###################################################
# Build the supervisor dependencies
###################################################
2024-08-21 02:11:56 +00:00
FROM alpine:${ALPINE_VERSION} AS build-base
2022-07-06 19:51:49 +00:00
2022-11-11 16:28:45 +00:00
ARG ARCH
2023-03-10 00:01:09 +00:00
ARG NODE
ARG NPM
2022-11-11 16:28:45 +00:00
ARG FATRW_VERSION
2024-03-08 14:42:53 +00:00
ARG FATRW_RELEASES = " https://github.com/balena-os/fatrw/releases/download/v ${ FATRW_VERSION } "
2021-10-19 04:06:08 +00:00
WORKDIR /usr/src/app
2023-03-10 00:01:09 +00:00
RUN apk add --update --no-cache \
2023-08-10 19:18:12 +00:00
build-base \
2022-07-06 19:51:49 +00:00
python3 \
2023-03-10 00:01:09 +00:00
curl \
$NODE \
$NPM \
2021-10-19 04:06:08 +00:00
libuv \
sqlite-dev \
2023-08-10 19:18:12 +00:00
cargo \
rust
2022-07-06 19:51:49 +00:00
COPY package*.json ./
2024-03-08 14:42:53 +00:00
COPY ./build-utils/rust-arch.sh /
2022-07-06 19:51:49 +00:00
2023-03-10 00:01:09 +00:00
RUN strip " $( which node) "
2022-07-06 19:51:49 +00:00
2022-11-11 16:28:45 +00:00
# Install fatrw
2024-03-08 14:42:53 +00:00
RUN FATRW_ARCHIVE = " fatrw- $( /rust-arch.sh) .tar.gz " && \
FATRW_LOCATION = " ${ FATRW_RELEASES } / ${ FATRW_ARCHIVE } " && \
curl -SLO " ${ FATRW_LOCATION } " && \
2022-11-11 16:28:45 +00:00
ls -la " ${ FATRW_ARCHIVE } " && \
tar -xzf " ${ FATRW_ARCHIVE } " -C /usr/local/bin && \
rm -f " ${ FATRW_ARCHIVE } "
2022-07-06 19:51:49 +00:00
# Just install dev dependencies first
2023-11-20 21:35:39 +00:00
RUN npm ci --build-from-source= sqlite3 --sqlite= /usr/lib
2022-07-06 19:51:49 +00:00
2022-12-05 19:24:11 +00:00
###################################################################
# 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
###################################################################
2024-10-18 13:42:52 +00:00
FROM debian:bookworm-slim AS journal
2022-12-05 19:24:11 +00:00
RUN apt-get update && apt-get install -y --no-install-recommends systemd
COPY ./build-utils/setup-journal.sh /
RUN /setup-journal.sh
2022-07-06 19:51:49 +00:00
###################################################
# Extra dependencies. This uses alpine 3.11 as the
# procmail package was removed on 3.12
###################################################
2024-08-21 02:11:56 +00:00
FROM alpine:3.11 AS extra
2022-07-06 19:51:49 +00:00
RUN apk add --update --no-cache procmail
###################################################
# Image with the final production dependencies.
# This image will also be be used for testing
###################################################
2024-08-21 02:11:56 +00:00
FROM alpine:${ALPINE_VERSION} AS runtime-base
2022-07-06 19:51:49 +00:00
2023-03-10 00:01:09 +00:00
ARG NODE
2022-07-06 19:51:49 +00:00
2023-03-10 00:01:09 +00:00
WORKDIR /usr/src/app
2023-03-24 21:27:58 +00:00
2022-11-11 16:28:45 +00:00
# Also copy the fatrw binary
COPY --from= build-base /usr/local/bin/fatrw /usr/local/bin/fatrw
2022-07-06 19:51:49 +00:00
# Similarly, from the procmail package we just need the lockfile binary
COPY --from= extra /usr/bin/lockfile /usr/bin/lockfile
2022-12-05 19:24:11 +00:00
# Copy journalctl and library dependecies to the final image
COPY --from= journal /sysroot /
2023-02-21 06:11:27 +00:00
# Copy mount script for mounting host partitions into container
COPY mount-partitions.sh .
2022-07-06 19:51:49 +00:00
# Runtime dependencies
2023-03-10 00:01:09 +00:00
RUN apk add --update --no-cache \
$NODE \
2022-07-06 19:51:49 +00:00
rsync \
dbus \
2022-01-06 20:32:50 +00:00
dmidecode \
2023-02-21 06:11:27 +00:00
sqlite-libs \
2024-08-15 20:29:22 +00:00
lsblk \
2024-09-23 10:56:48 +00:00
kmod \
device-mapper
2021-10-19 04:06:08 +00:00
2024-03-18 21:14:58 +00:00
# Iptables should be pinned to 1.8.9 (legacy) as balenaOS still uses iptables-legacy
RUN apk add --update --no-cache \
--repository= http://dl-cdn.alpinelinux.org/alpine/v3.18/main \
iptables~= 1.8.9 \
ip6tables~= 1.8.9
2022-07-06 19:51:49 +00:00
ARG ARCH
ARG VERSION = master
2023-02-21 06:11:27 +00:00
ENV LED_FILE = /dev/null \
2022-07-06 19:51:49 +00:00
SUPERVISOR_IMAGE = balena/$ARCH -supervisor \
2022-09-20 14:16:58 +00:00
VERSION = $VERSION
2021-10-19 04:06:08 +00:00
2022-08-19 20:07:33 +00:00
###############################################################
# Use the base image to run integration tests and for livepush
###############################################################
2024-08-21 02:11:56 +00:00
FROM runtime-base AS test
2021-10-19 04:06:08 +00:00
2023-03-10 00:01:09 +00:00
ARG NPM
ARG ARCH
2021-10-19 04:06:08 +00:00
2023-03-10 00:01:09 +00:00
# We want to use as close to the final image when running tests
# but we need npm so we install it here again
2023-08-10 19:18:12 +00:00
RUN apk add --update --no-cache $NPM
2023-03-10 00:01:09 +00:00
WORKDIR /usr/src/app
2023-03-24 21:27:58 +00:00
2022-07-06 19:51:49 +00:00
# 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
2021-10-19 04:06:08 +00:00
#dev-copy=entry.sh .
#dev-cmd-live=LIVEPUSH=1 ./entry.sh
2022-07-06 19:51:49 +00:00
# Copy build files
2024-01-25 17:30:13 +00:00
COPY entry.sh .
2021-10-19 04:06:08 +00:00
COPY build-utils ./build-utils
2022-08-19 20:07:33 +00:00
COPY webpack.config.js tsconfig.json tsconfig.release.json tsconfig.js.json .mochapodrc.yml ./
COPY typings ./typings
2021-10-19 04:06:08 +00:00
COPY src ./src
COPY test ./test
2022-08-19 20:07:33 +00:00
2023-03-27 15:14:01 +00:00
# Fail-safe, check the architecture used by apk against the expected architecture
# from the device type
RUN APK_ARCH = $( ./build-utils/apk-print-arch.sh) ; [ " $APK_ARCH " = " $ARCH " ] || ( echo " Image architecture ( $APK_ARCH ) does not match the target architecture ( $ARCH ) " && exit 1)
2022-11-11 16:28:45 +00:00
# Run type checking and unit tests here
2022-09-12 11:35:19 +00:00
# to prevent setting up a test environment that will
2022-08-22 23:54:21 +00:00
# most likely fail.
2022-09-12 22:10:17 +00:00
RUN npm run test
2022-08-22 23:54:21 +00:00
2022-09-12 11:35:19 +00:00
# When running tests from a container built from this stage,
2022-08-19 20:07:33 +00:00
# skip the mocha-pod setup
ENV MOCHAPOD_SKIP_SETUP = 1
2022-09-12 11:35:19 +00:00
# This command will be used by default when running integration tests
2022-08-19 20:07:33 +00:00
# from this stage
CMD npm run test:integration
2021-10-19 04:06:08 +00:00
2022-07-06 19:51:49 +00:00
###################################################
# Build the production package
###################################################
2024-08-21 02:11:56 +00:00
FROM build-base AS build-prod
2022-07-06 19:51:49 +00:00
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
2021-10-19 04:06:08 +00:00
# Run the production install here, to avoid the npm dependency on
# the later stage
2022-09-12 20:33:45 +00:00
RUN npm ci \
2023-08-10 19:18:12 +00:00
--omit= dev \
--omit= optional \
2022-09-12 20:33:45 +00:00
--unsafe-perm \
2023-11-20 21:35:39 +00:00
--build-from-source= sqlite3 \
2022-09-12 20:33:45 +00:00
--sqlite= /usr/lib \
2021-10-19 04:06:08 +00:00
&& 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
2022-07-06 19:51:49 +00:00
###################################################
# Build the production image
###################################################
FROM runtime-base
2021-10-19 04:06:08 +00:00
WORKDIR /usr/src/app
2022-07-06 19:51:49 +00:00
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
2021-10-19 04:06:08 +00:00
COPY entry.sh .
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" ]