Home Projects Services Blog Contact
Back to Blog

Docker in 10 minutes

What images and containers are, why teams deploy with them, and how to run your first one.

TL;DR

Docker packages your app with its runtime and dependencies into an image. A container started from that image behaves the same on your laptop, on a server in Paris or on a VPS in Tunisia, which removes most 'works on my machine' problems.

The problem Docker solves

The app runs fine on your laptop. A colleague clones it and it crashes. You deploy it to the server and it crashes again, with a different error.

Usually the cause is the environment, not the code: Python 3.11 locally and 3.8 on the server, version 2.0 of a library on one machine and 1.5 on another, a system package that only you installed. Docker ships the environment along with the code, so those differences go away.

The host doesn't need to know what's inside a container. As long as Docker is installed, it can run a Django app, a Node service and a PostgreSQL database side by side, each with its own versions.

Image vs container

An image is a read-only template: a base OS layer, your runtime, your dependencies and your code, stacked in layers. A container is a running instance of an image. You can start ten containers from the same image and each one gets its own isolated copy.

Under the hood, a container is a regular process on the host, isolated with Linux namespaces and cgroups. It has its own filesystem, network and process list, but it shares the host's kernel. That's why it starts in seconds and uses far less memory than a virtual machine.

Your first Docker commands

Terminal
# Pull and run an official image
docker pull nginx
docker run -p 8080:80 nginx

# List running containers
docker ps

# Stop a container
docker stop <container_id>

# Run interactively
docker run -it ubuntu bash

Your first Dockerfile

A Dockerfile lists the steps to build your image. Copy the dependency file and install it before copying the rest of the code: Docker caches each step, so dependencies are only reinstalled when requirements.txt changes. This example uses Django's development server; in production you would run gunicorn or uvicorn instead.

Dockerfile: Django app (development)
FROM python:3.11-slim

WORKDIR /app

# Install dependencies first (caching)
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy your code
COPY . .

EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

If you host from Tunisia, the usual VPS providers (OVH, Contabo, Hetzner) all run Docker without any special setup. For a Django or Next.js app on a single VPS, Docker with Compose is a standard way to deploy today.

Docker Compose for multiple services

Most apps need more than one container, typically the app and a database. Compose describes all of them in one file, with their ports, environment variables and volumes, and starts everything with docker compose up. The named volume keeps your PostgreSQL data when the container is recreated.

docker-compose.yml
services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Key takeaways

Docker has become a baseline skill for anyone who deploys software. Learn the image and container model, write a Dockerfile for one of your own projects, then add Compose. After that, deploying to a fresh server mostly comes down to installing Docker and running one command.

Tous les articles Article suivant