Bird
Raised Fist0
Dockerdevops~5 mins

Multiple FROM statements in Docker - Commands & Configuration

Choose your learning style10 modes available
Introduction
Sometimes you need to build a Docker image in steps, using one image to prepare files and another to run the app. Multiple FROM statements let you do this in one Dockerfile, making your images smaller and cleaner.
When you want to compile code in one image and run it in a smaller image.
When you need to separate build tools from runtime environment to reduce image size.
When you want to copy only the necessary files from a build stage to the final image.
When you want to create multi-stage builds to optimize Docker images for production.
When you want to keep your Dockerfile simple but efficient by combining build and runtime steps.
Config File - Dockerfile
Dockerfile
FROM node:18 AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:1.23
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

This Dockerfile has two stages:

  • builder: Uses the Node.js image to install dependencies and build the app.
  • final stage: Uses a lightweight Nginx image to serve the built app files copied from the builder stage.

This keeps the final image small and only includes what is needed to run the app.

Commands
Builds the Docker image using the Dockerfile with multiple FROM statements to create a multi-stage build.
Terminal
docker build -t my-multi-stage-app .
Expected OutputExpected
[+] Building 12.3s (10/10) FINISHED => [builder 1/6] FROM node:18 AS builder 2.0s => CACHED [builder 2/6] WORKDIR /app 0.0s => CACHED [builder 3/6] COPY package.json package-lock.json ./ 0.0s => [builder 4/6] RUN npm install 7.5s => CACHED [builder 5/6] COPY . . 0.0s => [builder 6/6] RUN npm run build 2.5s => [final 1/3] FROM nginx:1.23 1.0s => [final 2/3] COPY --from=builder /app/build /usr/share/nginx/html 0.5s => [final 3/3] EXPOSE 80 0.0s => exporting to image 0.3s => writing image sha256:abcdef1234567890 0.0s => naming to docker.io/library/my-multi-stage-app 0.0s
Lists the Docker images to verify that the multi-stage image was created successfully.
Terminal
docker images my-multi-stage-app
Expected OutputExpected
REPOSITORY TAG IMAGE ID CREATED SIZE my-multi-stage-app latest abcdef123456 10 seconds ago 45MB
Runs the built image in a container, mapping port 8080 on the host to port 80 in the container to serve the app.
Terminal
docker run -d -p 8080:80 my-multi-stage-app
Expected OutputExpected
d1e2f3a4b5c6d7e8f9g0h1i2j3k4l5m6n7o8p9q0r1s2t3u4v5w6x7y8z9a0b1c2
→
-d - Run container in detached mode (in the background)
→
-p 8080:80 - Map port 8080 on host to port 80 in container
Checks that the app is running by requesting the homepage served by Nginx inside the container.
Terminal
curl http://localhost:8080
Expected OutputExpected
<!DOCTYPE html><html><head><title>My App</title></head><body><h1>Welcome to My App</h1></body></html>
Key Concept

If you remember nothing else from this pattern, remember: multiple FROM statements let you build in stages and copy only what you need to keep images small and efficient.

Common Mistakes
Not using AS to name build stages and then trying to copy files from unnamed stages.
Docker cannot copy files from a stage without a name, so the build fails.
Always name your build stages with AS and use that name in COPY --from=stage.
Copying unnecessary files from the build stage to the final image.
This makes the final image larger and slower to deploy.
Copy only the files needed to run the app, like build output folders.
Using a large base image for the final stage instead of a lightweight one.
This increases the image size and attack surface.
Use a minimal image like nginx or alpine for the final stage.
Summary
Use multiple FROM statements to create multi-stage Docker builds.
Name build stages with AS to copy files between stages.
Build with docker build and verify the image with docker images.
Run the container mapping ports to access the app.
Use curl or a browser to check the app is served correctly.

Practice

(1/5)
1. What is the main purpose of using multiple FROM statements in a Dockerfile?
easy
A. To create multi-stage builds that reduce final image size
B. To run multiple containers at the same time
C. To specify different base images for different containers
D. To define environment variables for the container

Solution

  1. Step 1: Understand the role of FROM in Dockerfile

    The FROM statement sets the base image for building a Docker image.
  2. Step 2: Recognize multi-stage build benefits

    Using multiple FROM statements allows building in stages, copying only needed files to the final image, reducing size.
  3. Final Answer:

    To create multi-stage builds that reduce final image size -> Option A
  4. Quick Check:

    Multiple FROM = multi-stage build [OK]
Hint: Multiple FROM means multi-stage build for smaller images [OK]
Common Mistakes:
  • Thinking multiple FROM runs multiple containers
  • Confusing FROM with environment variable setting
  • Assuming FROM defines runtime commands
