<p>They're all functionally equivalent.  When you <code>docker push</code> or <code>docker pull</code> 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 <code>ubuntu</code> images are re-released pretty routinely to include current security patches.)</p>

<p>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 <code>.jar</code> 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.</p>

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

<p>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 <code>node:8</code> that image isn't being automatically built any more; if you pin to a more specific version, <code>node:12.13</code> or <code>node:12.14.0</code> aren't getting updates either.  (As of this writing the <a href="https://hub.docker.com/_/node" rel="nofollow noreferrer">Docker Hub <code>node</code> page</a> lists <code>12.14.1</code> 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.</p>

CC BY-SA 4.0
2020-02-07T14:43:49.460Z
Thank you! This helps my understand a lot.
MrAlexBailey
CC BY-SA 4.0
2020-02-07T00:40:32.490Z
2020-02-07T00:40:32.490Z
David Maze
<p>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.</p>

<p>Example 1 | Use application specific images:</p>

<pre><code>FROM node as build
RUN npm install
COPY package-lock.json
RUN ng build --prod

FROM nginx
# ... move files from build to nginx/html
EXPOSE port
</code></pre>

<p>Example 2 | Use a linux base image:</p>

<pre><code>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
</code></pre>

<p>Example 3 | Build angular app outside of docker first and:</p>

<pre><code>FROM nginx
COPY . .
# mv files to nginx/html
EXPOSE port
</code></pre>

<p>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?</p>

<docker><kubernetes>
Using a ubuntu base image vs an application specific image (node, python, etc)
MrAlexBailey
# Using a ubuntu base image vs an application specific image (node, python, etc)

(Asked by: username_0 on 2020-02-06)

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
EXPOSE port

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
EXPOSE port

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?

**Tags:** docker, kubernetes


---

## 1 answers

### Answer by username_1 on 2020-02-07. Score: 2 | Accepted answer

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](https://hub.docker.com/_/node) 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.

> **Comments:**
> **username_0**: Thank you! This helps my understand a lot.  

---

