Using Docker Init in Python

15 minute read     Updated:

Vivek Kumar Singh %
Vivek Kumar Singh

This tutorial explains Docker Init. Earthly optimizes Docker configurations. Learn more about Earthly.

Docker Init is a new plugin for Docker Desktop that’s equipped with a CLI tool that helps you set up project files automatically. It guides you by asking questions that help customize the Docker settings for your project.

Docker Init currently supports a variety of popular languages and frameworks, including Python, Node.js, ASP.NET, and Rust. One of its advantages is that it simplifies creating Docker-based Python projects by generating essential files like Dockerfile, .dockerignore, and compose.yaml. Docker Init is particularly useful for Python server applications, where you often need similar configurations for different projects.

In this article, you’ll learn how to use docker init with Python. Before you dive into the tutorial, let’s talk about why Docker Init was created.

Why Should You Use Docker Init?

Setting up an application on Docker involves configuring numerous settings to ensure smooth operation. Having to repeatedly create the Dockerfile and docker-compose.yaml files for multiple applications can become a laborious and time-consuming task.

For instance, here’s a sample Dockerfile file for a Python project:

FROM python:latest

ENV PYTHONUNBUFFERED=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app
COPY ./requirements.txt .
RUN pip install -r requirements.txt

COPY . .

This file includes several configurations for a Python project. However, it lacks adherence to many best practices that are necessary to ensure the creation of error-free application containers.

Similarly, here’s a sample compose.yaml file for a Python application:

version: '3.9'
services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - 8000:8000
    container_name: django_app

Unfortunately, initiating these files from the ground up can introduce errors. Additionally, creating Dockerfile and compose.yaml files this way can make it difficult to alter the configuration in the future.

Docker Init guarantees stability out of the box by generating Dockerfile, compose.yaml, and .dockerignore files that are tailored to the specific needs of the project. It’s a built-in feature of Docker Desktop, which means you don’t have to install any extra software to use it. It’s also easy to set up, so you can dive right into creating configurations using the CLI.

Using Docker Init With Python

Before you begin this tutorial, make sure you have Docker Desktop version 4.18 or newer installed on your system. You can check this by navigating to Settings in Docker Desktop. Click Software updates on the left-hand side of your screen, and you’ll see what version of Docker Desktop you’re using:

Docker Desktop version

To demonstrate the functionality of docker init, you’ll use a simple Python web application based on Django. Go ahead and clone the application.

To be able to containerize this application, you have to create three files: Dockerfile, compose.yaml, and .dockerignore.

Open the terminal in the project folder and run the following command:

docker init

Once you execute this command, you’ll be greeted by the Docker Init CLI welcome screen:

Docker Init CLI welcome screen

This screen will prompt you to select the platform on which your project will run. Select Python and press Enter to confirm your selection.

Subsequently, the CLI will prompt you to enter the Python version you’d like to use for this specific project. You can either type in the version or opt for the default Python version installed on your system by simply pressing Enter:

Select Python version

Next, the CLI will ask you to specify the port number where the application will be listening. You can input the port by typing or selecting Django’s default port, 8000:

Select a port in the CLI

Finally, the CLI will ask you to enter the command that will be used to run the app. In this case, the app utilizes the default server provided by Django, which is initiated using the command python manage.py runserver 0.0.0.0:8000:

Run the command input in Docker Init

Run python manage.py runserver 0.0.0.0:8000 and press Enter:

Docker Init final screen

The Docker Init CLI confirms that the Docker files have been prepared and provides you with a docker compose up --build command to start your application within the Docker container.

Now, if you take a look at your project directory, you should see the addition of three new Docker files: Dockerfile, compose.yaml, and .dockerignore.

1. Dockerfile

If you open the Dockerfile, you’ll find that each line is extensively commented on, providing thorough guidance for developers regarding the configurations for the project. The Dockerfile adheres to best practices, including the use of ARG instructions for defining variables like the Python version and user ID:

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

This snippet showcases the utilization of ARG to specify the Python version and the subsequent usage of the base image. This approach promotes maintainability and understanding for developers working on the project.

