Introduction
After defining your application's environment and dependencies in a Dockerfile, the next step is to transform that Dockerfile into a functional Docker image. This lesson will walk you through the process of building custom Docker images using the docker build command, explaining the concept of a build context and how to tag your newly created images for better management and distribution.
Key Concepts
The Build Context
When you execute the docker build command, you specify a build context. This is the set of files at a specified path or URL that Docker can access during the image build process. Docker sends the entire build context to the Docker daemon. It's crucial to keep your build context as small as possible to improve build performance.
.dockerignorefile: Similar to.gitignore, this file specifies files and directories to exclude from the build context. Using it prevents large or sensitive files from being sent to the daemon unnecessarily.
The docker build Command
The docker build command constructs Docker images from a Dockerfile and a context. Its basic syntax is docker build [OPTIONS] PATH | URL | -.
-
PATH: Refers to the directory containing the Dockerfile and the build context. Often, this is the current directory (.). -
-t(Tag): Allows you to assign a name and optional tag (in the formatname:tag) to the image. This makes images easier to identify and manage.
Image Layers and Caching
As mentioned, each instruction in a Dockerfile creates a new layer. Docker caches these layers. When rebuilding an image, if an instruction and its context haven't changed, Docker uses the cached layer, significantly speeding up the build process. Changes in an instruction will invalidate the cache for that layer and all subsequent layers.
- Order Matters: The order of instructions in your Dockerfile impacts caching. Place instructions that change infrequently (like
FROMor installing system dependencies) earlier in the Dockerfile.
Example/Code
Let's assume you have the Node.js Dockerfile from the previous lesson and an app.js file in the same directory.
Dockerfile (in your current directory):
dockerfileFROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD [ "npm", "start" ]
app.js:
javascriptconst express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => { res.send('Hello from Docker!'); }); app.listen(port, () => { console.log(`App listening at http://localhost:${port}`); });
package.json:
json{ "name": "my-docker-app", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "start": "node app.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.18.2" } }
To build the image, navigate to the directory containing these files and run:
bashdocker build -t my-node-app:1.0 .
Then, run the container:
bashdocker run -p 3000:3000 -d my-node-app:1.0
Summary/Key Takeaways
-
docker buildcreates images from a Dockerfile and a build context. -
The build context is the set of local files accessible during the build; use
.dockerignoreto optimize it. -
Use
-tto tag images with a name and version (e.g.,app:v1.0). -
Docker leverages caching of layers to speed up rebuilds; strategic instruction order is beneficial.