CHAPTER 05
Beginner
Creating Custom Docker Images
Updated: May 15, 2026
25 min read
# CHAPTER 5
Creating Custom Docker Images
1. Introduction
Using pre-built images from Docker Hub is only half of the Docker equation. If you are a developer writing a custom Python API or a PHP web application, you need to package *your* code into an image so you can send it to the production server. This is achieved by writing a Dockerfile. In this chapter, we will learn how to author a Dockerfile, understanding the step-by-step instructions required to build a custom, production-ready blueprint.2. Learning Objectives
By the end of this chapter, you will be able to:- Define what a Dockerfile is and its purpose.
-
Understand core Dockerfile instructions:
FROM,WORKDIR,COPY,RUN,CMD.
-
Execute the
docker buildcommand to compile an image.
- Understand the concept of Docker Image Layers and caching.
- Build a custom image containing a simple web application.
3. Beginner-Friendly Explanation
Imagine baking a cake using a highly strict recipe. A Dockerfile is the recipe card. It contains exact, sequential instructions.-
1.
FROM: Go to the store and buy a pre-made vanilla cake base. (Start with an official base image, like Python or PHP).
-
2.
WORKDIR: Put the cake base on the kitchen counter. (Set the working directory).
-
3.
COPY: Take the chocolate frosting from your fridge and put it on the cake. (Copy your custom code from your laptop into the container).
-
4.
RUN: Put the cake in the oven at 350 degrees. (Run an installation command, likenpm install).
-
5.
CMD: Serve the cake to the guests. (The final command that keeps the container alive).
When you run docker build, the Docker Engine reads the recipe card top-to-bottom and bakes your custom Image.
4. Core Dockerfile Instructions
A Dockerfile is a simple text file named exactlyDockerfile (no extension).
-
FROM <image>: This MUST be the first line. It defines your base operating system. Example:FROM php:8.2-apache.
-
WORKDIR /path: Creates a folder inside the container and makes it the active directory. All subsequent commands happen here. Example:WORKDIR /var/www/html.
-
COPY <source> <destination>: Copies files from your laptop into the container. Example:COPY . .(Copies everything from the current laptop folder into the current container folder).
-
RUN <command>: Executes a terminal command *during the build process*. Used to install software. Example:RUN apt-get update && apt-get install git.
-
EXPOSE <port>: Documentation only. Tells the user which port the app runs on. Example:EXPOSE 80.
-
CMD ["executable", "param"]: The default command that runs *when the container starts*. Example:CMD ["php", "-S", "0.0.0.0:80"].
5. Image Layers and Caching
Every single line in a Dockerfile creates a new Layer. Docker is incredibly smart. If you build an image, and then change one line of your HTML code and build it again, Docker does not rebuild the entire operating system from scratch. It utilizes Cache. It skips theFROM and RUN layers because they haven't changed, and only rebuilds the COPY layer where the HTML was modified. This makes rebuilding images take seconds instead of minutes.
6. Mini Project: Dockerize a PHP Application
Let's package a custom PHP script into a container.Step-by-Step Tutorial:
-
1.
On your laptop, create a new folder called
my-php-app. Open your terminal andcdinto it.
-
2.
Inside the folder, create a file named
index.phpand add this code:
php
-
3.
Inside the same folder, create a file named exactly
Dockerfile(no.txtextension) and add this code:
dockerfile
-
4.
Now, let's "bake" the image! Run the build command (don't forget the
.at the end, which means "look in this current directory for the Dockerfile"):
bash
-
-t: Tags (names) the image.
- 5. Once built, run your brand new custom image!
bash
-
6.
Open your browser to
http://localhost:8080. You will see your custom PHP code running!
7. Real-World Scenarios
A Node.js developer writes an app. Instead of emailing a zip file of their code to the operations team and writing a 5-page manual on how to install Node, runnpm install, and start the server, they simply write a 10-line Dockerfile. The operations team types docker build and the application is guaranteed to compile and run flawlessly, entirely independent of the developer's machine.
8. Best Practices
-
Order Matters for Caching: Because Docker caches layers top-to-bottom, you should place instructions that rarely change (like
RUN npm installorRUN apt-get install) at the TOP of the Dockerfile, and instructions that change constantly (likeCOPY . .for your source code) at the BOTTOM. If you copy your code *before* installing dependencies, Docker will reinstall the dependencies every single time you change a typo in your HTML!
9. Common Mistakes
-
RUNvs.CMDConfusion: This is the #1 beginner mistake.
-
RUNexecutes *while the image is being built* (e.g., installing a library).
-
CMDexecutes *when the container is finally launched* (e.g., starting the web server). If you try to start the web server usingRUN, the server will start during the build process, hang indefinitely, and the build will fail.
10. Exercises
-
1.
What is the purpose of the
.at the end of thedocker build -t my-app .command?
-
2.
Explain the functional difference between the
RUNinstruction and theCMDinstruction in a Dockerfile.
11. FAQs
Q: Can a Dockerfile have multipleFROM statements?
A: Yes! This is an advanced concept called a "Multi-Stage Build." It is used to compile code in Stage 1 (which requires heavy compiler tools), and then copy only the finished, compiled code into Stage 2 (a tiny, lightweight image) to keep the final production image as small as possible.
12. Interview Questions
- Q: Explain the concept of Docker Image Layers and the Build Cache. How would you structure a Dockerfile to optimize cache usage for a Node.js application?
- Q: Describe the step-by-step process of converting a legacy, non-containerized application into a Dockerized application using a Dockerfile.
13. Summary
In Chapter 5, we became Image authors. We introduced the Dockerfile as the declarative recipe for packaging custom software. We dissected the essential instructions—FROM, WORKDIR, COPY, RUN, and CMD—understanding how each instruction creates an immutable layer within the image. Finally, we executed the docker build command to compile our custom PHP application, proving that we can package and distribute our own code flawlessly without relying entirely on pre-built Hub images.