Skip to main content

Docker init: How to Initialize a Project with Docker (Step-by-Step Guide)

A practical guide to `docker init` - what it generates, how to use it with a real Python project, and when it's the right tool for the job.
Mar 25, 2026  · 14 min read

For some reason, setting up a new project with Docker always takes longer than it should.

You Google a template, paste it in, change a couple of lines, and hope for the best. The build fails, so then you tweak and repeat the cycle until it works. Every new project starts the same way - with a blank file and a vague memory of what worked last time. This is a clear setup problem, and Docker isn’t to blame.

The good news is that docker init fixes this. It's a CLI command that detects your project type and generates a Dockerfile, .dockerignore, and Compose file.

In this article, I'll walk you through how docker init works, how to use it step by step with a real Python project, and when it's the right tool for the job.

Are you completely new to Docker and containerization? Learn why it’s an essential part in the data professional’s toolkit by opting for our Introduction to Docker course.

What Is Docker init

docker init is a CLI tool that sets up Docker configuration for your project. It generates the files you need to containerize your app. So with it, there’s no need for templates or copy-pasting.

It produces three files:

  • Dockerfile - defines how your container image is built
  • .dockerignore - tells Docker which files to leave out of the build context
  • compose.yml - optional, but handy for multi-service setups

The smart part is automatic project detection. docker init looks at your project structure and figures out what stack you're using - Python, Node.js, Go, and others. It then generates files according to that stack instead of coming up with a generic template.

It's not a deployment tool, and it won't manage your containers in production. It just gets your configuration started so you can focus on the actual work.

How Docker init Works

docker init follows a four-step flow every time you run it.

First, you run docker init inside your project folder. Docker scans the directory, detects your project type, and chooses the right configuration template. Then it walks you through a short series of interactive prompts - things like which port your app runs on and what command starts it. Once you answer those, it generates your files.

The whole thing takes under a minute.

The prompts are easy to answer and rarely need additional explanation. You can accept the defaults by pressing Enter, or type in your own values if the defaults don't work. 

Here's what you’ll see when you first run the command:

Docker init setup screen

Docker init setup screen

Let me show you this process in more detail next.

How to Use Docker init Step by Step

Here's an overview on how to go from a project folder to a running container.

Step 1: Navigate to your project directory

Open your terminal and navigate to the root of your project - the folder that contains your application code.

cd /path/to/your/project

docker init generates files relative to wherever you run it, so make sure you're in the right directory before proceeding.

Step 2: Run Docker init

Run the following command:

docker init

Docker will scan your project folder, detect your stack, and launch the interactive setup prompt.

Step 3: Answer the prompts

docker init will ask you a couple of questions:

  • Application platform - the language or framework your project uses (Python, Node.js, Go, etc.)
  • Port - the port your app listens on
  • Start command - the command Docker should run to start your app

You can accept the suggested defaults by pressing Enter, or type in your own values. If docker init detects your stack, the defaults are usually good enough to start with.

Step 4: Review the generated files

Once you answer the prompts, docker init writes three files to your project folder:

.
├── Dockerfile
├── .dockerignore
└── compose.yaml

Open each file and read through it. The generated files include comments that explain what each line does, so it's worth taking a few minutes to understand what was created before you build anything.

Step 5: Build and run your container

Build and start your container with Docker Compose:

docker compose up --build

The --build flag tells Docker to build the image from your Dockerfile before starting the container. Once it's running, your app should be accessible on the port you specified in step 3.

Supported Project Types in Docker init

docker init supports the most common application stacks out of the box. Here’s just a few:

  • Python
  • Node.js
  • Go
  • Java
  • .NET

It detects the stack automatically.. When you run docker init, it scans your project folder for language-specific files - things like requirements.txt for Python or package.json for Node.js - and picks the right template based on what it finds.

Each template is tailored to the stack. A Python project gets a different base image, install commands, and start command than a Go project. You're not getting a one-size-fits-all Dockerfile with a language variable swapped out. The structure itself changes depending on what you're building.

If docker init can't detect your stack, it'll ask you to pick one manually from the list.

Files Generated by Docker init

docker init generates three files, and each one has a different role in your setup.

Dockerfile

The Dockerfile defines how Docker builds your container image. It tells Docker which base image to start from, how to install your dependencies, and what command to run when the container starts.

Here's an example of what a generated Python Dockerfile looks like:

FROM python:3.14-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]

You'll want to review this file before building. The generated output is a good starting point, but you may need to tweak it - for example, to add environment variables or adjust the base image version.

.dockerignore

The .dockerignore file tells Docker which files to exclude from the build context. This is the set of files Docker sends to the build engine when creating your image.

Without it, Docker would copy everything in your project folder into the image, including things like .git, node_modules, or local config files you don't need in production. That increases your image size and can expose files you didn't mean to include.

A typical .dockerignore looks like this:

.git
.env
__pycache__
*.pyc
node_modules

Docker Compose file

The compose.yaml file is for running multi-container setups. It defines your services, ports, volumes, and how containers connect to each other.

For a simple single-container app, you might not need it. But if your project involves a database, a cache, or any other service running alongside your app, the Compose file is where you configure all of that in one place.

Example: Using Docker init with a Python Project

Let's run docker init on a real project. I'll use a minimal FastAPI app with a single route as the example.

Here's the project structure before running docker init:

my-fastapi-app/
├── app.py
└── requirements.txt

app.py has a single Hello World route:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, World!"}

And requirements.txt has these two dependencies:

fastapi
uvicorn

Running docker init

To start, navigate to the project folder and run:

docker init

Docker init project detected

Docker init project detected

docker init detects Python from requirements.txt and asks you a couple of questions. Here's what the prompts look like and what to answer:

Docker init prompts for a Python project

Docker init prompts for a Python project

What gets generated

After answering the prompts, your project folder looks like this:

New project folder structure

New project folder structure

There are three new files. Let's look at each one.

The Dockerfile

# syntax=docker/dockerfile:1

ARG PYTHON_VERSION=3.14
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 uvicorn 'app:app' --host=0.0.0.0 --port=8000

A few things stand out here. PYTHONDONTWRITEBYTECODE=1 stops Python from writing .pyc files to disk, and PYTHONUNBUFFERED=1 makes sure logs show up in real time instead of getting held in a buffer - both are good defaults for containerized apps.

The adduser block creates a non-privileged user called appuser to run the application. By default, Docker containers run as root, which is a security risk. Running as a non-root user limits what an attacker can do if they manage to break out of your app.

The --mount=type=cache flag on the pip install step tells Docker to cache downloaded packages between builds. This means the following builds won't re-download dependencies from scratch, which speeds things up.

The .dockerignore

**/.DS_Store
**/__pycache__
**/.venv
**/.env
**/.git
**/.gitignore
**/node_modules
**/Dockerfile*
**/compose.y*ml
README.md

The .dockerignore file excludes files that don't belong in your image. Local environment files like .env, version control folders like .git, and Python cache files like __pycache__ all get skipped. The Dockerfile and compose.yaml themselves are also excluded - Docker doesn't need them inside the image it's building.

The compose.yaml

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

The Compose file defines your app as a service called server, builds it from the Dockerfile in the current directory, and maps port 8000 on your host to port 8000 inside the container.

All three generated files include some comments which I’ve omitted to keep things clean.

Run docker compose up --build and your FastAPI app will be live at http://localhost:8000.

FastAPI app running in a container

FastAPI app running in a container

Docker init vs Manual Dockerfile Setup

Both approaches get you a working Dockerfile, so it’s the matter of how much control you need and how fast you want to get there.

Docker init

docker init is the faster option. You answer a few prompts and get a working, reasonably secure configuration in under a minute. The generated files follow Docker's own best practices - non-root users, build caching, proper .dockerignore patterns - so you're not starting from scratch.

It's a good fit when you're starting a new project, onboarding a teammate, or just want a solid base to build on without spending time on boilerplate.

But there’s a question of flexibility. The templates cover common stacks well, but they're still templates. If your project has an unusual structure or specific build requirements, you'll hit the limits of what docker init can generate.

Manual setup

Writing your Dockerfile by hand gives you full control over every layer, every instruction, and every build decision. You can implement multi-stage builds to minimize image size, use custom base images, or fine-tune caching behavior in ways that docker init can't anticipate.

But, you need to know what you're doing. A poorly written Dockerfile can produce oversized images, introduce security issues, or fail in ways that are hard to debug, especially if you’re not experienced in the first place.

Which one to use

Here's a simple way to think about it:

