What are Docker Scratch Based Images?
Docker scratch-based images refer to images that are built from the scratch base, which is the most minimal base image available in Docker. The scratch image is essentially an empty image, meaning it contains no files or pre-installed libraries, making it a blank slate for building Docker containers.
What is Docker Scratch Based Image ?
A scratch-based image in Docker is like starting from absolute zero. It’s an empty, minimal base image with nothing pre-installed—no operating system, utilities, or libraries. This gives developers complete control over what goes into the container, allowing them to build extremely lightweight, tailored Docker images.
Why Use Scratch-based Images
- Super Lightweight: Since
scratch
starts with nothing, the resulting images are incredibly small, often just a few megabytes or less. This makes them perfect for quick downloads, faster container startups, and reduced storage costs. - No Extras: With a scratch-based image, you only add exactly what’s necessary for your application to run—whether it’s a single binary, custom dependencies, or specific configurations. There are no unnecessary files or utilities bloating the image.
- More Secure: Because the image is so minimal, the attack surface is dramatically reduced. There are fewer components that could have vulnerabilities, making it a more secure choice for production environments.
Where Scratch-based Images are Frequently Used
- Statically Compiled Applications: Scratch-based images are popular for languages like Go or C/C++, where the application is compiled into a self-contained binary. These applications don’t need system libraries or runtime environments, making them a perfect match for scratch images.
- Microservices and Containers in Production: In production environments, especially for microservices, scratch-based images help keep deployments lean and fast. They’re used to create efficient containers where performance, security, and resource savings are critical.
- Optimized Containers: Scratch images are also used in situations where developers want to ship only the bare minimum—no package managers, no shells, no system utilities—just the application itself. This is ideal for small, optimized container environments.
Step-by-Step Guide to Build a Scratch-Based Docker Image
Step 1: Create Your Application (Go Example)
First, you’ll write a simple application to include in the Docker image. We’ll use Go for this example, as it can produce a statically compiled binary that doesn’t require external libraries.
- File Name:
main.go
In your project directory, create a file named main.go
with the following code:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}

Step 2: Build the Statically Compiled Binary
To make the Go program work in the scratch
Docker image, we need to build a statically compiled binary.
Run the following command in your terminal:
GOOS=linux GOARCH=amd64 go build -o app
- Output File: This command will create a binary file called
app
in your current directory. This binary will be self-contained and run in the minimal scratch environment.
The GOOS=linux
flag ensures the binary is compiled for Linux (since Docker runs on Linux by default), and GOARCH=amd64
specifies the architecture. The -o app
option specifies that the output binary will be named app
.
Step 3: Create a Dockerfile
The Dockerfile tells Docker how to build the image. In this case, we will use the scratch
image as the base and add the statically compiled binary to the container.
- File Name:
Dockerfile
In the same project directory, create a file called Dockerfile
with the following content:
# Start from scratch (minimal base image)
FROM scratch
# Add a label (optional, for metadata)
LABEL maintainer="your-email@example.com"
# Copy the statically compiled binary to the root of the container
COPY app /app
# Define the command to run when the container starts
CMD ["/app"]
Explanation:
FROM scratch
: This specifies that we’re starting with the emptyscratch
image.LABEL maintainer
: Optional metadata for tracking the author or maintainer of the image.COPY app /app
: This copies the binaryapp
from the build context (your local directory) into the container's root directory.CMD ["/app"]
: This defines the default command that will run when the container starts (ourapp
binary).

Step 4: Build the Docker Image
Now that you have the Dockerfile
and the binary (app
), you can build the Docker image.
Run this command in the directory containing the Dockerfile
and the binary:
docker build -t hello-world-scratch .
-t hello-world-scratch
: This assigns the taghello-world-scratch
to the image, which you’ll use to refer to the image..
: This tells Docker to look in the current directory for theDockerfile
.

Step 5: Run the Docker Container
Now that the image is built, you can run the container to see your program in action.
Run this command to start the container:
docker run --rm hello-world-scratch
- The
--rm
flag ensures that the container is removed after it runs, so it doesn’t take up space. hello-world-scratch
is the name of the image you built earlier.

Step 6: Verify the Size of the Image
One of the main benefits of using scratch
is the minimal size of the image.
To check the size of your image, run:
docker images hello-world-scratch

Conclusion
Creating a scratch-based Docker image allows you to build highly optimized and minimal containers that only include what’s essential for your application. These types of images are perfect for statically compiled binaries, like those created with Go or C, where you don’t need any external dependencies. The key benefits of using scratch-based images are their small size, improved security, and faster deployments. By following the step-by-step guide, you can easily build your own scratch-based Docker images, ensuring that your applications are both lightweight and efficient. This approach is particularly useful for microservices and production environments where performance and security are top priorities.