Run services
Deploy with Docker Compose
Define one service, persistent storage, restart behavior, and a loopback-only published port.
10 minute lesson
You could start containers with long docker run commands, but those live in your shell history and nowhere else. Compose records the desired container, image, volumes, ports, and restart policy in one reviewable file. The file is the deployment: you can read it, diff it, back it up, and reproduce the service on a rebuilt host.
Define one small service
Create a directory like /opt/services/whoami and inside it a compose.yaml for a small service image you trust:
services:
web:
image: traefik/whoami:v1.11.0
restart: unless-stopped
ports:
- '127.0.0.1:8081:80'
Three deliberate choices here. The image tag is pinned to v1.11.0, not latest, so today’s working deployment is still the same deployment next month. restart: unless-stopped makes Docker bring the container back after a crash or a reboot — unless you stopped it on purpose. And the port mapping binds to 127.0.0.1, so the service answers on the server’s loopback interface only. Nothing on the LAN can reach it directly; the HTTPS proxy lesson adds the deliberate entry point later.
Start it and verify
cd /opt/services/whoami
docker compose up -d
docker compose ps
docker compose logs web
curl http://127.0.0.1:8081
docker compose ps should show the container Up. The curl from the server itself returns the whoami response — hostname, headers, addresses.
Now verify the boundary from your laptop:
curl --max-time 3 http://192.168.1.20:8081
# curl: (28) Connection timed out ...
The timeout is a success. It proves the loopback binding works: the service runs, and the network can’t touch it. If your laptop gets a response instead, the port line lost its 127.0.0.1: prefix and the service is published to the whole LAN.
The failure mode
Treating images casually. A container image is executable supply-chain input, not a harmless data file — you’re running someone else’s code as a long-lived service on your network. Pin reviewed image versions, prefer official or well-known publishers, and read the image’s page before the first up. An unpinned latest tag also breaks reproducibility: the rollback lesson depends on knowing exactly which version you were running.
Lesson completed