100 Docker practice problems with solutions

Want to move from Docker theory to truly confident hands-on skills? This post gives you 100 Docker practice problems with clear, step-by-step solutions. You’ll work through containers, images, volumes, networks, Dockerfiles, and Docker Compose.

Each problem is written in simple language — try it yourself, then check the answer. Perfect for beginners and interview prep. Pick a challenge and start building real Docker mastery today.

Try it: 100 Python practice problems with solutions

1. Pull the official Ubuntu 20.04 image from Docker Hub.

bash

docker pull ubuntu:20.04

2. Run an interactive container using the Ubuntu image and start a bash shell.

bash

docker run -it ubuntu:20.04 bash

3. Run a container in detached mode that continuously prints “Hello Docker” every 5 seconds using a simple script.

bash

docker run -d ubuntu:20.04 sh -c "while true; do echo Hello Docker; sleep 5; done"

4. List all running containers, then list all containers (including stopped ones).

bash

docker ps
docker ps -a

5. Stop a container with a specific name or ID, then remove it.

bash

docker stop <container_id>
docker rm <container_id>

6. Remove all stopped containers at once.

bash

docker container prune

7. Run an Nginx web server container named “web” mapping port 8080 of the host to port 80 of the container.

bash

docker run -d --name web -p 8080:80 nginx

8. Execute a command inside a running container (e.g., list files in /usr/share/nginx/html).

bash

docker exec web ls /usr/share/nginx/html

9. Copy a local index.html file into the running Nginx container’s html directory.

bash

docker cp index.html web:/usr/share/nginx/html/index.html

10. Inspect the IP address of a running container.

bash

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

11. Create a Dockerfile that uses Python 3.9 base image and installs flask, then sets the working directory to /app and copies app.py into it.

dockerfile

FROM python:3.9
WORKDIR /app
COPY app.py .
RUN pip install flask
CMD ["python", "app.py"]

12. Build an image from the Dockerfile in the current directory and tag it as “my-flask-app”.

bash

docker build -t my-flask-app .

13. Run a container from the “my-flask-app” image, mapping host port 5000 to container port 5000.

bash

docker run -d -p 5000:5000 my-flask-app

14. View the logs of a running container.

bash

docker logs <container_id>

15. Follow the logs of a container in real time.

bash

docker logs -f <container_id>

16. Create a volume named “data-volume” and mount it to a container’s /data directory.

bash

docker volume create data-volume
docker run -v data-volume:/data ubuntu touch /data/test.txt

17. Mount a host directory (e.g., ./host-data) into a container at /container-data.

bash

docker run -v $(pwd)/host-data:/container-data ubuntu ls /container-data

18. Use the --mount flag to mount a named volume into a container.

bash

docker run --mount source=data-volume,target=/app/data ubuntu echo "Mounted"

19. Create a network named “my-net” and run two containers (alpine) attached to that network; verify they can ping each other by container name.

bash

docker network create my-net
docker run -d --name c1 --network my-net alpine sleep 3600
docker run -it --name c2 --network my-net alpine ping c1

20. Inspect the network “my-net” to see which containers are connected.

bash

docker network inspect my-net

21. Build a Docker image with a multi‑stage build: first stage compiles a Go program, second stage copies the binary from the first stage and sets the entrypoint.

dockerfile

FROM golang:1.20 AS builder
WORKDIR /src
COPY hello.go .
RUN go build -o hello hello.go

FROM alpine:latest
COPY --from=builder /src/hello /hello
ENTRYPOINT ["/hello"]

22. Tag a local image “my-app:latest” with a new tag “my-app:v1.0” and push it to a private registry (e.g., localhost:5000).

bash

docker tag my-app:latest my-app:v1.0
docker tag my-app:v1.0 localhost:5000/my-app:v1.0
docker push localhost:5000/my-app:v1.0

23. Use a .dockerignore file to exclude node_modules and .git from the build context.