2. Which of the following is the correct syntax to copy files from a previous build stage named builder?
easy
A. COPY --stage=builder /app/build /app
B. COPY --from=builder /app/build /app
C. COPY --source=builder /app/build /app
D. COPY --stage-name=builder /app/build /app

Solution

  1. Step 1: Recall the correct COPY syntax for multi-stage

    The correct flag to copy from another stage is --from=stage_name.
  2. Step 2: Match the option with correct syntax

    Only COPY --from=builder /app/build /app uses --from=builder, which is valid syntax.
  3. Final Answer:

    COPY --from=builder /app/build /app -> Option B
  4. Quick Check:

    Copy from stage uses --from [OK]
Hint: Use COPY --from=stage_name to copy files between stages [OK]
Common Mistakes:
  • Using --stage or --source instead of --from
  • Misspelling the flag name
  • Omitting the equals sign (=) after --from
3. Given this Dockerfile snippet, what will be the final image size behavior?
FROM node:18 AS builder
RUN npm install && npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
medium
A. Final image includes full Node.js and npm layers, making it large
B. Final image will fail to build due to missing /app/build directory
C. Final image only contains nginx and the built files, keeping it small
D. Final image contains both Node.js and nginx running simultaneously

Solution

  1. Step 1: Analyze the multi-stage build steps

    The first stage builds the app with Node.js. The second stage uses nginx base image.
  2. Step 2: Understand the COPY --from usage

    The built files from the builder stage are copied into nginx image, but Node.js layers are not included.
  3. Final Answer:

    Final image only contains nginx and the built files, keeping it small -> Option C
  4. Quick Check:

    Multi-stage copy keeps final image small [OK]
Hint: Final image excludes build tools if copied from previous stage [OK]
Common Mistakes:
  • Assuming all build layers stay in final image
  • Thinking COPY --from copies the entire image
  • Confusing build failure with missing files
4. Identify the error in this Dockerfile snippet using multiple FROM statements:
FROM python:3.12 AS builder
RUN pip install -r requirements.txt
FROM alpine
COPY --from=build /app /app
medium
A. The stage name 'build' does not match the defined stage 'builder'
B. Alpine image cannot be used after python image
C. COPY command syntax is incorrect; missing destination path
D. pip install command should be in the second stage

Solution

  1. Step 1: Check stage names in FROM statements

    The first stage is named 'builder', but COPY uses 'build' which is undefined.
  2. Step 2: Understand COPY --from requires exact stage name

    Stage names must match exactly; otherwise, Docker throws an error.
  3. Final Answer:

    The stage name 'build' does not match the defined stage 'builder' -> Option A
  4. Quick Check:

    Stage names must match exactly in COPY --from [OK]
Hint: Match stage names exactly in COPY --from [OK]
Common Mistakes:
  • Assuming similar names are accepted
  • Thinking base image order matters here
  • Ignoring COPY destination path correctness
5. You want to build a Docker image that compiles a Go application and then creates a minimal final image with only the compiled binary. Which Dockerfile snippet correctly uses multiple FROM statements to achieve this?
hard
A. FROM golang:1.20 AS builder WORKDIR /app COPY . . RUN go build -o myapp FROM scratch COPY --from=builder /app/myapp /myapp CMD ["/myapp"]
B. FROM golang:1.20 WORKDIR /app COPY . . RUN go build -o myapp FROM alpine COPY /app/myapp /myapp CMD ["/myapp"]
C. FROM alpine AS builder RUN apk add --no-cache go WORKDIR /app COPY . . RUN go build -o myapp FROM alpine COPY --from=builder /app/myapp /myapp CMD ["/myapp"]
D. FROM golang:1.20 AS builder WORKDIR /app COPY . . RUN go build -o myapp FROM alpine COPY --from=builder /app/myapp /myapp CMD ["/myapp"]

Solution

  1. Step 1: Identify the build stage with Go compiler

    Stage named 'builder' uses golang image to compile the app.
  2. Step 2: Use a minimal runtime image for final stage

    The final stage uses alpine (small image) and copies only the binary from builder.
  3. Step 3: Verify COPY --from syntax and CMD

    COPY uses --from=builder to get binary; CMD runs the binary correctly.
  4. Final Answer:

    FROM golang:1.20 AS builder WORKDIR /app COPY . . RUN go build -o myapp FROM alpine COPY --from=builder /app/myapp /myapp CMD ["/myapp"] -> Option D
  5. Quick Check:

    Multi-stage build with builder and minimal final image [OK]
Hint: Use builder stage for compile, minimal image for final [OK]
Common Mistakes:
  • Using scratch without proper setup
  • Copying files without --from flag
  • Building in final stage instead of builder
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard