Docker init: The Ultimate Guide to Creating Dockerfiles

docker init

In this blog, you will learn to create Dockerfile using Docker built-in command docker init. We will also look at practical examples of Dockerizing applications using docker init.

Are you tired of writing Dockerfiles manually?

Don’t worry, Docker has created a command-line utility tool called docker init to make the Dockerfile creating process easy.

Let’s learn all about the utility in this blog.

What is docker init?

Docker init is a command line utility that automates the creation of a Dockerfile based on the language the application is built in.

Docker init comes with Docker Desktop by default. If you have Docker Desktop version 4.19.0 or later installed in your system you can use the docker init command.

docker init command analyzes your project directory and proposes suitable configurations based on detected programming languages or frameworks in your workspace.

By running the docker init command on your project workspace, it will create the following files based on your project.

  1. Dockerfile : To build the docker image.
  2. compose.yaml: For multi container applications
  3. .dockerignore: File exclusions to reduce the Docker image size.

Using docker init is pretty simple. Go to your project directory and run the docker init command.

It will prompt a few questions related to your application; Once you have answered the prompts, docker init will create the files instantly.

docker init uses templates, to create Dockerfile based on the programming language you choose.

You can select the following options after running the docker init command

  1. GO
  2. Python
  3. Node
  4. Rust
  5. ASP.NET
  6. Other – Select this option if your application is not mentioned in the above options.

Even though it creates the files following all best practices, you can further customize them based on your requirements

Note: If any of these files are already present in your workspace, docker init will overwrite the files. It will ask for confirmation before overwriting the files.

Note: Dont confuse docker init with  docker-init. docker-init is a process that acts as the init process (PID 1) within a Docker container.

Docker Init Workflow

The following diagram shows the docker init workflow.

Docker Init Workflow explained

Here is how it works.

  1. Developer runs the docker init command inside the project directory.
  2. docker init then scans your project code files and prompts you with configration questions.
  3. Once you have answered all the promtp docker init will create the Dockerfile, compose.yaml, and .dockerignore files in an instant.

How to Use Docker Init

In this section we will learn to use docker init using practical examples.

We will try hands-on examples of docker init using simple Python and Go projects.

For demonstration purposes, we are going to create a simple Hello World web application for each programming language and generate Dockerfile file using docker init.

The examples used in this guide are hosted on Github. You can clone the repository using the following command.

git clone https://github.com/techiescamp/docker-init

Generating Python Dockerfile

For Python, we are going to create a Python file for the Python Flask application, create two files app.py and requiremts.txt, and copy the below content into the files

#app.py

# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_docker():
    return '<h1> hello world </h1'

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
#requiremts.txt

flask
gunicorn

As you can see the app.py file has the code for the flask application and the requiremts.txt file has the dependencies needed to run the flask application.

The dependency txt file is important because, without the dependency file, docker init will not automatically detect the language of your application.

Of course, you can also select the languages manually.

Once you have created both files, run the below init command in the same directory where the files are to start the process

docker init

Docker init will check your files and ask some questions.

You can see it has automatically detected a Python-based application

Press ENTER to select Python and it will ask for the Python version, listening port, and command to run the app with suggested default values and that is so cool.

You can either select the default value by pressing ENTER or provide custom the values you want as shown in the following gif.

docker init Dockerfile creation workflow.

Once you have answered all questions docker init will create three files .dockerignore, compose.yaml, and Dockerfile as shown in the below directory structure

.
├── .dockerignore
├── Dockerfile
├── app.py
├── compose.yaml
└── requirements.txt

Here is an example of created Dockerfile. I have removed the generated comments for demo purposes.

ARG PYTHON_VERSION=3.11.6
FROM python:${PYTHON_VERSION}-slim as base

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR /app

ARG UID=10001
RUN adduser \
    --disabled-password \
    --gecos "" \
    --home "/nonexistent" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    appuser

RUN --mount=type=cache,target=/root/.cache/pip \
    --mount=type=bind,source=requirements.txt,target=requirements.txt \
    python -m pip install -r requirements.txt

USER appuser

COPY . .

EXPOSE 8000

CMD python3 app.py

