0
0
DockerHow-ToBeginner · 4 min read

Best Practices for Writing Dockerfile: Clean and Efficient Containers

Use multi-stage builds to keep images small, specify exact base image versions for consistency, and minimize layers by combining commands. Always use a non-root user and include a .dockerignore file to exclude unnecessary files.
📐

Syntax

A Dockerfile is a text file with instructions to build a Docker image. Key instructions include:

  • FROM: sets the base image.
  • RUN: runs commands inside the image.
  • COPY or ADD: copies files into the image.
  • CMD or ENTRYPOINT: defines the container start command.
  • USER: switches to a non-root user for security.

Each instruction creates a new layer, so combining commands reduces image size.

dockerfile
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y curl
COPY app /app
USER appuser
CMD ["/app/start.sh"]
💻

Example

This example shows a multi-stage Dockerfile that builds a Go application and creates a small final image with only the binary.

dockerfile
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM debian:bullseye-slim
RUN useradd -m appuser
USER appuser
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
⚠️

Common Pitfalls

Common mistakes include:

  • Using latest tag in FROM, causing unpredictable builds.
  • Running many RUN commands separately, increasing image size.
  • Running containers as root, which is a security risk.
  • Not using .dockerignore, which copies unnecessary files and slows builds.
dockerfile
### Wrong way:
FROM node:latest
RUN npm install
RUN npm run build

### Right way:
FROM node:18.16.0
RUN npm install && npm run build
USER node

# .dockerignore
node_modules
.git
Dockerfile
📊

Quick Reference

  • Always pin base image versions (avoid latest).
  • Use multi-stage builds to reduce final image size.
  • Combine commands with && to minimize layers.
  • Use a non-root user with USER for security.
  • Include a .dockerignore file to exclude unnecessary files.
  • Keep Dockerfile readable and well-commented.

Key Takeaways

Pin base image versions to ensure consistent builds.
Use multi-stage builds to keep images small and efficient.
Combine commands in one RUN to reduce image layers.
Run containers as a non-root user for better security.
Use a .dockerignore file to speed up builds and reduce image size.