dockerignore

node_modules
.git
*.md

24. Set environment variables inside a container using -e (e.g., MESSAGE=”Hello”).

bash

docker run -e MESSAGE="Hello" alpine env | grep MESSAGE

25. Use an environment file (.env) with --env-file to pass multiple variables.

bash

echo "USER=john" > .env
echo "PASS=secret" >> .env
docker run --env-file .env alpine env

26. Limit the memory of a container to 256MB and CPU share to 0.5.

bash

docker run -d --memory="256m" --cpus="0.5" nginx

27. Restart a container automatically unless it is explicitly stopped (policy: unless-stopped).

bash

docker run -d --restart unless-stopped nginx

28. Use docker stats to monitor real-time resource usage of containers.

bash

docker stats

29. Save an image to a tar file and then load it back.

bash

docker save -o my-image.tar my-image:latest
docker load -i my-image.tar

30. Export a container’s filesystem to a tar file and then import it as an image.

bash

docker export <container_id> > container.tar
docker import container.tar my-new-image:imported

31. Run a MySQL container with root password “root”, create a volume for data persistence, and expose port 3306.

bash

docker run -d --name mysql-db -e MYSQL_ROOT_PASSWORD=root -v mysql-data:/var/lib/mysql -p 3306:3306 mysql:8

32. Connect to the MySQL container using docker exec and run a SQL query.

bash

docker exec -it mysql-db mysql -uroot -proot -e "SHOW DATABASES;"

33. Create a docker-compose.yml that runs a WordPress container linked to a MySQL container with a shared network.

yaml

version: '3'
services:
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    volumes:
      - db-data:/var/lib/mysql
  wordpress:
    image: wordpress:latest
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: root
    depends_on:
      - db
volumes:
  db-data:

34. Bring up the docker-compose services in detached mode.

bash

docker-compose up -d

35. View logs of a specific service in docker-compose.

bash

docker-compose logs wordpress

36. Scale the WordPress service to 3 replicas (in docker-compose).

bash

docker-compose up -d --scale wordpress=3

37. Execute a one-off command inside a docker-compose service (e.g., wp command).

bash

docker-compose run wordpress wp --info

38. Remove all containers, networks, volumes, and images created by docker-compose.

bash

docker-compose down -v --rmi all

39. Build a Docker image with a build argument VERSION=1.2.3 and use it inside the Dockerfile.

dockerfile

ARG VERSION
FROM alpine:${VERSION}

bash

docker build --build-arg VERSION=3.15 -t alpine-custom .

40. Use docker commit to create a new image from changed container (not recommended, but practice).

bash

docker run -it ubuntu bash
# make changes (install package, create file)
# exit
docker commit <container_id> my-modified-ubuntu

41. Run a container that automatically removes itself when stopped (add --rm flag).

bash

docker run --rm ubuntu echo "I will be removed"

42. Create a Docker network with a specific subnet (e.g., 172.20.0.0/16) and run a container with a static IP.

bash

docker network create --subnet=172.20.0.0/16 my-net
docker run --net my-net --ip 172.20.0.10 alpine ip addr show

43. Use docker system prune to remove unused data (stopped containers, dangling images, unused networks).

bash

docker system prune -a -f

44. Build a Docker image that uses a non‑root user for security.

dockerfile

FROM alpine
RUN adduser -D appuser
USER appuser
WORKDIR /home/appuser
COPY script.sh .
ENTRYPOINT ["./script.sh"]

45. Run a container with read‑only root filesystem (except mounted volumes).

bash

docker run --read-only -v /tmp:/tmp alpine touch /tmp/test.txt

46. Pass a secret (like API key) using Docker secrets in Swarm mode (initialise swarm first).

bash

docker swarm init
echo "my-api-key" | docker secret create api_key -
docker service create --secret api_key --name test alpine env

47. Create a Docker Swarm service with 5 replicas of the nginx image.

