This is not so much "my code is wrong" as it is a question about what the best approach is. I'm building a small webapp based on Aurelia (using jspm) and Flask-restful for the backend. I'm trying different things when it comes to building a Docker container for all of this (for now its a single container containing both frontend and backend).
The 2 approaches I've tried:
Perform all dependency installs (npm / jspm) "outside" the container and just copy all artifacts into the container using Dockerfile's "COPY" statement. This works fine, but the "build artifact" and even listing of all files is extremely slow. Aurelia generates a huge footprint in terms of number of files, so it takes forever for Docker build to complete.
Perform all dependency installs inside the container (using RUN jspm install etc in the Dockerfile). The good thing with this approach is that the host computer is left untouched and doesn't have any requirements except git and Docker-engine. The problem is that jspm often fails because of git rate limiting since most jspm packages are using git and not its "own" repo. To counter this I'd have to deal with sending github credentials into the container at build time, which adds a ton of complexity.
A hybrid approach where I configre a separate "base container" using a tag which includes "most" of the required packages. This combined with #2 would allow me to base my daily builds on an image where at least most of the dependencies are already met. I would have to implement a separate build process for keeping the base container up to date.
For clarity: My local dev environment is fine, the problem is (very) slow builds in CI - which queues up other jobs.
I'm just interested in what people are doing - I'm sure I'm not the only one who has faced the problem of excessive build times using Docker and especially with file-heavy frontend frameworks.
I favour the 'cascading' container approach (which is one of the great features of Docker) - this is basically the same as your hybrid approach. Although nothing stopping you from having several images used in sequence rather than just a single base container of course.
You cascade your builds based on the hierarchy of your dependencies. You can also reduce the build time of each docker image in the chain, speeding up your continual builds.
Downside is that this introduces more complexity as you require a new build pipeline for each separated image.
For transient files such as npm packages I also favour building these within the container - this makes your images and build setup more portable although I normally keep git outside of containers and let the build wrapper handle that, this keeps your git creds more secure.
You say your builds are slow but why is that necessarily a problem? You shouldn't need to be rebuilding all the time once you've got the environments set up? Just use volume mounts to develop against running containers and let the build process kick off in the background whenever there's a merge (or whatever) all handled by your build server.