2 minute read

Context

Most people interact with Docker through docker run. It’s convenient, compact, and hides a lot of complexity.

But docker run is actually doing two things at once:

  1. creating a container
  2. starting it

When you separate those steps using docker create, Docker becomes easier to reason about—especially when debugging, experimenting, or learning how containers are really wired.

This post explains why and when that separation matters.


docker run vs docker create

At a high level:

docker run = docker create + docker start

docker create:

  • defines a container
  • stores its configuration
  • does not start it

docker start:

  • executes an already-defined container

That distinction is subtle, but important.


Why Use docker create Explicitly?

Using docker create forces you to think in terms of:

  • container identity
  • configuration as state
  • lifecycle boundaries

This is especially useful when:

  • debugging complex flags
  • iterating on volume mounts
  • inspecting container configuration before execution
  • understanding restart behavior

It’s also a bridge toward thinking in Compose and Kubernetes terms.


Anatomy of a docker create Command

A typical docker create command defines:

  • the image
  • container name
  • ports
  • volumes
  • environment variables
  • restart policies

Example pattern:

docker create \
  --name example-service \
  -p 8080:8080 \
  -v example-data:/var/lib/example \
  -e EXAMPLE_MODE=production \
  --restart unless-stopped \
  example-image:latest

Nothing runs yet. Docker simply records intent.


Inspecting Before Running

Once created, you can inspect the container:

docker inspect example-service

This is where docker create shines.

You can:

  • verify mounts
  • confirm ports
  • inspect environment variables
  • validate restart policies

All without starting the container.


Starting and Stopping Becomes Explicit

After creation:

docker start example-service

Stopping and restarting now operate on a known container, not a transient command.

This makes container behavior:

  • more predictable
  • easier to debug
  • less error-prone

Patterns This Enables

Using docker create works well for:

  • long-running infrastructure containers
  • stateful services
  • local development environments
  • reproducing issues reliably

It’s less useful for:

  • one-off commands
  • disposable CI jobs
  • quick experiments

Knowing when not to use it is part of the skill.


Relationship to Docker Compose

Docker Compose formalizes what docker create makes explicit:

  • declarative configuration
  • repeatability
  • separation of config and execution

If docker create feels helpful, Compose is usually the next step.

If Compose feels confusing, docker create is often a good way to learn why it exists.


Practical Takeaways

  • docker create exposes container configuration clearly
  • separating creation from execution improves debuggability
  • explicit lifecycle boundaries reduce surprises
  • this mental model scales toward Compose and Kubernetes

Understanding containers starts with understanding how they are defined.