DOCKER - 4 6 The bases of the Dockerfile
The Dockerfile is the recipe Docker uses to bake an image. Every official image you've used was built from one, and you can read them on Docker Hub. Despite looking like a shell script, a Dockerfile is its own little language, with its own instructions. The default filename is Dockerfile (capital D), but the CLI's -f flag lets you point at any file you want.
The main instructions, line by line
FROM is mandatory and must come first. It picks the base image — usually a minimal distribution like Debian or, more often, Alpine. These minimal images are far smaller than what a regular VM ISO would install: a base Ubuntu container doesn't even ship curl. Because they're official images, they receive timely security patches. The big advantage of starting from a distro is reusing its package manager (apt, apk) to install only what you need.
ENV sets environment variables — the recommended way to pass build-time and runtime configuration into containers. The Nginx official Dockerfile, for example, uses an ENV like NGINX_VERSION so the later instructions can reference it without hardcoding the version repeatedly.
RUN executes shell commands inside the image during the build: install packages, unzip files, patch configuration, run shell scripts you've copied in. Each instruction in a Dockerfile creates a new image layer, so the convention is to chain several shell commands into a single RUN with && — fewer layers, smaller image, faster builds.
FROM debian:stretch-slim— mandatory base imageENV NGINX_VERSION 1.21.6— env vars used downstreamRUN apt-get update && apt-get install -y nginx— install software with the distro's package managerRUN ln -sf /dev/stdout /var/log/nginx/access.log— redirect file logs tostdoutEXPOSE 80 443— declare ports, document only — no host bindingCMD ["nginx", "-g", "daemon off;"]— the process to run when the container starts
For logs, the Docker way is to send everything to stdout / stderr instead of writing to log files inside the container. The Nginx Dockerfile symlinks its access and error logs to those streams, and Docker captures and routes them through its log drivers. EXPOSE only documents which TCP/UDP ports the application listens on inside the virtual network — it does not publish them on the host; you still need -p at run time. CMD is the final mandatory instruction: it defines what process runs each time a container is started from this image. Full reference docs live on docs.docker.com.
Summary
A Dockerfile is a Docker-specific language (not a shell script) that serves as a recipe to build container images. It relies on essential commands like FROM (specifying the base image), ENV (defining environment variables), RUN (executing shell commands during build), and EXPOSE (declaring exposed ports). Understanding these foundational commands and best practices is critical for creating efficient, maintainable Docker containers.
Key points
- FROM command is mandatory in every Dockerfile and typically uses minimal distributions like Alpine or Debian to save time and space
- ENV command defines environment variables, the primary mechanism for configuring values and keys during container build and runtime
- RUN command executes shell commands inside the container during build, commonly used for package installation, decompression, and file modifications
- Chaining RUN commands with && ensures they execute in a single layer, saving build time and space
- Container logs should be sent to stdout and stderr, not to log files—Docker's log drivers automatically capture and manage all container output
- EXPOSE command declares which ports the container exposes to external networks, though it does not automatically open any TCP or UDP ports
FAQ
Why use minimal distributions like Alpine or Debian as base images in Dockerfile?
Minimal distributions are much smaller than full operating systems like Ubuntu, saving both build time and storage space. They are official images kept up-to-date with the latest security patches, making them trustworthy and reliable for container foundations.
What is the purpose of the ENV command in a Dockerfile?
ENV defines environment variables, which is the primary way to set configuration values and keys for building and running containers. These variables remain available throughout the container's lifecycle.
How should logging be handled inside Docker containers?
Containers should send all logs to stdout and stderr, not to log files. Docker's log drivers automatically capture and manage container output, eliminating the complexity of managing individual log files across multiple containers.