Building Images: From Manual Commits to the Dockerfile Revolution
Source: Dev.to
1. The Manual Way: Building Images with docker commit
A. How docker commit Works
-
Start a base container – run an image with interactive shell access.
docker run -it --name my_sandbox ubuntu:latest bash -
Make manual changes – install or configure software inside the container, e.g.:
apt-get update && apt-get install -y nginx -
Exit the container – type
exitto stop it while preserving the changes in the writable layer. -
Commit the changes – save the container’s current state as a new, immutable image.
docker commit :
Example
docker commit my_sandbox my_custom_nginx:v1.0
B. Upgrading a Committed Image
To “upgrade” the image, repeat the process:
- Start a new container from
my_custom_nginx:v1.0. - Apply further manual changes (e.g., update Nginx configuration).
- Commit the container again, tagging the new image.
docker commit my_custom_nginx:v2.0
2. The Limitations of docker commit
| Limitation | Description | Impact |
|---|---|---|
| No Traceability | No record of the commands run inside the container; you can’t see why a file exists or how a package was installed. | Auditing, debugging, and security checks become nearly impossible. |
| Non‑Reproducible | Deleting the image forces you to manually repeat the exact shell commands in the exact order to rebuild it. | Inconsistent development and deployment across environments. |
| Large Images | docker commit often captures unnecessary files (e.g., temporary install caches) in the image layer. | Bloated images that are slow to pull and consume more disk space. |
| Security Risk | You cannot easily verify the contents or history of the image layers. | Increased risk of hidden vulnerabilities. |
3. The Dockerfile Revolution
A Dockerfile is a plain‑text file containing a series of instructions that Docker executes sequentially to build an image.
Why Use a Dockerfile?
- Automation – the entire build process is fully automated.
- Traceability – every command is explicitly listed, providing a transparent, auditable history.
- Reproducibility – anyone with the Dockerfile can rebuild the exact same image consistently.
The Dockerfile becomes the source code for the image, enabling best‑practice builds that are small, secure, and version‑controlled.
4. Essential Dockerfile Instructions (Part 1)
| Instruction | Purpose | Creates Layer? | Example |
|---|---|---|---|
FROM | Specifies the base image for the build (must be first). | Yes | FROM node:18-alpine |
RUN | Executes a command in a new layer (e.g., installing packages). | Yes | RUN apk add --no-cache git |
WORKDIR | Sets the working directory for subsequent RUN, CMD, ENTRYPOINT, COPY, or ADD. | Yes | WORKDIR /app |
COPY | Copies files/directories from the host into the image filesystem. | Yes | COPY package.json /app |
CMD | Provides the default command for a running container; typically overridden at start. Only one CMD allowed. | Yes | CMD ["node", "server.js"] |
EXPOSE | Documents which ports the container listens on at runtime (does not publish them). | No | EXPOSE 8080 |
Understanding CMD vs. RUN
RUN– Executes during the image build (e.g., installing software).CMD– Executes when the container starts (e.g., launching the application).
Small Explanations on Omitted Topics
Networking
The EXPOSE instruction only documents the ports an application uses. Actual port mapping (e.g., -p 8080:80) is performed with docker run or in orchestration tools, not in the Dockerfile.
Volumes
Volumes handle data persistence and are usually defined with docker run -v or Docker Compose. The optional VOLUME instruction can mark a mount point, but managing volumes outside the image is generally preferred.
What’s Next?
You now understand why Dockerfiles are essential. In Part 2 we’ll explore the full build process with docker build, dive into advanced instructions like ENTRYPOINT, discuss multi‑stage builds, and cover best practices for publishing images to a registry.