📖 Scenario: You are creating a Docker image for a simple web application. You want to use one base image to build the application and another smaller image to run it. This helps keep the final image small and efficient.
🎯 Goal: Build a Dockerfile that uses two FROM statements: one to build the app and one to run the app. You will copy the built files from the first image to the second image.
📋 What You'll Learn
Create a Dockerfile with two FROM statements.
Use node:18 as the first base image to build the app.
Use nginx:alpine as the second base image to serve the app.
Copy the built app files from the first image to the second image.
Expose port 80 in the final image.
💡 Why This Matters
🌍 Real World
Multi-stage Dockerfiles are used to optimize container images by separating build and runtime environments. This reduces image size and improves security.
💼 Career
Understanding multi-stage builds is important for DevOps roles that involve containerization and deployment pipelines.
Progress0 / 4 steps
1
Create the first base image with Node.js
Write the first FROM statement using the exact image node:18. Then create a working directory called /app.
Docker
Hint
Start your Dockerfile with FROM node:18 and then add WORKDIR /app on the next line.
2
Add build commands and second base image
Add commands to copy package.json and install dependencies using npm install. Then add a second FROM statement using the exact image nginx:alpine.
Docker
Hint
Use COPY package.json . to copy the file and RUN npm install to install dependencies. Then start the second stage with FROM nginx:alpine.
3
Copy built files and expose port
Copy the built app files from the first stage to /usr/share/nginx/html in the second stage using COPY --from=0 /app/build /usr/share/nginx/html. Then expose port 80.
Docker
Hint
Use COPY --from=0 to copy files from the first stage. Then add EXPOSE 80 to open the port.
4
Print the final Dockerfile content
Print the entire Dockerfile content as a single string exactly as written in previous steps.
Docker
Hint
Use a triple-quoted string to store the Dockerfile content and print it.
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
Step 1: Understand the role of FROM in Dockerfile
The FROM statement sets the base image for building a Docker image.
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.
Final Answer:
To create multi-stage builds that reduce final image size -> Option A
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
Step 1: Recall the correct COPY syntax for multi-stage
The correct flag to copy from another stage is --from=stage_name.
Step 2: Match the option with correct syntax
Only COPY --from=builder /app/build /app uses --from=builder, which is valid syntax.
Final Answer:
COPY --from=builder /app/build /app -> Option B
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
Step 1: Analyze the multi-stage build steps
The first stage builds the app with Node.js. The second stage uses nginx base image.
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.
Final Answer:
Final image only contains nginx and the built files, keeping it small -> Option C
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
Step 1: Check stage names in FROM statements
The first stage is named 'builder', but COPY uses 'build' which is undefined.
Step 2: Understand COPY --from requires exact stage name
Stage names must match exactly; otherwise, Docker throws an error.
Final Answer:
The stage name 'build' does not match the defined stage 'builder' -> Option A
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
Step 1: Identify the build stage with Go compiler
Stage named 'builder' uses golang image to compile the app.
Step 2: Use a minimal runtime image for final stage
The final stage uses alpine (small image) and copies only the binary from builder.
Step 3: Verify COPY --from syntax and CMD
COPY uses --from=builder to get binary; CMD runs the binary correctly.
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
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 unknownstrongwhile earning +1 Grip toward your certificate.