Card 03/ 06
Building an Image With docker build and Running It
From a project with a Dockerfile to a container answering on a port, with the old version kept.
docker build turns a directory containing a Dockerfile (a text file listing the steps that build an image) into an image, the packaged program and its files, and docker run starts a container, a running copy of that image. The steps below build a small web API, run it, check that it answers, then build a second version beside the first.
You need a project directory with a Dockerfile in it, such as a small Node.js server built from node:20-alpine, whose server answers on port 3000 (the numbered network endpoint it listens on) at /health.
Building an image and starting a container from it
Build it
docker build -t my-api:1 .
[+] Building 12.4s (10/10) FINISHED
=> naming to docker.io/library/my-api:1-t my-api:1 names the image my-api with the tag 1, a label that tells one build of it from another. The final . is the build context: the directory sent to the builder, and the only place COPY can read files from. The last line of output confirms the name.
Check it exists
docker images my-api
REPOSITORY TAG IMAGE ID SIZE
my-api 1 7b1e4c9a2f30 142MBdocker images my-api lists the images with that name. The image id is the image's real identity; my-api:1 is a name pointing at it.
Run it
docker run -d --name api -p 3000:3000 my-api:1
curl -s localhost:3000/health
{"status":"ok"}-p 3000:3000 forwards port 3000 on your machine to port 3000 in the container, where the server listens. curl asks the health endpoint, and {"status":"ok"} means the server inside the container is answering.
Change something and build again
docker build -t my-api:2 .
docker run -d --name api2 -p 3001:3000 my-api:2After a change to the code, build again with a new tag, 2, and run it on another port on your machine so both versions answer at once. The first image is still there and still runnable, so going back to it is one command.
You know it worked when curl gets an answer from the container and docker images my-api lists both tags. So give every build its own tag: the old image stays available, and running a previous version is a matter of naming it.
← → move through sections and cards