ARG ARCH=%%BALENA_ARCH%% # Used by livepush to support multi arch images in older # balenaOS with buggy platform support # see https://github.com/balena-os/balena-engine/issues/269 ARG PREFIX=library ################################################### # Build the supervisor dependencies ################################################### FROM balenalib/${ARCH}-alpine-node:16-run as build-base ARG PREFIX # Sanity check to prevent a prefix for a non-official docker image being # inserted. Only 'library' and 'arm32v6' are allowed right now RUN for allowed in "library" "arm32v6"; do [ "${PREFIX}" = "${allowed}" ] && break; done 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 # Just install dev dependencies first RUN npm ci --build-from-source --sqlite=/usr/lib ################################################### # Extra dependencies. This uses alpine 3.11 as the # procmail package was removed on 3.12 ################################################### FROM ${PREFIX}/alpine:3.11 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 ${PREFIX}/alpine:3.16 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 # Similarly, from the procmail package we just need the lockfile binary COPY --from=extra /usr/bin/lockfile /usr/bin/lockfile # 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/legacy tests here # to prevent setting up a test environment that will # most likely fail. # For now this also runs the legacy tests, that are slow, this is a # forcing function to finish the split between unit/integration 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"]