bash

docker service create --name nginx-svc --replicas 5 -p 80:80 nginx

48. Update the Swarm service to use a different image version and perform a rolling update.

bash

docker service update --image nginx:alpine nginx-svc

49. Drain a node in Docker Swarm to reschedule its tasks.

bash

docker node update --availability drain <node-id>

50. Inspect a Swarm service to see its details.

bash

docker service inspect --pretty nginx-svc

51. Create a Dockerfile that installs Node.js dependencies and runs a Node.js app with production environment.

dockerfile

FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
ENV NODE_ENV=production
CMD ["node", "server.js"]

Try it: 100 Go (Golang) practice problems with solutions

52. Use docker logs with --since to show logs from the last 1 hour.

bash

docker logs --since 1h web

53. Use docker cp to copy a file from a container to the host.

bash

docker cp web:/usr/share/nginx/html/index.html ./index.html

54. Set the working directory and user in a Dockerfile to run an application securely.

dockerfile

FROM node:18
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /home/appuser
COPY . .
RUN chown -R appuser:appuser /home/appuser
USER appuser
CMD ["node", "index.js"]

55. Use HEALTHCHECK in a Dockerfile to check the health of a web service.

dockerfile

FROM nginx
HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD curl --fail http://localhost/ || exit 1

56. Inspect the health status of a running container.

bash

docker inspect --format='{{json .State.Health}}' web

57. Create a Docker bridge network and connect an existing container to it.

bash

docker network create my-bridge
docker network connect my-bridge existing-container

58. Disconnect a container from a network.

bash

docker network disconnect my-bridge existing-container

59. Limit the rate at which a container writes to disk using --device-write-bps.

bash

docker run --device-write-bps /dev/sda:1mb ubuntu dd if=/dev/zero of=test bs=1M count=100

60. Run a container with a custom hostname.

bash

docker run --hostname myhost ubuntu hostname

61. Set the timezone inside a container using environment variable TZ.

bash

docker run -e TZ=America/New_York ubuntu date

62. Use docker top to view running processes inside a container.

bash

docker top web

63. Use docker diff to see changes made to container’s filesystem since it started.

bash

docker diff web

64. Pause and unpause a container.

bash

docker pause web
docker unpause web

65. Build a Docker image with --no-cache to ignore cache.

bash

docker build --no-cache -t fresh-image .

66. Use docker image history to see layers of an image.

bash

docker image history ubuntu:latest

67. Tag an image with multiple tags and push all of them.

bash

docker tag my-app my-registry/my-app:v1
docker tag my-app my-registry/my-app:latest
docker push my-registry/my-app --all-tags

68. Configure Docker to use a proxy for pulling images (set environment variables).

bash

mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080"
Environment="HTTPS_PROXY=https://proxy.example.com:8080"
EOF
systemctl daemon-reload && systemctl restart docker

69. Run a container with a custom dns server (e.g., 8.8.8.8).

bash

docker run --dns 8.8.8.8 alpine cat /etc/resolv.conf

70. Create a docker-compose override file to use different environment variables in production.

yaml

# docker-compose.override.yml (for development)

bash

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

71. Use docker exec to run an interactive shell inside a container as a specific user.

bash

docker exec -it --user appuser web bash

72. Build a Docker image with a label (e.g., version=1.0, maintainer=user@example.com).

dockerfile

LABEL version=1.0 maintainer="user@example.com"

73. Filter containers by label using docker ps --filter.

bash

docker run -d --label env=prod nginx
docker ps --filter "label=env=prod"

74. Use docker system df to see disk usage of images, containers, and volumes.

bash

docker system df

75. Set the default ulimit for a container (e.g., nofile=1024:2048).

bash

docker run --ulimit nofile=1024:2048 ubuntu ulimit -n

76. Use docker run with --add-host to add a custom host entry to /etc/hosts.

bash

docker run --add-host=myhost:192.168.1.100 alpine cat /etc/hosts

