NAWAZ SHARIF
October 17, 2026 · DevOps · By Nawaz Sharif

Docker for Beginners: Images, Containers and Your First Dockerfile

"It works on my machine" is one of the oldest problems in software. An application runs perfectly on a developer's laptop, then fails on the server because of a different operating system, library version or configuration. Docker solves this by packaging an application together with everything it needs, so it runs the same way everywhere. This guide explains Docker from scratch, with a diagram, your first Dockerfile and the commands you will use every day.

What is Docker?

Docker is a platform for building, shipping and running applications in containers. A container is an isolated process that includes your code, its libraries and its settings. A virtual machine runs a complete guest operating system on top of a hypervisor, which is heavy and slow to start. A container shares the kernel of the host machine and packages only the application and its dependencies, so it is small and starts in seconds.

That is why Docker is so popular for web applications, automated testing, CI/CD pipelines and microservice architectures.

The four core concepts

The diagram below shows how the main pieces fit together.

Docker workflow diagram A Dockerfile is built into an image, and the image runs as a container. Images are pushed to and pulled from a registry such as Docker Hub. Everything runs on the Docker Engine of the host machine. Dockerfile the recipe Image the template Container running app build run Registry e.g. Docker Hub push pull Docker Engine runs on your laptop or server and shares the host kernel
Figure 1: The Docker workflow. A Dockerfile is built into an image, the image runs as a container, and images travel through a registry.

Installing Docker

On Windows and macOS, install Docker Desktop from the official Docker website. On Linux, follow the official instructions for your distribution to install Docker Engine. Then check that it works:

docker --version
docker run hello-world

The second command downloads a tiny test image and runs it. If you see a welcome message, Docker is ready.

Your first container

Let us run the Nginx web server without installing anything on your machine:

docker run -d -p 8080:80 --name web nginx

The flag -d runs the container in the background, -p 8080:80 maps port 8080 on your computer to port 80 inside the container, and --name web gives it a friendly name. Open http://localhost:8080 in your browser and you will see the Nginx welcome page. These commands manage it:

docker ps              # list running containers
docker logs web        # show the container's output
docker stop web        # stop it
docker rm web          # remove it
docker images          # list downloaded images

Writing your first Dockerfile

Here is a simple Dockerfile for a small Python application:

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"]

Each line has a purpose. FROM chooses the base image. WORKDIR sets the working folder inside the container. COPY adds files, and RUN executes a command while the image is being built. EXPOSE documents the port the app uses, and CMD sets the command that starts when the container runs.

Notice that requirements.txt is copied and installed before the rest of the code. Docker caches every step, so when only your source code changes, the slow dependency installation is skipped. Also create a .dockerignore file to keep things like .git and local secrets out of the image.

Build and run it:

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

Keeping data with volumes

Containers are temporary. When you remove one, everything written inside it is lost. To keep data such as a database, use a volume:

docker volume create mydata
docker run -d -v mydata:/app/data --name myapp myapp:1.0

The volume lives outside the container, so your data survives restarts and upgrades.

Running several services with Docker Compose

Real applications often need more than one container, such as a web app and a database. Docker Compose describes them all in one docker-compose.yml file:

services:
  web:
    build: .
    ports:
      - "5000:5000"
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - dbdata:/var/lib/postgresql/data
volumes:
  dbdata:

Start everything with docker compose up -d and stop it with docker compose down. The password above is only for local learning. In a real project, load secrets from environment files or a secrets manager.

Security basics

The host matters too. Harden the server that runs Docker by following my guide on securing Linux servers.

Common beginner mistakes

Forgetting the -p flag, so the app runs but cannot be reached. Storing important data inside a container without a volume. Using the latest tag, which can change without warning. Building huge images by copying unnecessary files. And leaving old containers and images around: use docker system prune to clean up, but read its warning first, because it deletes unused data.

Summary

Docker packages your application and its environment into an image, runs that image as a container, and shares it through a registry. Start with docker run, write a small Dockerfile, use volumes for data, and move to Compose when you have more than one service. If you want to practise the commands behind all this, see my guide to essential Linux commands.

← All articles