Home Explore Blog CI



docker

3rd chunk of `content/get-started/workshop/09_image_best.md`
de9163fdca84ca4baa23d969c47b0f3f83e0d5beaf9c2edb0000000100000f4f
    => [3/5] COPY package.json yarn.lock ./
    => [4/5] RUN yarn install --production
    => [5/5] COPY . .
    => exporting to image
    => => exporting layers
    => => writing image     sha256:d6f819013566c54c50124ed94d5e66c452325327217f4f04399b45f94e37d25
    => => naming to docker.io/library/getting-started
    ```

3. Now, make a change to the `src/static/index.html` file. For example, change the `<title>` to "The Awesome Todo App".

4. Build the Docker image now using `docker build -t getting-started .` again. This time, your output should look a little different.

    ```plaintext
    [+] Building 1.2s (10/10) FINISHED
    => [internal] load build definition from Dockerfile
    => => transferring dockerfile: 37B
    => [internal] load .dockerignore
    => => transferring context: 2B
    => [internal] load metadata for docker.io/library/node:lts-alpine
    => [internal] load build context
    => => transferring context: 450.43kB
    => [1/5] FROM docker.io/library/node:lts-alpine
    => CACHED [2/5] WORKDIR /app
    => CACHED [3/5] COPY package.json yarn.lock ./
    => CACHED [4/5] RUN yarn install --production
    => [5/5] COPY . .
    => exporting to image
    => => exporting layers
    => => writing image     sha256:91790c87bcb096a83c2bd4eb512bc8b134c757cda0bdee4038187f98148e2eda
    => => naming to docker.io/library/getting-started
    ```

    First off, you should notice that the build was much faster. And, you'll see
    that several steps are using previously cached layers. Pushing and pulling
    this image and updates to it will be much faster as well. 

## Multi-stage builds

Multi-stage builds are an incredibly powerful
tool to help use multiple stages to create an image. There are several advantages for them:

- Separate build-time dependencies from runtime dependencies
- Reduce overall image size by shipping only what your app needs to run

### Maven/Tomcat example

When building Java-based applications, you need a JDK to compile the source code to Java bytecode. However,
that JDK isn't needed in production. Also, you might be using tools like Maven or Gradle to help build the app.
Those also aren't needed in your final image. Multi-stage builds help.

```dockerfile
# syntax=docker/dockerfile:1
FROM maven AS build
WORKDIR /app
COPY . .
RUN mvn package

FROM tomcat
COPY --from=build /app/target/file.war /usr/local/tomcat/webapps 
```

In this example, you use one stage (called `build`) to perform the actual Java build using Maven. In the second
stage (starting at `FROM tomcat`), you copy in files from the `build` stage. The final image is only the last stage
being created, which can be overridden using the `--target` flag.

### React example

When building React applications, you need a Node environment to compile the JS code (typically JSX), SASS stylesheets,
and more into static HTML, JS, and CSS. If you aren't doing server-side rendering, you don't even need a Node environment
for your production build. You can ship the static resources in a static nginx container.

```dockerfile
# syntax=docker/dockerfile:1
FROM node:lts AS build
WORKDIR /app
COPY package* yarn.lock ./
RUN yarn install
COPY public ./public
COPY src ./src
RUN yarn run build

FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
```

In the previous Dockerfile example, it uses the `node:lts` image to perform the build (maximizing layer caching) and then copies the output
into an nginx container.

## Summary

In this section, you learned a few image building best practices, including layer caching and multi-stage builds.

Related information:
 - [Dockerfile reference](/reference/dockerfile/)
 - [Dockerfile best practices](/manuals/build/building/best-practices.md)

## Next steps

In the next section, you'll learn about additional resources you can use to continue learning about containers.

{{< button text="What next" url="10_what_next.md" >}}

Title: Multi-Stage Builds and Dockerfile Best Practices
Summary
This section highlights the benefits of multi-stage builds for Docker images. Multi-stage builds allow for the separation of build-time and runtime dependencies, leading to smaller image sizes. Examples for Maven/Tomcat and React applications demonstrate how to use different stages for building and running applications, improving efficiency and security. Layer caching and multi-stage builds are presented as key image building best practices, with links to additional resources for further learning.