Bird
Raised Fist0
Dockerdevops~5 mins

Development vs production Dockerfiles - CLI Comparison

Choose your learning style10 modes available
Introduction
When building software with Docker, you often need different setups for development and production. Development Dockerfiles include tools and settings to help you write and test code easily. Production Dockerfiles focus on making the app small, fast, and secure for users.
When you want to run your app with live code changes during development without rebuilding the image every time.
When you need debugging tools and extra logs while developing your app.
When you want a smaller, faster Docker image to deploy to users in production.
When you want to avoid including development tools and files in your production image for security and performance.
When you want to use multi-stage builds to share code but separate development and production environments.
Config File - Dockerfile
Dockerfile
### Development stage
FROM node:18-alpine AS development
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]

### Production stage
FROM node:18-alpine AS production
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install --production
COPY . .
CMD ["node", "server.js"]

This Dockerfile uses two stages: development and production.

The development stage installs all dependencies and runs the app with live reload for easy coding.

The production stage installs only the necessary packages to run the app, making the image smaller and faster.

You can build either stage depending on your need.

Commands
Builds the Docker image using the development stage. This image includes all tools and dependencies for coding and testing.
Terminal
docker build --target development -t my-app-dev .
Expected OutputExpected
Sending build context to Docker daemon 10.24MB Step 1/10 : FROM node:18-alpine AS development 18-alpine: Pulling from library/node ... Successfully built abcdef123456 Successfully tagged my-app-dev:latest
→
--target - Specifies which stage in the Dockerfile to build
→
-t - Names the image for easy reference
Runs the development image and maps port 3000 so you can access the app in your browser during development.
Terminal
docker run -p 3000:3000 my-app-dev
Expected OutputExpected
Starting development server... Listening on http://localhost:3000
→
-p - Maps container port to host port
Builds the Docker image using the production stage. This image is optimized for running the app in production with only necessary files.
Terminal
docker build --target production -t my-app-prod .
Expected OutputExpected
Sending build context to Docker daemon 10.24MB Step 1/10 : FROM node:18-alpine AS production 18-alpine: Pulling from library/node ... Successfully built 123456abcdef Successfully tagged my-app-prod:latest
→
--target - Specifies which stage in the Dockerfile to build
→
-t - Names the image for easy reference
Runs the production image and maps port 8080 on your machine to port 3000 in the container to serve the app to users.
Terminal
docker run -p 8080:3000 my-app-prod
Expected OutputExpected
Server started on port 3000
→
-p - Maps container port to host port
Key Concept

If you remember nothing else from this pattern, remember: use separate Dockerfile stages to keep development tools out of your production image for better performance and security.

Common Mistakes
Building the Docker image without specifying the --target flag and expecting a development or production image.
Docker will build the last stage by default, which may not be the one you want.
Always use --target development or --target production to build the correct stage.
Including development dependencies in the production image by copying all files and running full npm install.
This makes the production image larger and may expose unnecessary tools or files.
Use npm install --production in the production stage to install only needed packages.
Running the production image with the development command like npm run dev.
The production image may not have development tools or live reload, causing errors or unexpected behavior.
Use the correct CMD for each stage: npm run dev for development, node server.js for production.
Summary
Use multi-stage Dockerfiles to separate development and production environments.
Build development images with all tools for coding and testing using --target development.
Build production images with only necessary files and dependencies using --target production.
Run containers with appropriate port mappings to access your app.
Avoid mixing development tools in production images for better security and performance.

Practice

(1/5)
1. Why do we use separate Dockerfiles for development and production environments?
easy
A. Because development needs debugging tools and production needs optimized images
B. Because production requires more debugging tools than development
C. Because development images must be smaller than production images
D. Because production Dockerfiles always include all source code

Solution

  1. Step 1: Understand development Dockerfile purpose

    Development Dockerfiles include debugging tools and full dependencies to help developers test and debug easily.
  2. Step 2: Understand production Dockerfile purpose

    Production Dockerfiles are optimized for smaller size, speed, and security, removing unnecessary tools.
  3. Final Answer:

    Because development needs debugging tools and production needs optimized images -> Option A
  4. Quick Check:

    Separate Dockerfiles fit different environment needs [OK]
Hint: Dev needs tools; prod needs speed and security [OK]
Common Mistakes:
  • Thinking production needs more debugging tools
  • Assuming development images must be smaller
  • Believing production always includes all source code