Docker init versus manual setup comparison

Docker init versus manual setup comparison

A good approach is to start with docker init and then manually edit the generated files as your requirements grow.

When to Use Docker init

docker init isn't the right tool for every situation. Here's when it makes sense and when it doesn't.

Go with docker init when:

  • You're starting a new project: It gets your Docker configuration off the ground in under a minute, so you can focus on writing code instead of setting up the containerization

  • You're learning Docker: The generated files are well-commented and follow best practices. They're a better starting point than a random Stack Overflow snippet

  • You're prototyping: When you need a containerized environment fast and don't care about fine-tuning the build, docker init gives you something that works

  • You're standardizing across a team: Instead of every developer rolling their own Dockerfile, docker init gives everyone a consistent starting point with the same structure and defaults

That said, you should skip docker init when:

  • You need multi-stage builds: If you're optimizing image size by splitting your build into separate stages - compiling in one, running in another - you'll need to write that manually. The generated Dockerfile is single-stage

  • You have complex production requirements: Custom base images, advanced caching strategies, non-standard project layouts - these aren't things docker init can anticipate. You'll spend more time working around the generated files than just writing your own

To conclude, docker init is a starting point. Use it to get moving, then edit the generated files as your needs grow.

Limitations of Docker init

You can run into some limitations as your project grows. Here are a few.

The generated files are template-based. They're designed to cover the most common cases for each supported stack, which means they work well for common projects and less well for anything outside that range. If your project has an unusual structure, the generated files maybe won't account for that.

Another common limitation is that manual tuning is almost always required. The defaults are good, but they're still defaults. You'll likely need to adjust the base image version, tweak environment variables, or modify the start command before the configuration fits your project. Think of the generated files as a first draft, nothing more.

docker init also doesn't support advanced build patterns. Multi-stage builds, custom build arguments, conditional logic, and other techniques that experienced Docker users rely on for production images are outside the scope of what the tool generates. But if you need any of that, you're writing the Dockerfile yourself anyway.

None of this makes docker init a bad tool. It just means you need to go in with the right expectations - it removes the blank-page problem, but it doesn't replace the need to understand what's in your Dockerfile.

Best Practices After Using Docker init

The files docker init generates are a starting point. Here are the steps you need to take to turn them into something production-ready.

  • Review the generated files: Read through the Dockerfile, .dockerignore, and compose.yaml line by line. The files are well-commented, so this won't take long. You want to understand what's there before you start building on top of it

  • Optimize your image size: The default base image is python:3.x-slim, which is already a lightweight choice. But you can go further by making sure your .dockerignore is excluding everything it should, and check that you're not copying files into the image that don't need to be there

  • Move secrets and environment-specific values into environment variables: Don't hardcode API keys, database URLs, or environment flags in your Dockerfile. Use environment variables, and manage them through a .env file locally or your deployment platform's secret management in production

  • Test locally before pushing anywhere: Run docker compose up --build and verify your app behaves the same inside the container as it does outside. Check your logs, go to your endpoints, and confirm the port mapping works

  • Refine your build steps as the project grows: The generated Dockerfile installs dependencies in a single layer. As your project matures, think about layer ordering. In other words, put steps that change less often earlier in the file so Docker can cache them. If your build times start creeping up, that's usually the first place to look

Common Issues and Troubleshooting

Like always in tech, a couple of things can go wrong. Here's what to look for and how to fix it.

Incorrect project detection

If docker init picks the wrong stack, it'll generate files that don't match your project. This usually happens when your project folder has mixed-language files or is missing the file docker init looks for - like requirements.txt for Python or package.json for Node.js.

When the prompt asks for your application platform, just select the correct one manually instead of accepting the detected default.

Port conflicts

If your container starts but you can't reach your app, or Docker throws an error about a port already being in use, another process on your machine is likely occupying the same port.

Find and stop the conflicting process, or change the host-side port in your compose.yaml:

ports:
  - 8001:8000  # maps host port 8001 to container port 8000

The left side is the port on your machine. The right side needs to match what your app listens on inside the container.

Missing dependencies

If your container builds but crashes on start, missing dependencies are a common reason why. Check that your requirements.txt (or equivalent) is complete and up to date. If you've added a package locally without updating that file, the container won't have it.

Run docker compose logs to see the error output:

