IT Training
Blog
Search

Docker Tutorial for Beginners: Images, Containers and Compose Step by Step

Container ship loaded with shipping containers, a common metaphor for Docker containers

Docker lets you package an application with everything it needs (code, runtime, libraries and settings) into a container that runs the same way on any machine. This Docker tutorial for beginners walks you through the core ideas, the commands you will use every day, and a small hands-on project: containerising a Python web app, then running it with a database using Docker Compose. Follow along on your own laptop; you only need about an hour.

What is Docker, in plain words?

Before Docker, a common problem was it works on my machine. A developer’s laptop had one Python version and one set of libraries, while the test server had another. Docker solves this by shipping the application together with its environment.

Four terms explain almost everything:

  • Image: a read-only template that contains your app and its dependencies. Think of it as a recipe that has already been cooked and frozen.
  • Container: a running instance of an image. You can start many containers from the same image.
  • Dockerfile: a text file with step-by-step instructions to build an image.
  • Registry: a place to store and share images. Docker Hub is the public default; companies also use Amazon ECR, Azure Container Registry or GitHub Container Registry.

Containers vs virtual machines

Both isolate applications, but they do it at different levels.

PointContainerVirtual machine
What is virtualisedThe operating system (shares the host kernel)The hardware (each VM has its own OS)
SizeUsually tens to hundreds of MBUsually several GB
Start timeSeconds or lessOften minutes
Best forMicroservices, CI/CD, consistent dev environmentsRunning different operating systems, strong isolation

In real companies you will see both: containers often run on top of cloud virtual machines.

Step 1: Install Docker

  • Windows and macOS: install Docker Desktop from the official Docker website. On Windows, enable WSL 2 when the installer asks.
  • Linux (Ubuntu): install Docker Engine using the official repository instructions, then add your user to the docker group so you do not need sudo for every command.

Check the installation:

docker --version
docker run hello-world

If you see a Hello from Docker! message, Docker downloaded a tiny image from Docker Hub and ran it as a container. That is the whole Docker workflow in one line.

Step 2: The commands you will use every day

# images
docker pull nginx:alpine        # download an image
docker images                   # list local images
docker rmi nginx:alpine         # remove an image

# containers
docker run -d -p 8080:80 --name web nginx:alpine   # run in background
docker ps                       # running containers
docker ps -a                    # all containers, including stopped
docker logs web                 # see output
docker exec -it web sh          # open a shell inside the container
docker stop web                 # stop it
docker rm web                   # delete it

# cleanup
docker system prune             # remove unused data

Run the nginx example, then open http://localhost:8080 in your browser. The flag -p 8080:80 maps port 8080 on your laptop to port 80 inside the container. Port mapping is one of the most common things beginners get wrong, so read it as host:container.

Step 3: Write your first Dockerfile

Create a folder called docker-demo with two files. First, a tiny Flask app in app.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello from a container!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Then a requirements.txt containing one line: flask. Now the Dockerfile:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

What each line does:

  • FROM picks a base image. The slim variant is smaller than the full image.
  • WORKDIR sets the folder inside the container.
  • COPY requirements.txt first, then RUN pip install. Copying the dependency list before the code means Docker can reuse the cached layer when only your code changes, which makes rebuilds much faster.
  • EXPOSE documents the port the app listens on.
  • CMD is the command that runs when the container starts.

Build and run it:

docker build -t docker-demo:1.0 .
docker run -d -p 5000:5000 --name demo docker-demo:1.0

Visit http://localhost:5000. You have just containerised an application.

Step 4: Keep data with volumes

Containers are disposable. When you delete one, any files written inside it are gone. To keep data, such as a database, use a volume:

docker volume create pgdata
docker run -d --name db -e POSTGRES_PASSWORD=secret -v pgdata:/var/lib/postgresql/data postgres:16

Now you can remove and recreate the db container and the data in pgdata stays. During development you can also use a bind mount (-v $(pwd):/app) so code changes on your laptop appear inside the container immediately.

Step 5: Run several containers with Docker Compose

Real applications usually need more than one container, for example a web app and a database. Docker Compose describes them in one compose.yaml file:

services:
  web:
    build: .
    ports:
      - 5000:5000
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:
docker compose up -d     # start everything
docker compose ps        # status
docker compose logs web  # logs for one service
docker compose down      # stop and remove

Inside the Compose network, the web app can reach the database using the hostname db, because Compose creates a private network and a DNS name for each service.

Step 6: Push your image to a registry

docker login
docker tag docker-demo:1.0 yourname/docker-demo:1.0
docker push yourname/docker-demo:1.0

Anyone (or any server) can now run your app with a single docker run. This is exactly how CI/CD pipelines ship code: build an image, push it, then deploy it to a server or a Kubernetes cluster.

Dockerfile best practices

  • Use small, official base images such as -slim or -alpine variants, and pin a version tag instead of latest.
  • Order layers from least to most frequently changed so the build cache works for you.
  • Add a .dockerignore file to keep .git, virtual environments and secrets out of the image.
  • Do not bake passwords into images. Pass them as environment variables or use a secrets manager.
  • Run as a non-root user with the USER instruction in production images.
  • Use multi-stage builds for compiled languages, so build tools are not shipped in the final image.

Common beginner mistakes

  • App listens on 127.0.0.1 inside the container. It must listen on 0.0.0.0, or the port mapping will not reach it.
  • Confusing image and container. You build images; you run containers.
  • Forgetting volumes and losing database data when a container is removed.
  • Huge images because everything was copied before installing dependencies, or because the full base image was used.

Practice tasks

  1. Containerise a small project you already have, in any language.
  2. Add a Postgres or MySQL container with Compose and connect your app to it.
  3. Reduce your image size by switching to a slim base image and adding a .dockerignore. Compare sizes with docker images.
  4. Push the image to Docker Hub and run it on a free cloud VM.

Put each task in a GitHub repository with a short README. Recruiters for DevOps roles look for exactly this kind of evidence.

What to learn after Docker

Once you are comfortable with images, containers, volumes and Compose, move on to Kubernetes, which runs containers across many machines, and to CI/CD tools such as Jenkins or GitHub Actions that build and push images automatically. Our DevOps roadmap for beginners shows where Docker fits in the full learning path, and our DevOps interview questions include the Docker questions that interviewers ask most often.

Frequently asked questions

Is Docker hard to learn for beginners?

No. Most people can run containers and write a basic Dockerfile within a few days of practice. It helps to know basic Linux commands first, because most containers run Linux.

Do I need Linux to use Docker?

No. Docker Desktop runs on Windows and macOS. Behind the scenes it uses a small Linux virtual machine, so learning Linux basics still pays off.

What is the difference between Docker and Kubernetes?

Docker builds and runs containers on one machine. Kubernetes orchestrates containers across a cluster of machines, handling scaling, self-healing and rolling updates. Learn Docker first.

Is Docker free?

Docker Engine is open source and free. Docker Desktop is free for personal use, education and small businesses; larger companies need a paid subscription, so check the current licence terms on the Docker website.

What is the difference between CMD and ENTRYPOINT?

ENTRYPOINT sets the main executable of the container, while CMD provides default arguments that are easy to override at docker run. For most beginner projects, CMD alone is enough.

Explore more DevOps tutorials on Radium4.

Other articles

Radium4 — IT training blog

Practical, plain-English guides for DevOps, cloud, data, Python, testing and security learners.