Additionally, the Dockerfile creates a non-root user named appuser to run the application in the container for security purposes:

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

In this snippet, the user with UID 10001 is created using the adduser command with the following attributes:

  • --disabled-password disables password authentication for the user
  • --gecos "" omits any additional information about the user
  • --home "/nonexistent" sets the home directory to /nonexistent
  • --shell "/sbin/nologin" assigns /sbin/nologin as the user’s login shell, preventing interactive login
  • --no-create-home ensures that a home directory is not created for the user
  • --uid "${UID}" assigns the specified UID (10001) to the user

The Dockerfile also includes instructions for running the application and building container images.

2. compose.yaml

The compose.yaml file sets up multi-container environments and specifies services, networks, and volumes. While containers usually host a single process, it’s possible to run multiples, which is why compose.yaml configures each service individually.

compose.yaml provides clear guidance on each configuration. It also comes preconfigured with a PostgreSQL database for app integration. However, this database will not be utilized because this specific Python project doesn’t rely on an external database.

The server configuration provided by the compose.yaml file looks like this:

services:
  server:
    build:
      context: .
    ports:
      - 8000:8000

In this snippet, compose.yaml defines a service named server. It builds an image from the current directory (context: .) and maps port 8000 on the host to port 8000 in the container. This allows access to the service from the host machine.

3. .dockerignore

The .dockerignore file lists all the file types that shouldn’t be copied to the container in order to save memory. These include Python cache files, IDE config files, and temporary files:

-- omitted --
**/.DS_Store
**/__pycache__
**/.venv
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
-- omitted --

The double asterisk is a wildcard that matches zero or more directories recursively. So, ** will match any subdirectory (and sub-subdirectory, and so on) under the current directory. This ensures that the directory names after the forward slash (/) get ignored while creating a container, resulting in reduced build time and image size.

Running the App in a Docker Container

Now, it’s time to run the application in a Docker container using the command provided by the Docker Init CLI. Before you run it, make sure Docker Desktop is running, then open the terminal and execute the following command:

docker compose up --build

This will pull a Python-based image from the Docker Hub repository and start to build the container. After building the container, Docker runs the command that runs the application specified during the creation of the Docker configuration files. The output looks like this:

-- omitted --
 ✔ Container dinit-server-1  Recreated                                                                             0.9s
Attaching to dinit-server-1
dinit-server-1  | Watching for file changes with StatReloader
dinit-server-1  | Performing system checks...
dinit-server-1  |
dinit-server-1  | System check identified no issues (0 silenced).
dinit-server-1  | October 24, 2023 - 09:34:34
dinit-server-1  | Django version 4.2.6, using settings 'core.settings'
dinit-server-1  | Starting development server at http://0.0.0.0:8000/
dinit-server-1  | Quit the server with CONTROL-C.

This application is running on port 8000. You can test it by opening the browser on your system and visiting http://127.0.0.1:8000/. When you visit the URL, you’ll see the following application window:

Application main window

As you can see, the Django app is working perfectly inside the container, and you can view and test the app locally.

Conclusion

In this tutorial, we’ve covered Docker Init, an essential tool for effortlessly generating Dockerfile, compose.yaml, and .dockerignore files. Docker Init streamlines the process, promoting best practices and offering a straightforward path for developers diving into containerization.

Loved how Docker Init simplified your setup? Take it further with Earthly to make your builds just as smooth and repeatable. Earthly can complement Docker by ensuring that your build process is not only straightforward but also consistent across different environments. Check it out for an even tighter build process that integrates seamlessly with your Docker workflow!

Earthly Cloud: Consistent, Fast Builds, Any CI
Consistent, repeatable builds across all environments. Advanced caching for faster builds. Easy integration with any CI. 6,000 build minutes per month included.

Get Started Free

Vivek Kumar Singh %
Vivek Kumar Singh
Vivek is a Python/Django developer who spends his time building projects and learning new technologies. He also likes to breakdown complex topics in his blogs to help new developers.

Published:

Get notified about new articles!
We won't send you spam. Unsubscribe at any time.