Learn containers by doing. Read a concept, then type the real command in the simulated Docker terminal. No installation needed — it runs entirely in your browser.
1 What is Docker?
Docker is a platform for running containers. A container is a lightweight, isolated process that packages an application together with everything it needs — code, runtime, libraries and settings — so it runs identically on any machine.
Virtual machine
Each VM includes a full guest operating system. Boots slowly, is large (GBs), and several VMs per host.
Container
Shares the host kernel, no guest OS. Starts in seconds, is tiny (MBs), and you can run dozens on one host.
Image — a read-only template (the "blueprint") for a container, built from layers.
Container — a running (or stopped) instance of an image.
Dockerfile — a text file describing how to build an image.
Registry — where images are stored; Docker Hub is the default public one.
💡 Why it matters: "works on my machine" disappears — the same image runs on a laptop, a test server and production.
2 Images & containers
Images are pulled from a registry. A container is created when you run an image. Images use a layered filesystem: each instruction in a Dockerfile adds a layer that is cached and shared between images.
docker pull nginx # download the nginx image
docker images # list local images
docker run hello-world # run a tiny test image
docker ps # list RUNNING containers
docker ps -a # list ALL containers (incl. stopped)
💡 One image → many containers. Containers are ephemeral: data written inside is lost when the container is removed unless you use a volume.
3 Your first containers
The core lifecycle you will use constantly:
docker run -d -p 8080:80 --name web nginx # start in background
docker logs web # view its logs
docker stop web # stop it
docker start web # start again
docker rm web # delete (must be stopped)
docker rm -f web # force-remove a running one
-d = detached (run in the background).
-p host:container = publish a port so you can reach it.
--name = give the container a friendly name instead of a random one.
4 Run options in detail
# Interactive shell inside a container
docker run -it ubuntu bash
docker exec -it web sh # open a shell in a running container
docker exec web cat /etc/os-release # run one command# Environment variables & cleanup
docker run -e MY_VAR=hello alpine env
docker run --rm alpine echo "gone after exit"
-it = interactive + allocate a TTY (for shells).
-e KEY=VAL = set an environment variable.
--rm = automatically remove the container when it exits.
5 Building images — the Dockerfile
A Dockerfile is a recipe. Common instructions:
FROM node:20-alpine # base imageWORKDIR /app # working directoryCOPY package*.json ./ # copy files into the imageRUN npm install --omit=dev # execute a build stepCOPY . .
EXPOSE 8080 # document the portCMD ["node","server.js"] # default command
docker build -t myapp:1.0 . # build, tag as myapp:1.0
docker images # see your new image
docker run -d -p 8081:8080 myapp:1.0
💡 -t sets name:tag. The . is the build context (current directory). Layers are cached, so rebuilding after a small change is fast.
6 Data & volumes
Container files vanish when the container is removed. To keep data, mount a volume (managed by Docker) or a bind mount (a host directory).
docker volume create webdata
docker run -d -p 8090:80 \
-v webdata:/usr/share/nginx/html --name site nginx
docker volume ls
docker volume inspect webdata
Named volume-v name:/path — Docker manages storage; best for databases and persistent data.
Bind mount-v /host/path:/path — mirrors a host folder; great for development.
7 Networking
By default containers attach to the bridge network and reach each other via IP. For name-based service discovery, put them on the same user-defined network.
docker network create webnet
docker network ls
docker run -d --network webnet --name api nginx
docker run --rm --network webnet alpine ping -c1 api
💡 On a user-defined network, containers resolve each other by name. Port publishing (-p) is only needed to reach a container from outside Docker.
8 Docker Compose
Compose defines multi-container apps in a docker-compose.yml file and starts them with one command.
docker compose up -d # start all services in background
docker compose ps # service status
docker compose logs # combined logs
docker compose down # stop and remove everything