2. Which of the following is a correct way to specify a base image in a production Dockerfile?
easy
A. BASE node:alpine
B. FROM node:latest
C. FROM alpine:node
D. FROM node:alpine

Solution

  1. Step 1: Identify correct Dockerfile syntax for base image

    The correct keyword to specify a base image is 'FROM', followed by the image name and tag.
  2. Step 2: Choose a lightweight base image for production

    For production, 'node:alpine' is a lightweight image suitable for smaller, optimized containers.
  3. Final Answer:

    FROM node:alpine -> Option D
  4. Quick Check:

    Use 'FROM' and lightweight image for production [OK]
Hint: Use 'FROM' and lightweight tags like alpine for production [OK]
Common Mistakes:
  • Using 'BASE' instead of 'FROM'
  • Incorrect image name order like 'alpine:node'
  • Using 'latest' tag for production images
3. Given this production Dockerfile snippet:
FROM node:alpine
WORKDIR /app
COPY package.json ./
RUN npm install --production
COPY . .
CMD ["node", "server.js"]

What is the main effect of the npm install --production command?
medium
A. Installs all dependencies including devDependencies
B. Installs no dependencies at all
C. Installs only production dependencies, skipping devDependencies
D. Installs only devDependencies

Solution

  1. Step 1: Understand npm install --production flag

    The '--production' flag tells npm to install only dependencies needed for running the app, skipping devDependencies used for development.
  2. Step 2: Relate to production Dockerfile purpose

    Skipping devDependencies reduces image size and improves security for production environments.
  3. Final Answer:

    Installs only production dependencies, skipping devDependencies -> Option C
  4. Quick Check:

    npm install --production = only production deps [OK]
Hint: npm install --production skips devDependencies [OK]
Common Mistakes:
  • Assuming it installs all dependencies
  • Thinking it installs no dependencies
  • Confusing devDependencies with production dependencies
4. You have a development Dockerfile that installs extra debugging tools but your production image is unexpectedly large. What is a likely cause?
medium
A. You used the development Dockerfile to build the production image
B. You forgot to copy source code in production Dockerfile
C. You used a smaller base image in production
D. You ran npm install without --production flag in development

Solution

  1. Step 1: Identify cause of large production image

    If the production image is large, it may include unnecessary development tools and dependencies.
  2. Step 2: Check which Dockerfile was used for production build

    Using the development Dockerfile for production will include extra tools, increasing image size.
  3. Final Answer:

    You used the development Dockerfile to build the production image -> Option A
  4. Quick Check:

    Wrong Dockerfile causes large production image [OK]
Hint: Use correct Dockerfile for each environment [OK]
Common Mistakes:
  • Assuming missing source code causes large image
  • Thinking smaller base image increases size
  • Confusing npm install flags in development
5. You want to create a multi-stage Dockerfile that uses a full Node.js image for development and a lightweight Alpine image for production. Which snippet correctly achieves this?
hard
A. FROM node:alpine AS build WORKDIR /app COPY . . RUN npm install FROM node:alpine COPY --from=build /app . CMD ["node", "server.js"]
B. FROM node:latest AS build WORKDIR /app COPY . . RUN npm install FROM node:alpine COPY --from=build /app . CMD ["node", "server.js"]
C. FROM node:alpine AS build WORKDIR /app COPY . . RUN npm install --production FROM node:latest COPY --from=build /app . CMD ["node", "server.js"]
D. FROM node:latest WORKDIR /app COPY . . RUN npm install CMD ["node", "server.js"]

Solution

  1. Step 1: Identify multi-stage build structure

    The first stage uses a full Node.js image (node:latest) for building with all tools, suitable for development.
  2. Step 2: Use lightweight Alpine image for final production stage

    The second stage uses node:alpine to copy only necessary files from build stage, creating a smaller production image.
  3. Step 3: Verify correct order and commands

    FROM node:latest AS build WORKDIR /app COPY . . RUN npm install FROM node:alpine COPY --from=build /app . CMD ["node", "server.js"] correctly uses 'AS build' for first stage and copies from it to the lightweight image.
  4. Final Answer:

    FROM node:latest AS build WORKDIR /app COPY . . RUN npm install FROM node:alpine COPY --from=build /app . CMD ["node", "server.js"] -> Option B
  5. Quick Check:

    Multi-stage: full image build + alpine production [OK]
Hint: Use full image first, then alpine with COPY --from=build [OK]
Common Mistakes:
  • Using alpine for build stage losing dev tools
  • Using latest image for final production stage
  • Not using multi-stage COPY syntax
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