77. Create a Docker image that uses an entrypoint script which accepts arguments.

dockerfile

FROM alpine
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["default-arg"]

78. Run a container and override the default command (e.g., bash instead of what’s in CMD).

bash

docker run -it ubuntu bash

79. Use docker events to monitor real‑time events from the daemon.

bash

docker events

80. Create a Docker volume with a driver option (e.g., local with type=nfs).

bash

docker volume create --driver local --opt type=nfs --opt o=addr=192.168.1.100,rw --opt device=:/exported/path nfs-volume

81. Run a container in the host network namespace (use host networking).

bash

docker run --network host nginx

82. Enable live restore in Docker daemon so containers keep running when daemon stops.

json

# /etc/docker/daemon.json
{
  "live-restore": true
}

83. Use docker update to change resource limits of a running container.

bash

docker update --memory 512m --cpus 1 web

84. Save a container’s logs to a file using docker logs redirection.

bash

docker logs web > web.log 2>&1

85. Use docker run with --init to run an init process inside container (to reap zombies).

bash

docker run --init ubuntu sleep 100

86. Run a container that publishes all exposed ports to random host ports.

bash

docker run -P nginx
docker port <container-id>

87. Create a Docker network with IPAM configuration (custom subnet and gateway).

bash

docker network create --ipam-driver default --subnet=10.10.0.0/16 --gateway=10.10.0.1 my-ipam-net

88. Use docker search to find official images for Postgres.

bash

docker search --filter "is-official=true" postgres

89. Build a Docker image with a specific target stage in a multi‑stage Dockerfile.

bash

docker build --target builder -t my-builder .

90. Use a tmpfs mount for a container’s /tmp to improve performance.

bash

docker run --tmpfs /tmp ubuntu mount | grep tmpfs

91. Run a container and set its container name explicitly to “my-app”.

bash

docker run --name my-app nginx

92. Inspect the number of times a container has been restarted (restart policy).

bash

docker inspect -f '{{.RestartCount}}' web

93. Prune unused Docker volumes.

bash

docker volume prune

94. Use docker stats --no-stream to get a one‑shot snapshot of stats.

bash

docker stats --no-stream

Try it: 100 .NET practice problems with solutions

95. Create a Docker secret from a file and use it in a service.

bash

echo "password" > secret.txt
docker secret create db_pass secret.txt
docker service create --secret db_pass --name db mysql:8

96. Use docker stack deploy to deploy a docker-compose.yml file to Swarm.

bash

docker stack deploy -c docker-compose.yml mystack

97. Remove a Docker stack.

bash

docker stack rm mystack

98. Configure Docker daemon to use a different data directory (e.g., /data/docker).

json

// /etc/docker/daemon.json
{
  "data-root": "/data/docker"
}

99. Run a container with --privileged to give extended privileges (dangerous, only for learning).

bash

docker run --privileged ubuntu docker ps  # only if docker-in-docker

100. Build an image that runs a static binary from scratch (empty base image).

dockerfile

FROM scratch
COPY hello /
CMD ["/hello"]

Final Thought

And that’s a wrap — 100 Docker problems, and you absolutely crushed them!

Give yourself a happy little cheer, a victory dance, or at least a big, goofy grin. You didn’t just read about containers — you spun them up, networked them, built images, wrote Dockerfiles, and orchestrated like a joyful conductor of tiny, portable penguins. Every problem added a splash of confidence to your DevOps toolbox.

Docker can feel scary until you practice. Now? It’s your cheerful companion that says, “It works on my machine… and yours too!” That’s a superpower wrapped in a smiling whale.

Bookmark this page for rainy days. Revisit a problem just for fun. Share the cheer with a teammate who’s container-curious. You’re now someone who can ship code anywhere with a wink and a docker run. Sending you a virtual high-five and all the happy deployment energy in the world. Keep sailing, you container captain, you!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top