From 00aff5b025345a4a6dcddf9f436604977bb77e12 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 6 Jul 2020 17:33:45 +0200 Subject: [PATCH 01/13] replace buster with alpine - multi stage build - sh instead of bash --- Dockerfile | 50 ++++++++++++++++++++++++++++++++++---------- docker-entrypoint.sh | 4 ++-- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1aecfce..184ee6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,51 @@ -FROM node:12-buster - -RUN set -e; \ - apt update; \ - apt install -y gettext; \ - rm -rf /var/lib/apt/lists/* +FROM node:12-alpine AS BUILD_IMAGE ARG branch=master ENV NODE_ENV production WORKDIR /opt/magic_mirror -RUN git clone --depth 1 -b ${branch} https://github.com/MichMich/MagicMirror.git . -RUN cp -R modules /opt/default_modules -RUN cp -R config /opt/default_config -RUN npm install --unsafe-perm --silent +# get magic mirror +RUN apk update && apk add --no-cache git \ + && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . \ + && apk del git \ + && rm -rf /var/cache/apk/* + +# save default modules and configuration and install dependencies +RUN cp -R modules /opt/magic_mirror/default_modules \ + && cp -R config /opt/magic_mirror/default_config \ + && npm set unsafe-perm true \ + && npm ci \ + # && npm prune --production + && wget -q https://install.goreleaser.com/github.com/tj/node-prune.sh | sh + + + +FROM node:12-alpine + +WORKDIR /opt/magic_mirror + +RUN set -x \ + && apk add --update libintl \ + && apk add --virtual build_deps gettext \ + && apk del build_deps + +COPY --from=BUILD_IMAGE /opt/magic_mirror/node_modules ./node_modules +COPY --from=BUILD_IMAGE /opt/magic_mirror/config ./config +COPY --from=BUILD_IMAGE /opt/magic_mirror/css ./css +COPY --from=BUILD_IMAGE /opt/magic_mirror/fonts ./fonts +COPY --from=BUILD_IMAGE /opt/magic_mirror/js/ ./js +COPY --from=BUILD_IMAGE /opt/magic_mirror/serveronly ./serveronly +COPY --from=BUILD_IMAGE /opt/magic_mirror/translations ./translations +COPY --from=BUILD_IMAGE /opt/magic_mirror/vendor ./vendor +COPY --from=BUILD_IMAGE /opt/magic_mirror/index.html /opt/magic_mirror/package.json /opt/magic_mirror/package-lock.json ./ +COPY --from=BUILD_IMAGE /opt/magic_mirror/default_config ./default_config +COPY --from=BUILD_IMAGE /opt/magic_mirror/default_modules/ ./default_modules + +EXPOSE 8080 COPY mm-docker-config.js docker-entrypoint.sh ./ RUN chmod +x ./docker-entrypoint.sh -EXPOSE 8080 ENTRYPOINT ["./docker-entrypoint.sh"] CMD ["node", "serveronly"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 32fddb2..5f17a23 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,8 +1,8 @@ -#!/bin/bash +#!/bin/sh set -e if [ ! "$(ls -A /opt/magic_mirror/modules)" ]; then - cp -Rn /opt/default_modules/. /opt/magic_mirror/modules + cp -R /opt/magic_mirror/default_modules/. /opt/magic_mirror/modules fi if [ ! "$(ls -A /opt/magic_mirror/config)" ]; then From 66eb48f141eb70f2ede25f16335e4802a6b51ac1 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Wed, 8 Jul 2020 09:02:21 +0200 Subject: [PATCH 02/13] mark as executable chmod +x --- docker-entrypoint.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 docker-entrypoint.sh diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh old mode 100644 new mode 100755 From 6e791eddf06de3ffba2121352caec68469530ea3 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Wed, 8 Jul 2020 09:02:27 +0200 Subject: [PATCH 03/13] Create .dockerignore --- .dockerignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..96567b4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.github +config +modules +build.sh +test-build.sh \ No newline at end of file From 991a098dc8550d32ca72999a6dc2d31daeea9f40 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Wed, 8 Jul 2020 09:05:37 +0200 Subject: [PATCH 04/13] add bin/bash shebang --- test-build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test-build.sh b/test-build.sh index a8b7b48..0cd9d5e 100755 --- a/test-build.sh +++ b/test-build.sh @@ -1,3 +1,6 @@ +#!/bin/bash +set -e + rm -rf ./config rm -rf ./modules mkdir config From eff03838821bec6fa845da62d289e7ad4561dd7e Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Wed, 8 Jul 2020 09:08:29 +0200 Subject: [PATCH 05/13] clean up file and minify copying between stages --- Dockerfile | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/Dockerfile b/Dockerfile index 184ee6c..67339fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,17 +8,32 @@ WORKDIR /opt/magic_mirror # get magic mirror RUN apk update && apk add --no-cache git \ && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . \ - && apk del git \ - && rm -rf /var/cache/apk/* + && apk del git # save default modules and configuration and install dependencies -RUN cp -R modules /opt/magic_mirror/default_modules \ - && cp -R config /opt/magic_mirror/default_config \ +RUN set -o pipefail \ + && mkdir dist \ + && cp -R config /opt/magic_mirror/dist/default_config \ + && cp -R modules /opt/magic_mirror/dist/default_modules \ && npm set unsafe-perm true \ && npm ci \ - # && npm prune --production - && wget -q https://install.goreleaser.com/github.com/tj/node-prune.sh | sh - + # removes required depdencies and should not be used + # && npm prune --production --json \ + # prune unnecessary files from ./node_modules, such as markdown, typescript source files, and so on. https://github.com/tj/node-prune + && wget -q https://install.goreleaser.com/github.com/tj/node-prune.sh | sh \ + # it is intentional that modules are not copied to dist folder. Please keep alphabetically sorted + && cp -R \ + config \ + css \ + fonts \ + index.html \ + js \ + node_modules \ + package.json \ + package-lock.json \ + serveronly \ + translations \ + vendor /opt/magic_mirror/dist FROM node:12-alpine @@ -26,26 +41,15 @@ FROM node:12-alpine WORKDIR /opt/magic_mirror RUN set -x \ - && apk add --update libintl \ - && apk add --virtual build_deps gettext \ + && apk add --no-cache --update libintl \ + && apk add --no-cache --virtual build_deps gettext \ && apk del build_deps -COPY --from=BUILD_IMAGE /opt/magic_mirror/node_modules ./node_modules -COPY --from=BUILD_IMAGE /opt/magic_mirror/config ./config -COPY --from=BUILD_IMAGE /opt/magic_mirror/css ./css -COPY --from=BUILD_IMAGE /opt/magic_mirror/fonts ./fonts -COPY --from=BUILD_IMAGE /opt/magic_mirror/js/ ./js -COPY --from=BUILD_IMAGE /opt/magic_mirror/serveronly ./serveronly -COPY --from=BUILD_IMAGE /opt/magic_mirror/translations ./translations -COPY --from=BUILD_IMAGE /opt/magic_mirror/vendor ./vendor -COPY --from=BUILD_IMAGE /opt/magic_mirror/index.html /opt/magic_mirror/package.json /opt/magic_mirror/package-lock.json ./ -COPY --from=BUILD_IMAGE /opt/magic_mirror/default_config ./default_config -COPY --from=BUILD_IMAGE /opt/magic_mirror/default_modules/ ./default_modules +COPY --from=BUILD_IMAGE /opt/magic_mirror/dist/ . EXPOSE 8080 COPY mm-docker-config.js docker-entrypoint.sh ./ -RUN chmod +x ./docker-entrypoint.sh ENTRYPOINT ["./docker-entrypoint.sh"] CMD ["node", "serveronly"] From 61dfc317c88f83ec7c9e0a2774d58df0591df803 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Wed, 8 Jul 2020 10:59:02 +0200 Subject: [PATCH 06/13] don't cleanup apk packages in stage 0 (BUILD_IMAGE) --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 67339fd..6dff4b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,7 @@ WORKDIR /opt/magic_mirror # get magic mirror RUN apk update && apk add --no-cache git \ - && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . \ - && apk del git + && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . # save default modules and configuration and install dependencies RUN set -o pipefail \ From ca2ab3acf664f2fbeaf315f77088e47ca78cbbc5 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 13 Jul 2020 18:26:21 +0200 Subject: [PATCH 07/13] adding helper script --- update.sh | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 update.sh diff --git a/update.sh b/update.sh new file mode 100644 index 0000000..4940240 --- /dev/null +++ b/update.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -Eeuo pipefail + +cd "$(dirname "$(readlink "$BASH_SOURCE")")" + +versions=( "$@" ) +if [ ${#versions[@]} -eq 0 ]; then + versions=( */ ) +fi +versions=( "${versions[@]%/}" ) + +for version in "${versions[@]}"; do + for variant in \ + 12{-alpine,-buster} \ + 14{-alpine,-buster} \ + ; do + tag="$variant" + template='debian' + case "$variant" in + *alpine*) tag="${variant#alpine}"; template='alpine' ;; + esac + + if [ ! -d "$version/$variant" ]; then + mkdir -p ./$version/$variant + touch ./$version/$variant/Dockerfile + fi + echo $tag + echo $variant + echo $template + + sed -e 's!%%TAG%%!'"$tag"'!g' \ + "./Dockerfile-${template}.template" > "$version/$variant/Dockerfile" + + cp docker-entrypoint.sh $version/$variant/ + cp mm-docker-config.js $version/$variant/ + done +done \ No newline at end of file From 9b436a28af13b8233853447061f3cbffc041f9bd Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 13 Jul 2020 18:26:56 +0200 Subject: [PATCH 08/13] generating docker structure --- 2.12.0/12-alpine/Dockerfile | 58 ++++++++++++++++ 2.12.0/12-alpine/docker-entrypoint.sh | 16 +++++ 2.12.0/12-alpine/mm-docker-config.js | 97 +++++++++++++++++++++++++++ 2.12.0/12-buster/Dockerfile | 23 +++++++ 2.12.0/12-buster/docker-entrypoint.sh | 16 +++++ 2.12.0/12-buster/mm-docker-config.js | 97 +++++++++++++++++++++++++++ 2.12.0/14-alpine/Dockerfile | 58 ++++++++++++++++ 2.12.0/14-alpine/docker-entrypoint.sh | 16 +++++ 2.12.0/14-alpine/mm-docker-config.js | 97 +++++++++++++++++++++++++++ 2.12.0/14-buster/Dockerfile | 23 +++++++ 2.12.0/14-buster/docker-entrypoint.sh | 16 +++++ 2.12.0/14-buster/mm-docker-config.js | 97 +++++++++++++++++++++++++++ Dockerfile-alpine.template | 58 ++++++++++++++++ Dockerfile-debian.template | 23 +++++++ 14 files changed, 695 insertions(+) create mode 100644 2.12.0/12-alpine/Dockerfile create mode 100755 2.12.0/12-alpine/docker-entrypoint.sh create mode 100644 2.12.0/12-alpine/mm-docker-config.js create mode 100644 2.12.0/12-buster/Dockerfile create mode 100755 2.12.0/12-buster/docker-entrypoint.sh create mode 100644 2.12.0/12-buster/mm-docker-config.js create mode 100644 2.12.0/14-alpine/Dockerfile create mode 100755 2.12.0/14-alpine/docker-entrypoint.sh create mode 100644 2.12.0/14-alpine/mm-docker-config.js create mode 100644 2.12.0/14-buster/Dockerfile create mode 100755 2.12.0/14-buster/docker-entrypoint.sh create mode 100644 2.12.0/14-buster/mm-docker-config.js create mode 100644 Dockerfile-alpine.template create mode 100644 Dockerfile-debian.template diff --git a/2.12.0/12-alpine/Dockerfile b/2.12.0/12-alpine/Dockerfile new file mode 100644 index 0000000..6d28e82 --- /dev/null +++ b/2.12.0/12-alpine/Dockerfile @@ -0,0 +1,58 @@ +FROM node:12-alpine AS BUILD_IMAGE + +ARG branch=master + +ENV NODE_ENV production +WORKDIR /opt/magic_mirror + +# get magic mirror +RUN apk update && apk add --no-cache git \ + && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . + +# save default modules and configuration and install dependencies +RUN set -o pipefail \ + && mkdir dist \ + && cp -R config /opt/magic_mirror/dist/default_config \ + && cp -R modules /opt/magic_mirror/dist/default_modules \ + && npm set unsafe-perm true \ + && npm ci \ + # removes required depdencies and should not be used + # && npm prune --production --json \ + # prune unnecessary files from ./node_modules, such as markdown, typescript source files, and so on. https://github.com/tj/node-prune + && wget -q https://install.goreleaser.com/github.com/tj/node-prune.sh | sh \ + # it is intentional that modules are not copied to dist folder. Please keep alphabetically sorted + && cp -R \ + .git \ + config \ + css \ + fonts \ + index.html \ + js \ + node_modules \ + package.json \ + package-lock.json \ + serveronly \ + translations \ + vendor /opt/magic_mirror/dist + + +FROM node:12-alpine + +WORKDIR /opt/magic_mirror + +RUN set -x \ + && apk update && apk add --no-cache git \ + && apk add --no-cache --update libintl \ + && apk add --no-cache --virtual build_deps gettext \ + && cp /usr/bin/envsubst /usr/local/bin/envsubst \ + && apk del build_deps \ + && mv /usr/local/bin/envsubst /usr/bin/envsubst + +COPY --from=BUILD_IMAGE /opt/magic_mirror/dist/ . + +EXPOSE 8080 + +COPY mm-docker-config.js docker-entrypoint.sh ./ + +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["node", "serveronly"] diff --git a/2.12.0/12-alpine/docker-entrypoint.sh b/2.12.0/12-alpine/docker-entrypoint.sh new file mode 100755 index 0000000..5f17a23 --- /dev/null +++ b/2.12.0/12-alpine/docker-entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +if [ ! "$(ls -A /opt/magic_mirror/modules)" ]; then + cp -R /opt/magic_mirror/default_modules/. /opt/magic_mirror/modules +fi + +if [ ! "$(ls -A /opt/magic_mirror/config)" ]; then + cp /opt/magic_mirror/mm-docker-config.js /opt/magic_mirror/config/config.js +fi + +if [ -f "/opt/magic_mirror/config/config.js.template" ]; then + envsubst < /opt/magic_mirror/config/config.js.template > /opt/magic_mirror/config/config.js +fi + +exec "$@" diff --git a/2.12.0/12-alpine/mm-docker-config.js b/2.12.0/12-alpine/mm-docker-config.js new file mode 100644 index 0000000..7ae119c --- /dev/null +++ b/2.12.0/12-alpine/mm-docker-config.js @@ -0,0 +1,97 @@ +/* Magic Mirror Config Sample + * + * By Michael Teeuw http://michaelteeuw.nl + * MIT Licensed. + * + * For more information how you can configurate this file + * See https://github.com/MichMich/MagicMirror#configuration + * + */ + +var config = { + address: "0.0.0.0", // Address to listen on, can be: + // - "localhost", "127.0.0.1", "::1" to listen on loopback interface + // - another specific IPv4/6 to listen on a specific interface + // - "0.0.0.0" to listen on any interface + // Default, when address config is left out, is "localhost" + port: 8080, + ipWhitelist: [], // Set [] to allow all IP addresses + // or add a specific IPv4 of 192.168.1.5 : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], + // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], + + language: "en", + timeFormat: 24, + units: "metric", + + modules: [ + { + module: "alert", + }, + { + module: "updatenotification", + position: "top_bar" + }, + { + module: "clock", + position: "top_left" + }, + { + module: "calendar", + header: "US Holidays", + position: "top_left", + config: { + calendars: [ + { + symbol: "calendar-check", + url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + } + ] + } + }, + { + module: "compliments", + position: "lower_third" + }, + { + module: "currentweather", + position: "top_right", + config: { + location: "New York", + locationID: "", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "weatherforecast", + position: "top_right", + header: "Weather Forecast", + config: { + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "newsfeed", + position: "bottom_bar", + config: { + feeds: [ + { + title: "New York Times", + url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml" + } + ], + showSourceTitle: true, + showPublishDate: true, + broadcastNewsFeeds: true, + broadcastNewsUpdates: true + } + }, + ] + +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/2.12.0/12-buster/Dockerfile b/2.12.0/12-buster/Dockerfile new file mode 100644 index 0000000..1aecfce --- /dev/null +++ b/2.12.0/12-buster/Dockerfile @@ -0,0 +1,23 @@ +FROM node:12-buster + +RUN set -e; \ + apt update; \ + apt install -y gettext; \ + rm -rf /var/lib/apt/lists/* + +ARG branch=master + +ENV NODE_ENV production +WORKDIR /opt/magic_mirror + +RUN git clone --depth 1 -b ${branch} https://github.com/MichMich/MagicMirror.git . +RUN cp -R modules /opt/default_modules +RUN cp -R config /opt/default_config +RUN npm install --unsafe-perm --silent + +COPY mm-docker-config.js docker-entrypoint.sh ./ +RUN chmod +x ./docker-entrypoint.sh + +EXPOSE 8080 +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["node", "serveronly"] diff --git a/2.12.0/12-buster/docker-entrypoint.sh b/2.12.0/12-buster/docker-entrypoint.sh new file mode 100755 index 0000000..5f17a23 --- /dev/null +++ b/2.12.0/12-buster/docker-entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +if [ ! "$(ls -A /opt/magic_mirror/modules)" ]; then + cp -R /opt/magic_mirror/default_modules/. /opt/magic_mirror/modules +fi + +if [ ! "$(ls -A /opt/magic_mirror/config)" ]; then + cp /opt/magic_mirror/mm-docker-config.js /opt/magic_mirror/config/config.js +fi + +if [ -f "/opt/magic_mirror/config/config.js.template" ]; then + envsubst < /opt/magic_mirror/config/config.js.template > /opt/magic_mirror/config/config.js +fi + +exec "$@" diff --git a/2.12.0/12-buster/mm-docker-config.js b/2.12.0/12-buster/mm-docker-config.js new file mode 100644 index 0000000..7ae119c --- /dev/null +++ b/2.12.0/12-buster/mm-docker-config.js @@ -0,0 +1,97 @@ +/* Magic Mirror Config Sample + * + * By Michael Teeuw http://michaelteeuw.nl + * MIT Licensed. + * + * For more information how you can configurate this file + * See https://github.com/MichMich/MagicMirror#configuration + * + */ + +var config = { + address: "0.0.0.0", // Address to listen on, can be: + // - "localhost", "127.0.0.1", "::1" to listen on loopback interface + // - another specific IPv4/6 to listen on a specific interface + // - "0.0.0.0" to listen on any interface + // Default, when address config is left out, is "localhost" + port: 8080, + ipWhitelist: [], // Set [] to allow all IP addresses + // or add a specific IPv4 of 192.168.1.5 : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], + // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], + + language: "en", + timeFormat: 24, + units: "metric", + + modules: [ + { + module: "alert", + }, + { + module: "updatenotification", + position: "top_bar" + }, + { + module: "clock", + position: "top_left" + }, + { + module: "calendar", + header: "US Holidays", + position: "top_left", + config: { + calendars: [ + { + symbol: "calendar-check", + url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + } + ] + } + }, + { + module: "compliments", + position: "lower_third" + }, + { + module: "currentweather", + position: "top_right", + config: { + location: "New York", + locationID: "", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "weatherforecast", + position: "top_right", + header: "Weather Forecast", + config: { + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "newsfeed", + position: "bottom_bar", + config: { + feeds: [ + { + title: "New York Times", + url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml" + } + ], + showSourceTitle: true, + showPublishDate: true, + broadcastNewsFeeds: true, + broadcastNewsUpdates: true + } + }, + ] + +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/2.12.0/14-alpine/Dockerfile b/2.12.0/14-alpine/Dockerfile new file mode 100644 index 0000000..26291a7 --- /dev/null +++ b/2.12.0/14-alpine/Dockerfile @@ -0,0 +1,58 @@ +FROM node:14-alpine AS BUILD_IMAGE + +ARG branch=master + +ENV NODE_ENV production +WORKDIR /opt/magic_mirror + +# get magic mirror +RUN apk update && apk add --no-cache git \ + && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . + +# save default modules and configuration and install dependencies +RUN set -o pipefail \ + && mkdir dist \ + && cp -R config /opt/magic_mirror/dist/default_config \ + && cp -R modules /opt/magic_mirror/dist/default_modules \ + && npm set unsafe-perm true \ + && npm ci \ + # removes required depdencies and should not be used + # && npm prune --production --json \ + # prune unnecessary files from ./node_modules, such as markdown, typescript source files, and so on. https://github.com/tj/node-prune + && wget -q https://install.goreleaser.com/github.com/tj/node-prune.sh | sh \ + # it is intentional that modules are not copied to dist folder. Please keep alphabetically sorted + && cp -R \ + .git \ + config \ + css \ + fonts \ + index.html \ + js \ + node_modules \ + package.json \ + package-lock.json \ + serveronly \ + translations \ + vendor /opt/magic_mirror/dist + + +FROM node:12-alpine + +WORKDIR /opt/magic_mirror + +RUN set -x \ + && apk update && apk add --no-cache git \ + && apk add --no-cache --update libintl \ + && apk add --no-cache --virtual build_deps gettext \ + && cp /usr/bin/envsubst /usr/local/bin/envsubst \ + && apk del build_deps \ + && mv /usr/local/bin/envsubst /usr/bin/envsubst + +COPY --from=BUILD_IMAGE /opt/magic_mirror/dist/ . + +EXPOSE 8080 + +COPY mm-docker-config.js docker-entrypoint.sh ./ + +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["node", "serveronly"] diff --git a/2.12.0/14-alpine/docker-entrypoint.sh b/2.12.0/14-alpine/docker-entrypoint.sh new file mode 100755 index 0000000..5f17a23 --- /dev/null +++ b/2.12.0/14-alpine/docker-entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +if [ ! "$(ls -A /opt/magic_mirror/modules)" ]; then + cp -R /opt/magic_mirror/default_modules/. /opt/magic_mirror/modules +fi + +if [ ! "$(ls -A /opt/magic_mirror/config)" ]; then + cp /opt/magic_mirror/mm-docker-config.js /opt/magic_mirror/config/config.js +fi + +if [ -f "/opt/magic_mirror/config/config.js.template" ]; then + envsubst < /opt/magic_mirror/config/config.js.template > /opt/magic_mirror/config/config.js +fi + +exec "$@" diff --git a/2.12.0/14-alpine/mm-docker-config.js b/2.12.0/14-alpine/mm-docker-config.js new file mode 100644 index 0000000..7ae119c --- /dev/null +++ b/2.12.0/14-alpine/mm-docker-config.js @@ -0,0 +1,97 @@ +/* Magic Mirror Config Sample + * + * By Michael Teeuw http://michaelteeuw.nl + * MIT Licensed. + * + * For more information how you can configurate this file + * See https://github.com/MichMich/MagicMirror#configuration + * + */ + +var config = { + address: "0.0.0.0", // Address to listen on, can be: + // - "localhost", "127.0.0.1", "::1" to listen on loopback interface + // - another specific IPv4/6 to listen on a specific interface + // - "0.0.0.0" to listen on any interface + // Default, when address config is left out, is "localhost" + port: 8080, + ipWhitelist: [], // Set [] to allow all IP addresses + // or add a specific IPv4 of 192.168.1.5 : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], + // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], + + language: "en", + timeFormat: 24, + units: "metric", + + modules: [ + { + module: "alert", + }, + { + module: "updatenotification", + position: "top_bar" + }, + { + module: "clock", + position: "top_left" + }, + { + module: "calendar", + header: "US Holidays", + position: "top_left", + config: { + calendars: [ + { + symbol: "calendar-check", + url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + } + ] + } + }, + { + module: "compliments", + position: "lower_third" + }, + { + module: "currentweather", + position: "top_right", + config: { + location: "New York", + locationID: "", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "weatherforecast", + position: "top_right", + header: "Weather Forecast", + config: { + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "newsfeed", + position: "bottom_bar", + config: { + feeds: [ + { + title: "New York Times", + url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml" + } + ], + showSourceTitle: true, + showPublishDate: true, + broadcastNewsFeeds: true, + broadcastNewsUpdates: true + } + }, + ] + +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/2.12.0/14-buster/Dockerfile b/2.12.0/14-buster/Dockerfile new file mode 100644 index 0000000..afe270f --- /dev/null +++ b/2.12.0/14-buster/Dockerfile @@ -0,0 +1,23 @@ +FROM node:14-buster + +RUN set -e; \ + apt update; \ + apt install -y gettext; \ + rm -rf /var/lib/apt/lists/* + +ARG branch=master + +ENV NODE_ENV production +WORKDIR /opt/magic_mirror + +RUN git clone --depth 1 -b ${branch} https://github.com/MichMich/MagicMirror.git . +RUN cp -R modules /opt/default_modules +RUN cp -R config /opt/default_config +RUN npm install --unsafe-perm --silent + +COPY mm-docker-config.js docker-entrypoint.sh ./ +RUN chmod +x ./docker-entrypoint.sh + +EXPOSE 8080 +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["node", "serveronly"] diff --git a/2.12.0/14-buster/docker-entrypoint.sh b/2.12.0/14-buster/docker-entrypoint.sh new file mode 100755 index 0000000..5f17a23 --- /dev/null +++ b/2.12.0/14-buster/docker-entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +if [ ! "$(ls -A /opt/magic_mirror/modules)" ]; then + cp -R /opt/magic_mirror/default_modules/. /opt/magic_mirror/modules +fi + +if [ ! "$(ls -A /opt/magic_mirror/config)" ]; then + cp /opt/magic_mirror/mm-docker-config.js /opt/magic_mirror/config/config.js +fi + +if [ -f "/opt/magic_mirror/config/config.js.template" ]; then + envsubst < /opt/magic_mirror/config/config.js.template > /opt/magic_mirror/config/config.js +fi + +exec "$@" diff --git a/2.12.0/14-buster/mm-docker-config.js b/2.12.0/14-buster/mm-docker-config.js new file mode 100644 index 0000000..7ae119c --- /dev/null +++ b/2.12.0/14-buster/mm-docker-config.js @@ -0,0 +1,97 @@ +/* Magic Mirror Config Sample + * + * By Michael Teeuw http://michaelteeuw.nl + * MIT Licensed. + * + * For more information how you can configurate this file + * See https://github.com/MichMich/MagicMirror#configuration + * + */ + +var config = { + address: "0.0.0.0", // Address to listen on, can be: + // - "localhost", "127.0.0.1", "::1" to listen on loopback interface + // - another specific IPv4/6 to listen on a specific interface + // - "0.0.0.0" to listen on any interface + // Default, when address config is left out, is "localhost" + port: 8080, + ipWhitelist: [], // Set [] to allow all IP addresses + // or add a specific IPv4 of 192.168.1.5 : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], + // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], + + language: "en", + timeFormat: 24, + units: "metric", + + modules: [ + { + module: "alert", + }, + { + module: "updatenotification", + position: "top_bar" + }, + { + module: "clock", + position: "top_left" + }, + { + module: "calendar", + header: "US Holidays", + position: "top_left", + config: { + calendars: [ + { + symbol: "calendar-check", + url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + } + ] + } + }, + { + module: "compliments", + position: "lower_third" + }, + { + module: "currentweather", + position: "top_right", + config: { + location: "New York", + locationID: "", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "weatherforecast", + position: "top_right", + header: "Weather Forecast", + config: { + location: "New York", + locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + appid: "YOUR_OPENWEATHER_API_KEY" + } + }, + { + module: "newsfeed", + position: "bottom_bar", + config: { + feeds: [ + { + title: "New York Times", + url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml" + } + ], + showSourceTitle: true, + showPublishDate: true, + broadcastNewsFeeds: true, + broadcastNewsUpdates: true + } + }, + ] + +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template new file mode 100644 index 0000000..8991880 --- /dev/null +++ b/Dockerfile-alpine.template @@ -0,0 +1,58 @@ +FROM node:%%TAG%% AS BUILD_IMAGE + +ARG branch=master + +ENV NODE_ENV production +WORKDIR /opt/magic_mirror + +# get magic mirror +RUN apk update && apk add --no-cache git \ + && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . + +# save default modules and configuration and install dependencies +RUN set -o pipefail \ + && mkdir dist \ + && cp -R config /opt/magic_mirror/dist/default_config \ + && cp -R modules /opt/magic_mirror/dist/default_modules \ + && npm set unsafe-perm true \ + && npm ci \ + # removes required depdencies and should not be used + # && npm prune --production --json \ + # prune unnecessary files from ./node_modules, such as markdown, typescript source files, and so on. https://github.com/tj/node-prune + && wget -q https://install.goreleaser.com/github.com/tj/node-prune.sh | sh \ + # it is intentional that modules are not copied to dist folder. Please keep alphabetically sorted + && cp -R \ + .git \ + config \ + css \ + fonts \ + index.html \ + js \ + node_modules \ + package.json \ + package-lock.json \ + serveronly \ + translations \ + vendor /opt/magic_mirror/dist + + +FROM node:12-alpine + +WORKDIR /opt/magic_mirror + +RUN set -x \ + && apk update && apk add --no-cache git \ + && apk add --no-cache --update libintl \ + && apk add --no-cache --virtual build_deps gettext \ + && cp /usr/bin/envsubst /usr/local/bin/envsubst \ + && apk del build_deps \ + && mv /usr/local/bin/envsubst /usr/bin/envsubst + +COPY --from=BUILD_IMAGE /opt/magic_mirror/dist/ . + +EXPOSE 8080 + +COPY mm-docker-config.js docker-entrypoint.sh ./ + +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["node", "serveronly"] diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template new file mode 100644 index 0000000..4733ff8 --- /dev/null +++ b/Dockerfile-debian.template @@ -0,0 +1,23 @@ +FROM node:%%TAG%% + +RUN set -e; \ + apt update; \ + apt install -y gettext; \ + rm -rf /var/lib/apt/lists/* + +ARG branch=master + +ENV NODE_ENV production +WORKDIR /opt/magic_mirror + +RUN git clone --depth 1 -b ${branch} https://github.com/MichMich/MagicMirror.git . +RUN cp -R modules /opt/default_modules +RUN cp -R config /opt/default_config +RUN npm install --unsafe-perm --silent + +COPY mm-docker-config.js docker-entrypoint.sh ./ +RUN chmod +x ./docker-entrypoint.sh + +EXPOSE 8080 +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["node", "serveronly"] \ No newline at end of file From 05a0a008882b34abbecc06e0bf2447fa586cdf19 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 13 Jul 2020 18:27:07 +0200 Subject: [PATCH 09/13] remove obsolete Dockerfile --- Dockerfile | 54 ------------------------------------------------------ 1 file changed, 54 deletions(-) delete mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 6dff4b2..0000000 --- a/Dockerfile +++ /dev/null @@ -1,54 +0,0 @@ -FROM node:12-alpine AS BUILD_IMAGE - -ARG branch=master - -ENV NODE_ENV production -WORKDIR /opt/magic_mirror - -# get magic mirror -RUN apk update && apk add --no-cache git \ - && git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git . - -# save default modules and configuration and install dependencies -RUN set -o pipefail \ - && mkdir dist \ - && cp -R config /opt/magic_mirror/dist/default_config \ - && cp -R modules /opt/magic_mirror/dist/default_modules \ - && npm set unsafe-perm true \ - && npm ci \ - # removes required depdencies and should not be used - # && npm prune --production --json \ - # prune unnecessary files from ./node_modules, such as markdown, typescript source files, and so on. https://github.com/tj/node-prune - && wget -q https://install.goreleaser.com/github.com/tj/node-prune.sh | sh \ - # it is intentional that modules are not copied to dist folder. Please keep alphabetically sorted - && cp -R \ - config \ - css \ - fonts \ - index.html \ - js \ - node_modules \ - package.json \ - package-lock.json \ - serveronly \ - translations \ - vendor /opt/magic_mirror/dist - - -FROM node:12-alpine - -WORKDIR /opt/magic_mirror - -RUN set -x \ - && apk add --no-cache --update libintl \ - && apk add --no-cache --virtual build_deps gettext \ - && apk del build_deps - -COPY --from=BUILD_IMAGE /opt/magic_mirror/dist/ . - -EXPOSE 8080 - -COPY mm-docker-config.js docker-entrypoint.sh ./ - -ENTRYPOINT ["./docker-entrypoint.sh"] -CMD ["node", "serveronly"] From b51d1a7559f591102c193335e98cadd1eacfacf3 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 13 Jul 2020 18:27:17 +0200 Subject: [PATCH 10/13] :pencil: writing docs --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d40cf26..1473199 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ In some cases, you want to start the application without an actual app window. I - `latest` - The [latest stable release](https://github.com/MichMich/MagicMirror/releases/latest) of MagicMirror. - `develop` - Image based on the [`develop`](https://github.com/MichMich/MagicMirror/tree/develop) branch. -- `vX.Y.Z`- Specific MagicMirror release. Take a look at the [releases](https://github.com/MichMich/MagicMirror/releases) page in the MagicMirror repository to get the correct version number. +- `vX.Y.Z`- Specific MagicMirror release. There is a `-alpine` tag if you are looking for smaller images. Take a look at the [releases](https://github.com/MichMich/MagicMirror/releases) page in the MagicMirror repository to get the correct version number. > The respective docker images are getting updated daily by a cron job from Travis CI. @@ -116,5 +116,29 @@ and choose 'Localisation options' I'm happy to accept Pull Requests! Please note that this project is released with a [Contributor Code of Conduct](https://github.com/bastilimbach/docker-MagicMirror/blob/master/.github/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. +# Usage + +## `update.sh` +``` bash +./update.sh A.B.C,X.Y.Z +``` +Creates directory structure with _Dockerfile_, entrypoint file and _mmm-docker-config.js_ for the specified MagicMirror versions (no leading "v") and for the supported platforms i.e. NodeJS versions 12 and 14 on Debian buster and Alpine. + +## `build.sh` +``` bash +./build.sh 2.12.0 12-buster --push +# or +./build.sh 2.12.0,A.B.C,X.Y.Z 12-buster,12-alpine,14-buster,14-alpine --push +``` +Build Docker images locally. You can specify one or many versions that you want to build on one or many platforms. Building images locally for multiple architectures with the `--load` flag is [currently not possible](https://github.com/docker/buildx/issues/59). If the optional third argument `--push` is set when running the build script it will use `buildx` to build and push the Docker image for the defined architectures. + +## `test-build.sh` +``` bash +./test-build.sh 2.12.0 12-buster +``` + +Build and run specified MagicMirror version on specified platform locally. Exposed on port 80 and with _modules_ and _config_ as volumes in this project's root directory. + + # License [MIT](https://github.com/bastilimbach/docker-MagicMirror/blob/master/LICENSE) ❤️ From 5b6d1e9330b194a9abc889a65fd3130d6c625d82 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 13 Jul 2020 18:27:30 +0200 Subject: [PATCH 11/13] updating scripts --- build.sh | 92 +++++++++++++++++++++++++++++++++++++++++++++++---- test-build.sh | 2 +- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/build.sh b/build.sh index 1ff6a00..828b3d3 100755 --- a/build.sh +++ b/build.sh @@ -1,10 +1,90 @@ #!/bin/bash -set -e +set -euo pipefail -# https://stackoverflow.com/a/51761312/4934537 -latest_release=$(git ls-remote --tags --refs --sort="v:refname" https://github.com/MichMich/MagicMirror.git | tail -n1 | sed 's/.*\///') -if [ "$(docker manifest inspect bastilimbach/docker-magicmirror:"${latest_release}" > /dev/null; echo $?)" != 0 ]; then - docker buildx build --progress plain --platform=linux/amd64,linux/arm64,linux/arm/v7 ${1} --build-arg branch="${latest_release}" -t bastilimbach/docker-magicmirror:"${latest_release}" -t bastilimbach/docker-magicmirror:latest . +# Convert comma delimited cli arguments to arrays +# E.g. ./build.sh 10,12 slim,alpine +# "10,12" becomes "10 12" and "slim,alpine" becomes "slim alpine" +IFS=',' read -ra versions_arg <<< "${1:-}" +IFS=',' read -ra variant_arg <<< "${2:-}" +if [ -n "${3-}" ]; then + push="${3}" +else + push="" fi -docker buildx build --progress plain --platform=linux/amd64,linux/arm64,linux/arm/v7 ${1} --build-arg branch=develop -t bastilimbach/docker-magicmirror:develop . +function build() { + local version + local tag + local variant + local full_tag + version="$1" + shift + variant="$1" + shift + tag="$1" + shift + + full_tag=${tag} + case "$variant" in + *alpine*) full_tag="${version}-alpine" ;; + esac + + echo "Building ${full_tag}..." + branch="${version}" + if [ "${version}" != "master" ] && [ "${version}" != "develop" ]; then + branch="v${version}" + fi + + latest_tag="" + latest_release=$(git ls-remote --tags --refs --sort="v:refname" https://github.com/MichMich/MagicMirror.git | tail -n1 | sed 's/.*\///') + if [ "${latest_release}" = "v${version}" ] && [ "${full_tag}" != *"alpine"* ]; then + latest_tag="-t bastilimbach/docker-magicmirror:latest" + fi + + if [ "${push}" ]; then + docker buildx build --progress plain \ + --platform=linux/amd64,linux/arm64,linux/arm/v7 \ + ${push} \ + --build-arg branch="${branch}" \ + -t bastilimbach/docker-magicmirror:"${full_tag}" \ + ${latest_tag} \ + "${version}/${variant}/" + else + if ! docker build --cpuset-cpus="0,1" \ + --build-arg branch="${branch}" \ + -t bastilimbach/docker-magicmirror:"${full_tag}" \ + ${latest_tag} \ + "${version}/${variant}/"; then + echo "Build of ${full_tag} failed!" + exit 2 + fi + echo "Build of ${full_tag} succeeded." + fi +} + +IFS=' ' read -ra versions <<< "${versions_arg[@]}" +IFS=' ' read -ra variants <<< "${variant_arg[@]}" +for version in "${versions[@]}"; do + tag="${version}" + + for variant in "${variants[@]}"; do + # Skip non-docker directories + [ -f "${version}/${variant}/Dockerfile" ] || continue + + build "${version}" "${variant}" "${tag}" + #test_image "${full_version}" "${variant}" "${tag}" + done + +done + +echo "All builds successful!" + +exit 0 + +# https://stackoverflow.com/a/51761312/4934537 +# latest_release=$(git ls-remote --tags --refs --sort="v:refname" https://github.com/MichMich/MagicMirror.git | tail -n1 | sed 's/.*\///') +# if [ "$(docker manifest inspect bastilimbach/docker-magicmirror:"${latest_release}" > /dev/null; echo $?)" != 0 ]; then +# docker buildx build --progress plain --platform=linux/amd64,linux/arm64,linux/arm/v7 ${1} --build-arg branch="${latest_release}" -t bastilimbach/docker-magicmirror:"${latest_release}" -t bastilimbach/docker-magicmirror:latest . +# fi + +# docker buildx build --progress plain --platform=linux/amd64,linux/arm64,linux/arm/v7 ${1} --build-arg branch=develop -t bastilimbach/docker-magicmirror:develop . diff --git a/test-build.sh b/test-build.sh index 0cd9d5e..5fea327 100755 --- a/test-build.sh +++ b/test-build.sh @@ -7,7 +7,7 @@ mkdir config mkdir modules docker rm -f magic_mirror -docker build -t mm:latest . +docker build -t mm:latest ${1}/${2} docker run -d \ --publish 80:8080 \ --restart always \ From 6ca7b8fd6b45efc5ac3530780d22171676ba8762 Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 13 Jul 2020 18:28:01 +0200 Subject: [PATCH 12/13] :construction_worker: update travis build --- .travis.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2c6ed65..d5d835a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,17 @@ sudo: required services: - docker language: bash + +env: + - MM_VERSION=2.12.0 \ + PLATFORM=12-alpine + - MM_VERSION=2.12.0 \ + PLATFORM=12-buster + - MM_VERSION=2.12.0 \ + PLATFORM=12-alpine + - MM_VERSION=2.12.0 \ + PLATFORM=12-buster + before_script: # Upgrade Docker and enable experimental mode - curl -fsSL https://get.docker.com | sh @@ -24,6 +35,6 @@ script: dopush="--push" fi # Build the latest stable MagicMirror release - - ./build.sh ${dopush} + - ./build.sh $MM_VERSION $PLATFORM ${dopush} after_script: - docker logout From 4bef0073ea50be2a27a9e8ad1987a1c1b2e6d45a Mon Sep 17 00:00:00 2001 From: Stephan Huber Date: Mon, 13 Jul 2020 18:29:22 +0200 Subject: [PATCH 13/13] Update .travis.yml --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index d5d835a..54edfa0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,14 +5,14 @@ services: language: bash env: - - MM_VERSION=2.12.0 \ + - MM_VERSION=2.12.0 PLATFORM=12-alpine - - MM_VERSION=2.12.0 \ + - MM_VERSION=2.12.0 PLATFORM=12-buster - - MM_VERSION=2.12.0 \ - PLATFORM=12-alpine - - MM_VERSION=2.12.0 \ - PLATFORM=12-buster + - MM_VERSION=2.12.0 + PLATFORM=14-alpine + - MM_VERSION=2.12.0 + PLATFORM=14-buster before_script: # Upgrade Docker and enable experimental mode