docker compose logs

The error message will usually tell you exactly which package is missing.

Container not starting

If the container won't start at all, the problem is almost always in the CMD line of your Dockerfile. Check that the start command matches how you actually run your app.

For the FastAPI example, it should look like this:

CMD uvicorn 'app:app' --host=0.0.0.0 --port=8000

If your entry point file has a different name or the module path is wrong, the container will exit . Fix the CMD, rebuild with docker compose up --build, and check the logs again.

Conclusion

docker init won't replace a deep understanding of Docker, but it will get you out of the blank-page problem.

In a single command, you get a working Dockerfile, .dockerignore, and compose.yml file - all following Docker's own best practices. That's a good foundation for any new project, and a much better starting point than a copy-pasted template from Stack Overflow or ChatGPT.

Just don't stop there. The generated files are meant to be edited. Review them, tweak the build steps, lock down your base image version, and add your environment variables. The more your project grows, the more you'll move away from the defaults.

If you know the basics of Docker, the logical next step is to learn about multi-stage builds, networking tools, and Docker compose - all of which is covered in our Intermediate Docker course.


Dario Radečić's photo
Author
Dario Radečić
LinkedIn
Senior Data Scientist based in Croatia. Top Tech Writer with over 700 articles published, generating more than 10M views. Book Author of Machine Learning Automation with TPOT.

FAQs

What is docker init and what does it do?

It’s a Docker CLI command that generates the configuration files needed to containerize a project. It produces a Dockerfile, .dockerignore, and compose.yaml based on your project type. Instead of writing these files from scratch, you answer a few prompts and docker init does the rest.

Do I need Docker experience to use docker init?

No, it is designed to lower the barrier to entry for developers who are new to Docker. That said, you'll get more out of it if you understand the basics of how containers work. The generated files are well-commented, so they also serve as a learning tool for understanding what each configuration step does.

What programming languages does docker init support?

docker init currently supports Python, Node.js, Go, Java, and .NET. It detects your stack  by scanning your project folder for language-specific files like requirements.txt or package.json. If detection fails or your stack isn't supported, you can select a platform manually from the prompt.

Can I use docker init on an existing project?

Yes, you can run docker init in any project folder, not just new ones. If Docker configuration files already exist in the directory, docker init will warn you before overwriting them. It's a good way to replace an outdated or poorly written Dockerfile with a cleaner, best-practice baseline.

Does docker init generate production-ready Docker configuration?

The generated files follow Docker's own best practices - non-root users, build caching, and a slim base image - so they're a solid starting point. But they're not a finished production setup. You'll still need to configure environment variables, fine-tune your build steps, and potentially implement multi-stage builds depending on your deployment requirements.

Topics

Learn Docker with DataCamp

Track

Containerization and Virtualization with Docker and Kubernetes

13 hr
Learn the power of Docker and Kubernetes, this interactive track will allow you to build and deploy applications in modern environments.
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

blog

How to Learn Docker from Scratch: A Guide for Data Professionals

This guide teaches you how to learn Docker from scratch. Discover practical tips, resources, and a step-by-step plan to accelerate your learning!
Joel Wembo's photo

Joel Wembo

14 min

blog

10 Docker Project Ideas: From Beginner to Advanced

Learn Docker with these hands-on project ideas for all skill levels, from beginner to advanced, focused on building and optimizing data science applications.
Joel Wembo's photo

Joel Wembo

9 min

Tutorial

Update Docker: A Step-by-Step Guide

Learn how to update Docker Engine, Docker Desktop, and container images — all without breaking your setup.
Dario Radečić's photo

Dario Radečić

Tutorial

Docker for Beginners: A Practical Guide to Containers

This beginner-friendly tutorial covers the essentials of containerization, helping you build, run, and manage containers with hands-on examples.
Moez Ali's photo

Moez Ali

Docker bot

Tutorial

Docker for Data Science: An Introduction

In this Docker tutorial, discover the setup, common Docker commands, dockerizing machine learning applications, and industry-wide best practices.
Arunn Thevapalan's photo

Arunn Thevapalan

Tutorial

How to Containerize an Application Using Docker

Learn how to containerize machine learning applications with Docker and Kubernetes. A beginner-friendly guide to building, deploying, and scaling containerized ML models in production.

Rajesh Kumar

See MoreSee More