Open sthuber90 opened 4 years ago
Wow the size difference is huge! Thank you for your contribution 😊
Thank you for your input. I reduced the COPY
ing between the stages. package.json and package-lock.json are needed for MagicMirror to run, otherwise it errors with a message mentioning those files are missing.
As git
is not part of the alpine based image the following error occures.
[2020-07-08 07:04:20.600] [LOG] Ready to go! Please point your browser to: http://0.0.0.0:8080
[2020-07-08 07:05:12.323] [LOG] Create new calendar fetcher for url: http://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics - Interval: 300000
[2020-07-08 07:05:12.435] [LOG] Create new news fetcher for url: http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml - Interval: 300000
[2020-07-08 07:05:12.474] [ERROR] Error: spawn git ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:267:19)
at onErrorNT (internal/child_process.js:469:16)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
[2020-07-08 07:05:12.969] [INFO] Newsfeed-Fetcher: Broadcasting 57 items.
The error doesn't seem to affect MagicMirror. Everything seems to work as usual.
Adding git
adds 18 MB to the image size and another error appears, while the previously mentioned disappears:
[2020-07-08 07:18:18.900] [LOG] Ready to go! Please point your browser to: http://0.0.0.0:8080
[2020-07-08 07:19:25.987] [LOG] Create new calendar fetcher for url: http://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics - Interval: 300000
[2020-07-08 07:19:26.005] [LOG] Create new news fetcher for url: http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml - Interval: 300000
[2020-07-08 07:19:26.038] [ERROR] fatal: not a git repository (or any of the parent directories): .git
[2020-07-08 07:19:26.494] [INFO] Newsfeed-Fetcher: Broadcasting 57 items.
Adding the .git folder from MagicMirror to the docker image as well resolves the errors, but it feels weird to have git in a production image.
The new image size with git and .git would then be 330 MB on linux/amd64
What are your thoughts on this?
My thoughts:
git
only a build dependency? The default module updatenotification
needs git
, other foreign modules too, e.g. MMM-RemoteControl
. Installing new modules will not work from within the container.ensubst
is used in the entrypoint script, but AFAIS gettext
is installed and deinstalled in the Dockerfiledebian
to alpine
will break all images which are using this image as base image.git
is and should be treated as a development resource / build dependency but I also get that it should be part of the image as MagicMirror is not in any way packagedenvsubst
is workingIt is clear that space is not as huge of a cost factor as it used to be. Nevertheless, I don't see the point of using up almost 2 GB of my raspberry's space when also ~330 MB will do. I still strongly believe that having a smaller image is desireable
I like the idea of having the normal debian based image as default and the alpine image with a -alpine
tag
I think @bastilimbach have to decide if he wants to maintain both images.
A long time ago I discussed with him the idea not only providing images for server only
mode. He didn't want this at that time so I decided to make my own docker setup. And here I decided already to provide both image types (alpine and debian).
I think we should bring these things together again, so may take a look at this setup for deciding what of the stuff should also implemented here.
Beside the size (the debian image is currently 544MB) there are may other things to discuss as running as non-root and copying default modules in entrypoint.
On a side note the 544 MB you mentioned are only shown like this on Docker hub. If you pull the image the size is above 1 GB
The images tagged with 2.12.0 are the ones I created during my work in progress. The one with the latest tag was pulled just now from Docker Hub docker pull bastilimbach/docker-magicmirror:latest
.
Like the idea of having one repository for MagicMirror in docker. Honestly, started with my own Docker Image as well but came to my senses and thought that in the end everybody benefits if it's all maintainable in one repository.
In the end, it's still your decision @bastilimbach
In the meantime, maybe I will have some time to try to setup a draft of how we can build both debian and alpine images
The 544 MB are the result building with this Dockerfile using slim base image.
The build setup could be similiar to mine, building debian first and copying the mm-folder to the alpine image.
Alright, I was able to put a little something together. Didn't have the time to have a throughout look into your repo @khassel As you can see, Travis now builds MagicMirror version 2.12.0 on NodeJS 12 and 14 for Debian and Alpine with different tags. I mean this as a kinda proposal of what could be done. Currently, only buster based images get tagged with "latest" but not alpine to avoid any conflicts with solutions built on top of the current Debian based image.
To Do:
Looking forward to your feedback and input
@bastilimbach can we merge #45 first?
we can also create a GitHub action which checks for new releases of Magic Mirror and creates a pull request here with the generated dockerfiles for the new release.
Looking forward to your feedback and input
I feel not very comfortable only commenting things here ...
ARG
in the Dockerfile to provide the TAG
?
ARG TAG
FROM node:${TAG}
And you can use other files as Dockerfile
using the -f
flag, e.g. docker buildx -f Dockerfile-${template} ...
.gitignore
buster-slim
instead of buster
for debianThe templating was inspired by the official Docker images available for NodeJS, Go, etc. and how those repositories are set up and how their images are build. It may not be necessary to got that far here, if your proposed ARG
solution works.
Git will be added, as we discussed. Sorry, if I forgot it. Nonetheless, I think using multi-stage builds is valid. This way we will not package otherwise unneccessary files such as tests from the MagicMirror repo in the Docker image. Even though it may only be small size difference, I don't see the point why we shouldn't use multi-stage builds.
Instead of starting a discussion on buster-slim
vs buster
. Would it be acceptable to have a -slim
tag?
Tag | base image |
---|---|
2.12.0 | node:lts-buster |
2.12.0-slim | node:lts-buster-slim |
2.12.0-alpine | node:lts-alpine |
Instead of lts
should the Node version be frozen to 12 (LTS) or 14 or just using the lts
Docker tag?
I don't see the point why we shouldn't use multi-stage builds.
the idea was to do the stuff in one stage (see no image size diff to multi stage), this is untested:
FROM node:12-alpine
ENV NODE_ENV production
# get magic mirror
ARG branch=master
RUN set -o pipefail \
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
&& mkdir -p /tmp/magic_mirror \
&& cd /tmp/magic_mirror \
&& git clone --depth 1 -c advice.detachedHead=false -b ${branch} https://github.com/MichMich/MagicMirror.git .
&& mkdir -p /opt/magic_mirror \
&& cp -R config /opt/magic_mirror/default_config \
&& cp -R modules /opt/magic_mirror/default_modules \
&& npm set unsafe-perm true \
&& npm ci \
# 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 /opt/magic_mirror 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 \
&& rm -rf /tmp/magic_mirror
WORKDIR /opt/magic_mirror
EXPOSE 8080
The other questions (how many and which images) should be answered by the owner of this repo. We can think about many options, but he has to merge in the end ...
We both just have different ways of solving the same problem, I guess. Personally, I am not so fond of big RUN
statements. I agree with you though that whatever comes next needs to be @bastilimbach decision
That is great that this repository support multiple architecture.
However there is still a image size issue.
My docker image is half the bastilimbach/docker-magicmirror
image for the same content.
# docker images | grep magic
xbgmsharp/docker-magicmirror latest 1f351bd4aa49 20 hours ago 412MB
bastilimbach/docker-magicmirror latest 95bfee9026c3 5 weeks ago 970MB
@xbgmsharp as you can tell from the discussion, the changes I proposed to make the image smaller have not (yet) been merged.
also see #48
To use smaller base image, alpine is used as a new base. To keep only required files multi-stage builds are used. In addition, unnecessary files are cleaned up from node_modules folder.
This PR is intended to fix #44
The overall size reduction on linux/amd64 (Mac) can be seen here:
As you can see MagicMirror still works: