You've learned for 25 minutes. A short break helps your brain.
Sprint done! Great focus. Stretch for a minute?
Docker cheat sheet
The commands you learned, in one place.
Your laptop (D0 basics)
curl localhost:8080Ask hatch 8080 on this laptop for its page.curl -I localhost:8080Only the top of the reply, with the status code.curl 127.0.0.1:8080The same, using localhost's number.chmod +x cook.shLet cook.sh run as a program.ls -lSee the permissions: r read, w write, x run.export CHEF=KancilStick a note on the wall: CHEF is Kancil.echo $CHEFRead the note back.envList every environment variable.ps auxEvery process on this computer, with its PID.echo $?0 means all good. Anything else means trouble.
Run containers
docker versionIs Docker here and awake?docker infoCounts of containers and images, and more.docker run -d --name web -p 8080:80 nginx:1.30-alpineRun nginx in the background. Open hatch 8080.docker run hello-worldYour first container: it prints a hello.docker run --rm alpine:3.22 echo hiRun once, then clean the box away.docker run -it alpine:3.22 shGet a shell inside. Type exit to leave.docker run -d -e POSTGRES_PASSWORD=secret postgres:18-alpineGive the app a setting with -e.docker run -d -v pgdata:/var/lib/postgresql postgres:18-alpineKeep data in a locker (volume).docker ps -aShow all containers, stopped ones too.docker ps -qOnly the ids.docker ps --filter status=exitedOnly stopped containers.docker stop webStop web. It still exists.docker start webStart it again.docker restart webStop and start in one go.docker kill webStop at once, no clean-up (exit 137).docker pause webFreeze it; docker unpause web wakes it.docker port web80/tcp -> 0.0.0.0:8080 means: use localhost:8080.
Look inside
docker logs webRead web's messages.docker logs -f webKeep watching new lines. Ctrl+C stops.docker logs --tail 5 webOnly the last 5 lines.docker exec -it web shStep inside web. exit brings you back.docker exec web ls /usr/share/nginx/htmlRun one command and come back.docker inspect -f '{{.State.Status}}' webJust the state of web.docker top webnginx's master and workers.docker stats --no-streamMemory and CPU of each container, once.docker infoLook for Default Runtime: runc and Cgroup Version.docker diff boxEvery change in box, compared with its image.docker cp index.html web:/usr/share/nginx/html/Put a page into web.Risk: Carefuldocker cp web:/etc/nginx/conf.d/default.conf .Copy a file out.Risk: Careful
Images and recipes
docker imagesU in EXTRA means a container uses it.docker pull nginx:1.30-alpineGet nginx 1.30 on Alpine. Pin the tag!docker build -t diary:1.0 .Build this folder into diary:1.0.docker build --target build -t app:build .Stop at one stage of a multi-stage recipe.docker build --no-cache -t diary:1.0 .Bake every layer again.docker history diary:1.0Newest layer on top.docker tag diary:1.0 you/diary:1.0Add your Docker Hub name in front.docker buildx build --platform linux/amd64,linux/arm64 -t hello:1.0 .One name, a pack for each CPU.docker images --tree helloSee the packs inside one name.docker build --secret id=npm_token,src=token.txt -t api:1.0 .Lend a secret to RUN --mount=type=secret steps.
Lockers and phone lines
docker volume create pgdataMake a locker called pgdata.Risk: Carefuldocker volume lsList your lockers.Risk: Carefuldocker volume rm pgdataDelete a locker and its data. Careful!Risk: Carefuldocker volume inspect pgdataWhere the locker lives, and when it was made.Risk: Carefuldocker run --rm -v pgdata:/from -v "$PWD":/to alpine:3.22 tar czf /to/backup.tar.gz -C /from .Back up a locker into one file here.Risk: Carefuldocker network create shopnetA new line. Start containers with --network shopnet.docker network connect shopnet webPlug a running container in.docker network lsList the lines: bridge, host, none and yours.docker network inspect shopnetSee who is plugged into shopnet.
Set meals (Compose)
docker compose up -dBuild, pull and start it all in the background.docker compose --profile cache up -dAlso start services in the cache profile.docker compose up -d --scale api=2Run two api containers.docker compose downClear the table, keep the lockers.Risk: Carefuldocker compose down -vAlso delete the volumes and their data.Risk: Carefuldocker compose psEvery service with its state and ports.docker compose logs apiLogs of one service.docker compose exec api shA shell inside the api service.docker compose configThe final compose.yaml, with variables filled in.docker compose restart apiRestart one service.docker compose watchSave a file, see the change.
Share images
echo $DOCKER_TOKEN | docker login -u you --password-stdinLog in with a token, safely.Risk: Carefuldocker logoutForget the login.Risk: Carefuldocker push you/diary:1.0Put diary 1.0 in your Docker Hub account.Risk: Carefuldocker scout cves --only-severity critical,high kedai:1.0Only the two worst kinds of holes.docker scout quickview kedai:1.0A short summary of the holes.docker scout cves --exit-code kedai:1.0Exit code 2 when it finds holes. Good for scripts.docker buildx imagetools inspect ghcr.io/you/kedai-api:1.0Digest, platforms and attestation manifests.docker buildx imagetools inspect ghcr.io/you/kedai-api:1.0 --format '{{ json .SBOM.SPDX }}'The SBOM: every package inside.docker buildx imagetools inspect ghcr.io/you/kedai-api:1.0 --format '{{ json .Provenance.SLSA }}'The provenance: how it was built.
Clean up
docker rm webRemove web. Volumes stay.Risk: Can lose workdocker rm -f webStop and remove a running one. Careful!Risk: Can lose workdocker rmi diary:1.0Remove diary:1.0.Risk: Carefuldocker system dfRECLAIMABLE is what a clean-up could free.docker system pruneIt asks first. y deletes, N keeps.Risk: Can lose workdocker container pruneOnly stopped containers.Risk: Can lose workdocker image prune -aEvery image no container uses.Risk: Can lose workdocker volume pruneUnused unnamed volumes. With -a: all unused volumes!Risk: Can lose workdocker builder pruneOld build cache.Risk: Can lose work