Question: How to shrink size of Docker image with NodeJs


How to shrink size of Docker image with NodeJs

Answers 2
Added at 2017-01-05 14:01

I created new Angular2 app by angular-cli and run it in Docker.

At first I init app on my local machine:

ng new project && cd project &&  "put my Dockerfile there" && docker build -t my-ui && docker run.

My Dockerfile

FROM node

RUN npm install -g angular-cli@v1.0.0-beta.24 && npm cache clean && rm -rf ~/.npm

RUN mkdir -p /opt/client-ui/src
WORKDIR /opt/client-ui  

COPY package.json /opt/client-ui/
COPY angular-cli.json /opt/client-ui/
COPY tslint.json /opt/client-ui/

ADD src/ /opt/client-ui/src

RUN npm install
RUN ng build --prod --aot


ENV PATH="$PATH:/usr/local/bin/"    
CMD ["npm", "start"]

Everything is OK, problem is size of image: 939MB!!! I tried to use FROM: ubuntu:16.04 and install NodeJs on it (it works), but still my image has ~450 MB. I know that node:alpine exists, but I am not able to install angular-cli in it.

How can I shrink image size? Is it necessary to run "npm install" and "ng build" in Dockerfile? I would expect to build app on localhost and copy it to image. I tried to copy dist dir and and package.json etc files, but it does not work (app start fail). Thanks.

nr: #1 dodano: 2017-01-05 16:01

For production, you do not need to distribute an image with Node.js, NPM dependencies, etc. You simply need an image that can be used to start a data volume container that provides the compiled sources, release source maps and other assets, effectively no more than what you would redistributed with a package via NPM, that you can attach to your webserver.

So, for your CI host, you can pick one of the node:alpine distributions and copy the sources and install the dependencies therein, then you can re-use the image for running containers that test the builds until you finally run a container that performs a production compilation, which you can name.

docker run --name=compile-${RELEASE} ci-${RELEASE} npm run production

After you have finished compiling the sources within a container, run a container that has the volumes from the compilation container attached and copy the sources to a volume on the container and push that to your Docker upstream:

docker run --name=release-${RELEASE} --volumes-from=compile-${RELEASE} -v /srv/public busybox cp -R /myapp/dist /srv/public
docker commit release-${RELEASE} release-${RELEASE} myapp:${RELEASE}
nr: #2 dodano: 2017-01-05 16:01

You can certainly use my alpine-ng image if you like.

You can also check out the dockerfile, if you want to try and modify it in some way.

I regret to inform you that even based on alpine, it is still 610MB. An improvement to be sure, but there is no getting around the fact that the angular compiler is grossly huge.

Source Show
◀ Wstecz