Containers and Docker: the same box everywhere
Why:“It works on my machine” stops being an excuse once a program travels in a box with everything it needs. Afterwards you’ll tell an image, a container and a volume apart, read and write a Dockerfile and a compose file for your project’s site, run a container in a simulator and decide honestly whether you need one at all.
30 minutes
Read by speech synthesis (Qwen3-TTS); the voice is not a person’s.
Docker packs a program and what it needs into an image and runs it as a container anywhere. A Dockerfile defines the image, compose.yaml a set of containers.
“It works on my machine”
Everyone who has ever moved a program to another computer has this story. On the laptop the site works, and on the server it doesn’t: the language version is different, a library is missing, the web server is set up another way. People used to close that gap with ten pages of instructions (“install this, then that, then fix that file”), and the instructions went stale.
The solution was borrowed from shipping. Cargo used to travel any which way: sacks, barrels, crates, and every port loaded it differently. The standard container changed everything: whatever is inside, the port, the train and the truck treat the box the same. In programming the logic is the same. A program is packed together with everything it needs, and from then on you don’t care which computer runs it.
Image, container, volume
These are three words you need to keep apart.
- An image is a ready, unchangeable “box”: a trimmed-down system, your program, its libraries and settings. An image is made of layers, each adding something to the one before.
- A container is a running instance of an image: a process that believes it has a file system and a network of its own. You can run as many containers as you like from one image. An image is the recipe for a cake, and a container is the cake on the table.
- A volume is a place for data that lives apart from the container. Whatever a container wrote inside itself disappears with it. So what you’d hate to lose (requests, uploaded files, the database) is kept on a volume or in a separate database.
There is also the registry: a store of images, where they are downloaded from (Docker Hub, and the big clouds and GitHub have registries of their own). From a registry you take other people’s images (a ready-made nginx, say), and into a registry you publish your own.
You’ll remember the difference from a virtual machine in one phrase: a virtual machine carries a whole operating system with it, while a container uses the host system’s kernel and isolates only its own process. So a container takes megabytes and starts in seconds. The price: the isolation is weaker than a virtual machine’s.
Check yourself: what happens to the data a container wrote inside itself if you remove it?
It disappears with the container. For data that has to be kept you need a volume or a separate database.
The recipe for an image
An image is described in a file named Dockerfile: short lines of instructions, each making one layer.
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/
EXPOSE 80 Read it as a recipe. FROM says which ready image to start from (here the nginx web server in the light alpine build). COPY puts your site’s built files from the dist folder into the image (the build gives you that folder, as you learned in the parts on JavaScript and generators). EXPOSE warns that the thing inside listens on port 80. Everything else needed to serve files is already in nginx.
When the site has to be built first, a multi-stage build helps: in the first stage Node.js builds the site, and in the second only the finished result goes into a clean nginx, with no Node and no sources.
FROM node:lts-alpine AS build
WORKDIR /app
COPY package.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80 Two features save time and nerves. First: Docker remembers layers, and if an instruction and everything before it are unchanged, it takes the layer from the cache. So you copy what rarely changes first (package.json) and what changes often after it (the code). Second, and the main one: secrets don’t go into an image. The line ENV API_KEY=... writes the key into a layer for good: images get published and copied, and the key travels with them. Secrets are passed at launch. A small thing: a .dockerignore file keeps what you don’t need (a .env, say, or the node_modules folder) out of the image.
Several containers as one project
A project usually has several parts: the site, a program that receives requests, sometimes a database. Starting each with a command of five flags is awkward, so there is Compose: one file, compose.yaml, describes all the containers, ports, volumes and the links between them.
services:
site:
build: .
ports:
- "8080:80"
restart: unless-stopped
receiver:
build: ./receiver
env_file: .env
volumes:
- requests:/data
restart: unless-stopped
volumes:
requests: Here ports: "8080:80" joins port 8080 of your computer to port 80 inside the container (the left is “outside”, the right “inside”). env_file: .env takes secrets from a file that goes neither into the image nor into the repository. requests:/data attaches the volume requests to the receiver’s folder /data, and the volume is declared in the volumes section at the bottom. To start the whole project: docker compose up -d; its state: docker compose ps; to stop it: docker compose down (the volumes stay).
Try it in the simulator
There is no real Docker in a browser, so this is a simulator: the page reads the commands itself. But the order of things and the messages are real. Choose a Dockerfile (in the third one a key is written into the image, so see what the build says), build the image, run the container, open the site with curl, then stop and remove the container.
There are no images. Build one: docker build -t site .
There are no containers.
What to notice. If you run a container without -p, it works but can’t be opened from outside. If a port is already taken by another container, you get an error. A second build takes unchanged layers from the cache. And the site curl returns is signed with your project’s name.
If you want to try it for real, install Docker Desktop or its free replacement Podman and repeat the same commands in a terminal. Docker Desktop is free for companies with fewer than 250 employees and less than $10 million a year in revenue, and for non-commercial open source; Docker also lists a free Personal plan for individuals, subject to its license terms, and larger organizations need a paid subscription (Docker’s FAQ, October 2026). Docker Engine itself on Linux is open source.
Check yourself: what does -p 8080:80 mean in the run command?
Port 8080 of your computer is joined to port 80 inside the container. Without it the container works but can’t be opened from outside.
Honestly: when Docker is overkill
Containers have a price: you have to learn them, update the base images (vulnerabilities are found in those too), and watch the disk and the logs. So the honest question is: what do they solve for you?
- A site of static files. You don’t need Docker at all: the files go on static hosting, which is cheaper and more reliable. A container with nginx for one page is a complicated way of doing something simple.
- One machine, a fixed environment. An “identical box” gains nothing.
- Several programs that must run the same way for you, your colleague and the server (the site, a request receiver, a database): here Docker and Compose pay off.
- A project whose main action a ready-made service covers (receiving forms, booking, payment): there is nothing to pack.
Compare the first lesson of the part. The steps of hosting were a ladder too, and Docker is one more rung, not a necessity.
Practice
In front of you is your project’s site, and under it two files in boxes: a Dockerfile and compose.yaml. Finish them on the model in the lesson. Then open the simulator, build the image, run the container with its port, and paste the line from docker ps into the note. Say what is on the volume (through your project’s main action), and answer the last question: do you need Docker?
The check reads the texts in the boxes. Docker can’t be run in the sandbox, so running it in the simulator remains your job, and the note shows that it worked.
What was wrong before
In 2010 the unit of moving was a server: an admin set up a machine by hand, and a year later no one remembered how exactly. Such servers were called “snowflakes”: each is unique, and you can’t make a copy. A move meant a week of manual work and several “oh, we also need to install…”. A container turned the setup into a file that lies in the repository, can be read and reproduced. But, as always with convenient things, the main point remains: a container packs not the knowledge but only its record, and understanding what is inside is still your job.
Practice
Preparing your page…
Test
Question 1 of 5
Cards
These cards go into your review once you finish the lesson.
How does an image differ from a container?
Answer
An image is an unchangeable template (layers: the system, the program, the settings). A container is a running instance of an image. You can run many containers from one image.
What is a volume for?
Answer
Whatever a container writes inside itself disappears with it. A volume keeps data apart: the container can be removed and created again, and the data stays.
The main Dockerfile instructions
Answer
FROM (the base image), WORKDIR, COPY (put files in), RUN (a command at build time), ENV, EXPOSE (which port it listens on), CMD (what to run). Each instruction makes a layer, and unchanged layers come from the cache.
How do you handle secrets in Docker?
Answer
Don’t write them into the Dockerfile (ENV, ARG) or into a compose file kept in the repository. Pass them at launch: environment variables, an env_file with a .env file outside the repository, a secrets manager.
When is Docker not needed?
Answer
For a site of static files (static hosting is enough) and when there is one environment that never changes. It is useful when several programs must run the same way in different places.
Sources
- Docker Docs: What is Docker? link only, in English
- Docker Docs: Dockerfile reference link only, in English
- Docker Docs: Docker Compose link only, in English
- Docker (software) (Wikipedia) CC BY-SA, in English
- The Twelve-Factor App link only, in English
Videos
Docker in 100 Seconds (Fireship)
The video loads from youtube-nocookie.com only when you press play.
Docker Tutorial for Beginners, full course (TechWorld with Nana)
The video loads from youtube-nocookie.com only when you press play.
Next
You now know: containers and Docker, Dockerfile and Compose.