Package an app + its runtime into a portable artifact (image) and run it (container).
an image is a class; a container is an instance. The image is read-only; the container adds a thin writable layer on top.
Dockerfile --docker build--> Image (read-only layers)
|
v
docker run ----> Container
(image + writable top layer)
(process, network, fs)
A Docker image is an immutable, layered artifact stored in a registry (Docker Hub, ECR, GHCR). Each layer is a diff against the layer below. A container is a running instance: writable top layer, isolated network namespace, resource limits. Cleanup: docker rm for container, docker rmi for image. Treat containers as ephemeral; persist state via volumes or external stores (DB, S3).
docker pull nginx:1.25
docker images | grep nginx
docker inspect nginx:1.25 | jq '.[0].Config'
pulls an image, lists it, and dumps runtime config (Env, Cmd, exposed ports).
docker run -d --name web -p 8080:80 nginx:1.25
docker ps
curl http://localhost:8080
runs nginx as a daemon; exposes host 8080 -> container port 80.
docker exec -it web bash
docker stop web
docker rm web
drops into a shell in the running container; stops and removes it.
Assuming data persists when the container is removed - without a volume mount, the data is GONE (only the writable top layer survives). Also: docker system prune --volumes can wipe work in progress.
image = class, container = instance. Build once, run anywhere. Treat containers as ephemeral; persist state in volumes or external stores. Tag images explicitly (no latest in prod).
docker inspect.docker run postgres without -v pgdata:/var/lib/postgresql/data; FS changes lost on removal.latest resolved to 1.26 overnight.myapp:latest; docker pull resolved to new sha.latest in prod manifests; image-promotion pipeline ships tagged versions.