As you can see it created a full fledged Dockerfile with the following best practices.

  1. Added a minimal base image.
  2. It added a non-priveleged user for security best practice.
  3. It added cache directory for speeding up subsequent installs by avoiding unnecessary downloads.

Without making any changes to the generated Dockerfile, I ran the docker build command and it worked perfectly fine.

docker build -t flask-app:1.0 .

It built a image of size 161MB. Then I ran the SlimtoolKit on the build image and the image size reduced to 25MB.

I verified it the image is working as expected by deploying the image and it worked perfectly fine.

docker run -d -p 8000:8000 flask-app:1.0
running application built using docker init Dockerfile

Also, if you are are Docker compose user, you can directly use the following compose command to build and run the image using the generated compose.yaml file.

docker compose up --build

For demonstration purposes, we haven’t made any customizations to the Dockerfile. When working on real-world projects, you will need to use approved container-based images and add other required instructions such as proxies, etc., based on your organization’s standards.

Generating Go Dockerfile

For this example, we are going to dockerize a Go web application using docker init.

Create a file app.go, and copy the below content into the files

package main

import (
    "fmt"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}

func main() {
    http.HandleFunc("/", helloHandler)
    fmt.Println("Server listening on port 8080")
    http.ListenAndServe(":8080", nil)
}

Then run the below command in the same directory as the Go file, which will create a module file for the Go application.

Same as the above Python example without the module file, docker init will not automatically detect the language.

go mod init app

This will create a go.mod file that has the dependencies to run the Go web application.

#app.go

module app

go 1.22.2

Once both files have been created, run the below init command in the same directory where the files are to start the process

docker init

Docker init will check your files and ask some questions for conformation as given below

You can see it has automatically detected a Go based application

docker init output

Press ENTER to select Go and it will ask for the Go version, relative directory, listening port to run the app as shown below

docker init confirmation questions

Once you have answered all confirmation questions docker init will create three files .dockerignore, compose.yaml, and Dockerfile as shown in the below directory structure

.
├── Dockerfile
├── app.go
├── .dockerignore
├── compose.yaml
└── go.mod

Your Dockerfile be created as shown below


ARG GO_VERSION=1.22.2
FROM golang:${GO_VERSION} AS build
WORKDIR /src
RUN --mount=type=cache,target=/go/pkg/mod/ \
    --mount=type=bind,source=go.sum,target=go.sum \
    --mount=type=bind,source=go.mod,target=go.mod \
    go mod download -x
RUN --mount=type=cache,target=/go/pkg/mod/ \
    --mount=type=bind,target=. \
    CGO_ENABLED=0 go build -o /bin/server .
FROM alpine:latest AS final
RUN --mount=type=cache,target=/var/cache/apk \
    apk --update add \
        ca-certificates \
        tzdata \
        && \
        update-ca-certificates
ARG UID=10001
RUN adduser \
    --disabled-password \
    --gecos "" \
    --home "/nonexistent" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    appuser
USER appuser
COPY --from=build /bin/server /bin/
EXPOSE 8000
ENTRYPOINT [ "/bin/server" ]

You can see the Dockerfile is created with every best practice to create a Docker Image more securely.

Also, you can compare the Go Dockerfile created by docker init is similar to the Python Dockerfile in the above example.

Furthermore, customize the Dockerfile based on your requirements and use it to Dockerize the Go web application.

Advantages of using docker init

Following are the advantages for using docker init.

  1. Creates Dockerfile, compose.yaml, and .dockerignore in an instance, thus saving time taken to write these files.
  2. Creates Dockerfile with best practices to make the Docker image more secure.
  3. Creates Dockerfile and compose.yaml with an explanation and instruction of what each line does, even a beginner could understand what’s on the Dockerfile.
  4. It will be helpful for beginners to create and understand Dockerfile with ease.
  5. Docker init creates a Dockerfile to make the Docker Image as light as possible.

Conclusion

In this blog, you learned about docker init, that eases dockerize process of your applications.

Also, we have gone through examples on how to create Dockerfile, compose.yaml, and .dockerignore files based on the language of the application.

I believe this blog gives you good information about the docker init utility and how to use it.

Give it a try and you will love it.

Also, how are you creating Dockerfiles in your current projects?

Share your process in the comment section.

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like