Containers and Images: First Docker Commands

First lesson of the Docker and Deployment course, free to read: about 15 minutes, 3 exercises and 3 quiz questions. This is the catalogue's base lesson; in the student space, it is rewritten for your profile.

Objectives

  • Explain the difference between an image, a container, and a virtual machine
  • Run, inspect, and stop a container with the Docker CLI
  • Publish a port and mount a volume

ContainersImagesDocker CLI

“It works on my machine”: the phrase every developer has heard. The application works locally, but in production the Node version, a system library, or an environment variable differs. Docker solves this problem by packaging the application with its whole environment in an image that runs the same way everywhere.

The vocabulary

  • Image: a read-only template (file system + metadata), built in successive layers. Example: node:22-slim.
  • Container: a running instance of an image, with its own writable layer. You can run ten containers from the same image.
  • Registry: a repository of images (Docker Hub, GitHub Container Registry, cloud registries).

Unlike a virtual machine, a container does not include a complete operating system: it shares the host’s kernel and isolates itself using Linux namespaces and cgroups. It starts in a fraction of a second and weighs a few tens of MB.

A container’s lifecycle

# Download an image from Docker Hub
docker pull nginx:1.27-alpine

# Run a container in the background (-d), named, host port 8080 -> container port 80
docker run -d --name web -p 8080:80 nginx:1.27-alpine
# http://localhost:8080 shows the nginx welcome page

docker ps                 # running containers (-a to include stopped ones)
docker logs -f web        # follow the logs (the process's standard output)
docker exec -it web sh    # open a shell INSIDE the container
docker stop web           # stop gracefully (SIGTERM signal then SIGKILL)
docker rm web             # remove the container
docker images             # images present locally

A container lives as long as its main process. If that process ends, the container stops.

Publishing ports

By default, a container is isolated from the host’s network. The -p HOST:CONTAINER option publishes a port: -p 3000:3000 makes a Node API reachable on localhost:3000. To expose it only locally: -p 127.0.0.1:3000:3000.

Persisting data

Everything written inside the container is lost when it is removed. For a database, use a volume:

docker volume create pgdata
docker run -d --name db \
  -e POSTGRES_PASSWORD=dev_seulement \
  -v pgdata:/var/lib/postgresql/data \
  -p 127.0.0.1:5432:5432 \
  postgres:17
  • -e sets an environment variable;
  • -v pgdata:/path mounts the named volume: you can delete and recreate the container without losing the data.

In development, you also mount a host folder (bind mount): -v "$PWD":/app.

Cleaning up

docker system df          # space used
docker container prune    # removes stopped containers
docker image prune        # removes untagged images

Key takeaways

Image = template, container = instance. docker run with -d, -p, -e, -v, and --name covers most uses; ps, logs, and exec are for diagnosis.

Exercises

Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.

  1. TaskDifficulty 11 hint

    Run and inspect a web server

    Run an nginx:1.27-alpine container named vitrine, in the background, reachable on port 8080 of your machine. Check that it responds, look at its logs, open a shell in it to list /usr/share/nginx/html, then stop it and remove it.

    • `docker ps` shows the `vitrine` container with `0.0.0.0:8080->80/tcp`
    • `curl -I http://localhost:8080` returns `HTTP/1.1 200 OK`
    • `docker logs vitrine` shows the GET request made by curl
    • `docker exec vitrine ls /usr/share/nginx/html` lists `index.html`
    • After `docker stop vitrine && docker rm vitrine`, `docker ps -a` no longer shows it
  2. TaskDifficulty 21 hint

    Persist data with a volume

    Create a volume notes. Run an alpine:3.20 container that writes the date to /data/journal.txt, mounting this volume on /data, then remove the container. Run a second container with the same volume and display the file.

    • `docker volume ls` lists the `notes` volume
    • The first container is run with `-v notes:/data` and the `--rm` option
    • The second container displays the contents of `/data/journal.txt` with `cat`
    • The date written by the first container is indeed present
  3. Multiple choiceDifficulty 11 hint

    Image or container?

    You run docker run -d nginx:1.27-alpine three times. How many images and containers do you have?

    • 3 images and 3 containers
    • 1 image and 3 containers
    • 1 image and 1 container
    • 3 images and 1 container

End-of-lesson quiz

  1. What does a container share with the host machine?

    • Nothing, it brings its own kernel
    • The operating system kernel
    • Its database
  2. What does -p 8080:3000 do?

    • Publishes container port 3000 on host port 8080
    • Publishes container port 8080 on host port 3000
    • Limits memory
  3. Which command opens a shell in a running container?

    • docker run -it name sh
    • docker exec -it name sh
    • docker logs name

The rest of the course

  1. Writing a Dockerfile for Your Application18 min
  2. Optimizing and Securing Your Images18 min
  3. Docker Compose: Orchestrating a Multi-Service Application18 min
  4. Deploying to Production: Registry, CI/CD, and HTTPS20 min

Docker and Deployment · Advanced · 3 h 59 min