Write Better Dockerfile
Step by Step and Logic
Today I’m going to talk about how to write a Dockerfile that is safer, builds faster, has less volume and makes the first run fast.
But before I get to that, I’II go step by step talking about why we need it.
Why do we need a Dockerfile?
Docker is a containerization tool that allows us to create a container with all the necessary dependencies to run our application.
What is a container?
A container is a virtual machine that runs on the host machine. It is lighter than a virtual machine because it does not have a full operating system, but only the necessary dependencies to run our application.
What does the container have?
The container has the necessary dependencies to run our application. It can be a database, a web server, a programming language, etc.
More about containers: What is a container?
What is a Dockerfile?
The Dockerfile is a file that contains the instructions to build the image that will be used to create the container.
What is a Docker Image?
An image is a template that contains all the necessary dependencies to run our application.
Actually it is a snapshot of the container.
How to Write a Basic Dockerfile?
In this section, we will see how we can create a simple Dockerfile.
Step 1: Use a base image
The first thing we need to do is to choose a base image. The base image is the image that will be used to create the container.
Step 2: Copy the files
The next step is to copy the files to the container. The files that will be copied are the files that will be used to run the application.
Step 3: Install the dependencies
The next step is to install the dependencies. The dependencies are the dependencies that will be used to run the application.
Step 4: Expose the port
The next step is to expose the port. The port is the port that will be used to run the application.
Step 5: Run the application
The next step is to run the application.
Example
# Use a base image
FROM golang:1.19-alpine
# Copy the files
COPY . /app
# Install the dependencies
RUN go mod download
# Expose the port
EXPOSE 8080
# Run the application
CMD ["go", "run", "main.go"]
What did we do here?
We created a Dockerfile that uses the golang:1.19-alpine
image as a base image, copies the files, installs the dependencies, exposes the port 8080 and runs the application.
In fact, the application we make here is never a preferred situation for production.
Because here golang runs as a runtime. However, golang is a language that can give executable for us. Things can be safer and faster if we produce an executable.
How To Write a Dockerfile Dor Production?
In this section, we will focus on a more preferable example then the previous section.
Step 1: Use a base image
The first thing we need to do is to choose a base image. The base image is the image that will be used to create the container.
Step 2: Copy the files
The next step is to copy the files to the container. The files that will be copied are the files that will be used to run the application.
Step 3: Install the dependencies
The next step is to install the dependencies. The dependencies are the dependencies that will be used to run the application.
Step 4: Build the application
The next step is to build the application.
Step 5: Expose the port
The next step is to expose the port. The port is the port that will be used to run the application.
Step 6: Run the application
The next step is to run the application.
Example
FROM golang:1.19-alpine
# Copy the files
COPY . /app
# Install the dependencies
RUN go mod download
# Build the application
RUN go build -o main .
# Expose the port
EXPOSE 8080
# Run the application
CMD ["./main"]
What did we do here?
We created a Dockerfile that uses the golang:1.19-alpine
image as a base image, copies the files, installs the dependencies, builds the application, exposes the port 8080 and runs the application.
Actually, this method is used by some people in production. However, this is insufficient.
Because here we created an executable with golang and when our container runs we exec this executable. But the golang continues to live with our container. Also, as our project grows, we may not need to include various files in production. So we have a better method.
How To Write a Better Dockerfile?
In this section we will learn how to create a Dockerfile to create a really safe, fast and lightweight docker container.
Step 1: Use a base image
The first thing we need to do is to choose a base image. The base image is the image that will be used to create the container.
Step 2: Use a multi stage build
The multi stage build is a technique that allows us to create a Dockerfile with multiple stages. Each stage is a Dockerfile that will be used to create a container. The last stage is the one that will be used to create the container that will be used to run the application.
Step 3: Use a .dockerignore file
The .dockerignore
file is a file that contains the files and folders that will be ignored when building the image.
Example
The copy line here has been edited. Thanks to Mehmet Sezer for the correction.
# Use a smaller base image
FROM golang:1.19-alpine AS builder
# Copy go mod and sum files
COPY go.mod go.sum ./
# Download all dependencies.
# Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download
# Build the application
RUN go build -o main .
# Use a smaller base image
FROM alpine:3.14 AS runner
# Copy the files
COPY --from=builder /app/main /app/main
# Expose the port
EXPOSE 8080
# Run the application
CMD ["./app/main"]
What did we do here?
We created a Dockerfile that uses the golang:1.19-alpine
image as a base image, copies the files, installs the dependencies, builds the application, uses the alpine:3.14
image as a base image, copies the files, exposes the port 8080 and runs the application.
How To Build and Run The Image?
In this section, we will see how to create and run a Docker Image with the Dockerfile we created.
Step 1: Build the image
The first thing we need to do is to build the image. The image is the image that will be used to create the container.
Step 2: Run the container
The next step is to run the container. The container is the container that will be used to run the application.
Example
# Build the image
docker build -t go-docker .
# Run the container
docker run -p 8080:8080 go-docker
How Can I Tell If It Is Fast and Light?
In this section, we will learn how to see if we have really changed something in Docker with our Dockerfile changes.
Step 1: Check the size of the image
The first thing we need to do is to check the size of the image. The size of the image is the size of the image that will be used to create the container.
Step 2: Check the size of the container
The next step is to check the size of the container. The size of the container is the size of the container that will be used to run the application.
Step 3: Check the time it takes to build the image
The next step is to check the time it takes to build the image. The time it takes to build the image is the time it takes to build the image that will be used to create the container.
Step 4: Check the time it takes to run the container
The next step is to check the time it takes to run the container. The time it takes to run the container is the time it takes to run the container that will be used to run the application.
Example
# Check the size of the image
docker images
# Check the size of the container
docker ps -s
# Check the time it takes to build the image
docker build -t ssibrahimbas.com/fast-dockerfile .
# Check the time it takes to run the container
docker run -p 8080:8080 ssibrahimbas.com/fast-dockerfile
My Results
In this section
Step 1: Check the size of the image
REPOSITORY TAG IMAGE ID CREATED SIZE
ssibrahimbas.com/fast-dockerfile latest 1b1b1b1b1b1b 1 second ago 9.28MB
Step 2: Check the size of the container
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1b1b1b1b1b1b ssibrahimbas.com/fast-dockerfile "./app/main" 1 second ago Up 1 second
Step 3: Check the time it takes to build the image
[+] Building 0.5
Step 4: Check the time it takes to run the container
[+] Building 0.
Conclusion
In this article, we learned how to write a Dockerfile for production, how to write a Dockerfile that is safer, builds faster, has less volume and makes the first run fast, how to build the image, how to run the container and how to tell if it is fast and light.