3.1 The FROM
Instruction
So, as a reminder, a Dockerfile is a text file that contains instructions for creating a Docker image. Each instruction in a Dockerfile performs a specific task and creates a new layer in the image. In this lecture, we'll go into more detail about the main Dockerfile instructions: FROM
, RUN
, COPY
, and CMD
, which are key for creating functional and efficient Docker images.
The FROM
instruction sets the base image from which the new image will be created. This is the first instruction in any Dockerfile, and it defines the starting point for building the image.
Syntax
FROM <image>[:<tag>] [AS <name>]
Where:
<image>
: the name of the base image.<tag>
: (optional) the version of the base image. By default,latest
is used.AS <name>
: (optional) assigning a name to this build stage (used in multi-stage builds).
Examples
Using the Ubuntu
base image:
FROM ubuntu:20.04
Using the official Node.js
image:
FROM node:14
Using multi-stage builds for optimization:
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
In this example, two base images are used. The first (node:14) is used for building the application, and the second (nginx:alpine) is used to create a lightweight server that serves static files.
Thanks to the use of multi-stage builds, the final image contains only the minimal set of files and programs (in this case Nginx
and the compiled static files), making it lighter and faster to deploy.
3.2 RUN Instruction
The RUN
instruction executes commands inside the container and creates a new layer in the image. This instruction is used for installing packages, setting up the environment, and running other commands needed to prepare the image.
Syntax:
RUN <command>
Where:
<command>
: the command that will be executed inside the container.
Examples:
Installing packages on an Ubuntu image:
RUN apt-get update && apt-get install -y curl git
Compiling code:
RUN gcc -o myapp myapp.c
Combining Multiple Commands
To reduce the number of layers, decrease the image
size, and speed up the build process, it is recommended to combine multiple commands into a single RUN
instruction.
RUN apt-get update \
&& apt-get install -y curl git \
&& rm -rf /var/lib/apt/lists/*
3.3 The COPY
Instruction
The COPY
instruction copies files and directories from the build context to the container's file system. This is super handy for transferring source code, configuration files, and other resources into the container.
Syntax:
COPY <src> <dest>
Here:
-
<src>
: Path to files or directories in the build context. <dest>
: Destination path inside the container.
Examples:
Copying all content of the current directory into the container's working directory:
COPY . /app
Copying individual files:
COPY package.json /app/package.json
COPY server.js /app/server.js
Using the .dockerignore
file
You can exclude unnecessary files from the copying process by using a .dockerignore
file, which works similarly to .gitignore
.
node_modules
dist
*.log
3.4 The CMD
Instruction
The CMD
instruction sets a command that will be run when the container starts. Unlike RUN
, which is executed at build time, CMD
runs when a container is launched from the created image.
Syntax:
CMD ["executable","param1","param2"]
Or
CMD command param1 param2
Where:
- ["executable","param1","param2"]: exec form, which is preferred to ensure proper signal handling.
- command param1 param2:
shell
form, which runs the command in a shell.
Examples:
Running a Node.js
app:
CMD ["node", "app.js"]
Running a shell
script:
CMD /usr/bin/myscript.sh
Difference between CMD
and ENTRYPOINT
CMD
sets the default command, which can be overridden when the container is started. ENTRYPOINT
sets an unchangeable command that always runs when the container starts.
Example using ENTRYPOINT
:
ENTRYPOINT ["python", "script.py"]
CMD ["arg1"]
In this example, ENTRYPOINT
executes the Python script, and CMD
passes arguments that can be modified when the container starts.
Example Dockerfile with Basic Instructions
# Use a base Node.js image
FROM node:14
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json files
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the application's source code
COPY . .
# Specify the port the application will use
EXPOSE 3000
# Set the command to run the application
CMD ["node", "app.js"]
GO TO FULL VERSION