Docker basics: images, containers, Dockerfile

Updated October 9, 2026

Docker packages an application and everything it needs into an image, and runs that image as an isolated process called a container. An image is the immutable template; a container is a running instance of it. Anything that must survive the container goes in a volume, and anything a browser or another host must reach has to be published with -p. Most Docker exam questions come down to one of those three sentences.

From Dockerfile to running app, in five steps

The path below is the sequence exams ask you to read. Each step names the command and what it produces.

  1. Write a Dockerfile. A text file of build instructions, read top to bottom.
  2. Build an image. docker build -t myapp:1.0 . reads the Dockerfile and the files in the current directory (the build context) and produces an image.
  3. Store it in a registry. docker push sends the image to a registry such as Docker Hub or Azure Container Registry, so other machines can pull it. See AI-200 containers for registry tasks.
  4. Run a container. docker run -d -p 8080:5000 myapp:1.0 starts a container from the image.
  5. Inspect and stop it. docker ps lists running containers, docker logs shows output, docker stop ends the container. docker images lists local images.

Running docker run twice from the same image gives two independent containers. Deleting a container never deletes the image.

A small Dockerfile, line by line

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
USER 1000
CMD ["python", "app.py"]
LineWhat it doesTime
FROMChooses the base image everything else is added on top ofBuild
WORKDIRSets the working directory for the instructions that followBuild and run
COPYCopies files from the build context into the imageBuild
RUNExecutes a command and adds a new layerBuild
EXPOSEDocuments the port the application usesMetadata only
USERSets the user for later instructions and for the container’s processBuild and run
CMDThe default command when a container starts; if several exist only the last countsRun

RUN happens when you build; CMD happens when you run. Exam stems love this: installing a package in CMD means it is installed on every start, not once.

Four ideas behind the commands

Images are layered and immutable. Each layer records changes to the filesystem, and a finished image cannot be edited. To change it you build a new one, which is why a fix is “rebuild and redeploy”, never “log in and patch”.

Build order matters for speed. Docker’s build cache is layer based: when one layer changes, every layer after it is rebuilt. In the example, requirements.txt is copied and installed before the rest of the source. Editing app.py then reuses the cached dependency layer. Putting COPY . . first would reinstall dependencies on every code change.

The container filesystem is ephemeral. Files written inside a container disappear when the container is deleted. A named volume (docker run -v data:/var/lib/app ...) keeps files after the container is gone and can be attached to a new container or shared between containers. Databases, uploads and logs you need to keep belong in volumes.

EXPOSE does not publish. Docker’s own documentation says exposed ports are not published by default; EXPOSE documents the port. Publishing creates the forwarding rule: -p HOST_PORT:CONTAINER_PORT, so -p 8080:5000 makes host port 8080 reach container port 5000. The host port is on the left. -P publishes every exposed port to an ephemeral host port that Docker picks.

Container, VM or orchestrator

A container shares the host’s kernel and starts in moments, which is why it is small and portable. A virtual machine carries its own operating system. Containers solve “works on my machine” because the dependencies travel inside the image. A single docker run does not restart failed services across several machines or roll out new versions gradually; that is the job of an orchestrator, covered in Kubernetes and AKS basics. For the Azure choice between Container Instances, Container Apps and AKS, see the Azure compute selection guide.

Which exams test this

ExamHow it appearsGuide on this site
200-901Application Deployment and Security (15%): interpret the contents of a Dockerfile (4.6), use Docker images in a local developer environment (4.7) and describe containers as a deployment type next to virtual machines and bare metal (4.3)Deployment and security
AI-200Develop containerized solutions on Azure (20–25%): build, store, version and manage images in Azure Container Registry, build and run images with ACR Tasks, and deploy containers to App Service and Container AppsContainerized solutions
AZ-104Minor: Deploy and manage Azure compute resources (20–25%) covers creating a Container Registry and provisioning containers with Container Instances and Container Apps. Docker commands are not named; the image and container vocabulary is assumedCompute resources
AZ-400Minor: Design and implement build and release pipelines (50–55%) includes deploying applications by using containers, and Develop a security and compliance plan (10–15%) includes scanning container imagesSecurity and compliance
MLA-C02Deployment and Orchestration of ML and AI Workflows (24%): build and maintain containers for ML and AI workloads (3.2.3)MLA-C02 deployment and orchestration

Only the 200-901 outline names Dockerfiles and Docker images directly, and MLA-C02 asks you to build containers for ML workloads. The Azure exams test the services that build, store and run images, so the image and container vocabulary above is assumed.

How exam questions are built around it

  • “Reachable on host port 8080” means -p 8080:5000, host first. A trap answer relies on EXPOSE, which only documents.
  • “Data must survive the container being replaced” means a volume, not a bigger image and not a file written in the container.
  • “Build is slow after every code change” means reorder the Dockerfile so rarely changing steps (dependency install) come before frequently changing ones (source copy).
  • “Change a running application” means build a new image and start a new container, because images are immutable.
  • “Runs at build time” versus “runs at start” separates RUN from CMD.
  • Secrets: a value written into an image layer stays in the image history. Pass secrets at run time or pull them from a vault, as covered in managed identities vs service principals.

Practice questions

Question 1. A Dockerfile for a web service contains EXPOSE 3000 and the image is named shop. An engineer runs docker run -d shop, and the service cannot be reached from a browser on the Docker host at port 8080. Which command makes it reachable at that address?

  • A. docker run -d -p 3000:8080 shop
  • B. docker build -p 8080:3000 shop
  • C. docker run -d -p 8080:3000 shop
  • D. docker run -d shop, because EXPOSE already publishes port 3000
Show answer

Answer: C

Publishing uses -p HOST_PORT:CONTAINER_PORT, so 8080:3000 forwards host port 8080 to container port 3000. EXPOSE only documents the port and does not publish it. Reversing the numbers forwards host port 3000 to container port 8080. docker build creates an image and does not start a container.

Question 2. A container runs a database and writes its files inside the container filesystem. When the team replaces the container with one built from an updated image, all the data is gone. What should the team do?

  • A. Mount a named volume at the database data directory
  • B. Rebuild the image more often so it contains the latest data
  • C. Edit the existing image to include the data files
  • D. Choose a larger base image
Show answer

Answer: A

The container filesystem is ephemeral and disappears with the container. A named volume mounted at the database data path holds the files outside the container, so a new container can attach the same volume. Rebuilding the image more often does not preserve runtime data, and images are immutable so data cannot be written into them. A larger base image has no effect on persistence.

Go deeper