Writing a Dockerfile
Explanation
A Dockerfile is a text-based document that's used to create a container image. It provides instructions to the image builder on the commands to run, files to copy, startup command, and more.
As an example, the following Dockerfile would produce a ready-to-run Python application:
FROM python:3.12
WORKDIR /usr/local/app
# Install the application dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Copy in the source code
COPY src ./src
EXPOSE 5000
# Setup an app user so the container doesn't run as the root user
RUN useradd app
USER app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
Common instructions
Some of the most common instructions in a Dockerfile
include:
FROM <image>
- this specifies the base image that the build will extend.WORKDIR <path>
- this instruction specifies the "working directory" or the path in the image where files will be copied and commands will be executed.COPY <host-path> <image-path>
- this instruction tells the builder to copy files from the host and put them into the container image.RUN <command>
- this instruction tells the builder to run the specified command.ENV <name> <value>
- this instruction sets an environment variable that a running container will use.EXPOSE <port-number>
- this instruction sets configuration on the image that indicates a port the image would like to expose.USER <user-or-uid>
- this instruction sets the default user for all subsequent instructions.CMD ["<command>", "<arg1>"]
- this instruction sets the default command a container using this image will run.
To read through all of the instructions or go into greater detail, check out the Dockerfile reference.
Try it out
Just as you saw with the previous example, a Dockerfile typically follows these steps:
- Determine your base image
- Install application dependencies
- Copy in any relevant source code and/or binaries
- Configure the final image
In this quick hands-on guide, you'll write a Dockerfile that builds a simple Node.js application. If you're not familiar with JavaScript-based applications, don't worry. It isn't necessary for following along with this guide.
Set up
Download this ZIP file and extract the contents into a directory on your machine.
Creating the Dockerfile
Now that you have the project, you’re ready to create the Dockerfile
.
-
Download and install Docker Desktop.
-
Create a file named
Dockerfile
in the same folder as the filepackage.json
.Dockerfile file extensions
It's important to note that the
Dockerfile
has no file extension. Some editors will automatically add an extension to the file (or complain it doesn't have one). -
In the
Dockerfile
, define your base image by adding the following line:FROM node:20-alpine
-
Now, define the working directory by using the
WORKDIR
instruction. This will specify where future commands will run and the directory files will be copied inside the container image.WORKDIR /app
-
Copy all of the files from your project on your machine into the container image by using the
COPY
instruction:COPY . .
-
Install the app's dependencies by using the
yarn
CLI and package manager. To do so, run a command using theRUN
instruction:RUN yarn install --production
-
Finally, specify the default command to run by using the
CMD
instruction:CMD ["node", "./src/index.js"]
And with that, you should have the following Dockerfile:
FROM node:20-alpine WORKDIR /app COPY . . RUN yarn install --production CMD ["node", "./src/index.js"]
This Dockerfile isn't production-ready yet
It's important to note that this Dockerfile is not following all of the best practices yet (by design). It will build the app, but the builds won't be as fast, or the images as secure, as they could be.
Keep reading to learn more about how to make the image maximize the build cache, run as a non-root user, and multi-stage builds.
Containerize new projects quickly with
docker init
The
docker init
command will analyze your project and quickly create a Dockerfile, acompose.yaml
, and a.dockerignore
, helping you get up and going. Since you're learning about Dockerfiles specifically here, you won't use it now. But, learn more about it here.
Additional resources
To learn more about writing a Dockerfile, visit the following resources:
Next steps
Now that you have created a Dockerfile and learned the basics, it's time to learn about building, tagging, and pushing the images.