What are the benefits of using an application specific Docker image vs a generic OS? I'll use an angular app here as a contextual example, but this should apply to other apps as well.

Example 1 | Use application specific images:

FROM node as build
RUN npm install
COPY package-lock.json
RUN ng build --prod

FROM nginx
# ... move files from build to nginx/html

Example 2 | Use a linux base image:

FROM ubuntu
RUN apt-get install npm
RUN apt-get install nginx
COPY . . 
RUN npm install
# ... build Angular app and mv files to nginx/html

Example 3 | Build angular app outside of docker first and:

FROM nginx
COPY . .
# mv files to nginx/html

What are the advantages / disadvantages to doing it one of these 3 ways? Are there image size differences? Does the orchestration environment (kubernetes) need access to the base images or is everything needed included when it's pushed? Which way is considered best practice?


They're all functionally equivalent. When you docker push or docker pull an image (or mention it in a Kubernetes manifest), all of its layers are pushed or pulled, so you always get a complete image with all of its dependencies at the point where it was built. (It turns out the versioned ubuntu images are re-released pretty routinely to include current security patches.)

Building your application outside of Docker was pretty common before there were multi-stage builds. There's nothing wrong with doing it, if it makes sense. It makes more sense if your built application artifact is portable (in your example, Webpack JavaScript/HTML/CSS artifacts; Java .jar files work well here too). This is also pretty easy to plug into an existing CI system that produces the artifacts, and then you just need to wrap them up in an image.

Using prebuilt images like nginx or node, or building your own on top of ubuntu or alpine, is mostly a matter of taste and organizational requirements. Building an image FROM node will be easier than building your own Node image and can get you running faster; if you start FROM ubuntu then you know exactly who built it and what security updates and packages are in it.

If you're pinning to specific versions of software, the other important thing to be aware of is that the Docker Hub packages eventually stop getting updates. If you're using node:8 that image isn't being automatically built any more; if you pin to a more specific version, node:12.13 or node:12.14.0 aren't getting updates either. (As of this writing the Docker Hub node page lists 12.14.1 as the current LTS build.) That could be an issue if you're forced to take a language runtime update to get an OS-level security fix.

  • Thank you! This helps my understand a lot. – MrAlexBailey Feb 7 '20 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.