Docker and docker-compose interview questions
Reviewed by Mark Dickie · Last updated
8 questions on this page you can answer and see marked on the spot. Go to the first one
Docker is a platform that packages an application and its dependencies into container images that run the same way on any host. Interviewers check whether you can write a Dockerfile that builds small, cache-friendly images, and whether you can explain how docker compose wires several containers together with networks, volumes and health checks. Expect scenario questions such as why a build is slow, why a container exits right after starting, or why one service cannot reach another. The quiz below covers those areas.
Which Docker and Compose topics come up most in interviews?
| Topic | What you should be able to explain or do |
|---|---|
| Layer caching | Each Dockerfile instruction creates a layer, so copying the lockfile and running install before copying source keeps the dependency layer cached. |
| Multi-stage builds | FROM node AS build followed by COPY --from=build ships the runtime artifact without the compiler or dev dependencies. |
depends_on limits | It controls start order only; condition: service_healthy with a healthcheck is what waits for a database to accept connections. |
| Named volumes vs bind mounts | Named volumes are managed by Docker and survive docker compose down; bind mounts map a host path and depend on that path existing. |
| Compose networking | Services on the default network reach each other by service name, so postgres:5432 works from a web container but localhost does not. |
| Restart policies | no, on-failure, always and unless-stopped differ in whether a manually stopped container comes back after a daemon restart. |
| Environment and secrets | env_file and environment inject plain values into the container, which is why build-time secrets belong in BuildKit secret mounts instead. |
What should you practise before the interview?
- Write a Dockerfile for a small web app with a multi-stage build, then change one source file and confirm which layers rebuild.
- Write a
compose.yamlwith a web service and a Postgres service, add a healthcheck, and gate the web service oncondition: service_healthy. - Break a container on purpose, for example a wrong
CMD, then usedocker logsanddocker inspectto find the exit code and the failing command. - Publish one port and reach the service from the host, then remove the port mapping and reach it from a second container by service name.
Key facts
- Tarmac has 17 Docker interview questions on this topic, 10 of them on this page, at difficulty 1–4 of 5.
- Tarmac tracked 2,941 job postings asking for Docker in October 2026.
- Roles asking for Docker advertise a median base salary of £75,000, across 1,102 job postings as of October 2026.
- Tarmac last reviewed these Docker interview questions on 2 November 2026.
At a glance
| Questions | 10 shown · 17 in the bank |
|---|---|
| Difficulty | 1–4 of 5 |
| Formats | Multiple choice, Ordering, Flashcard |
What you'll review
- compose depends on
- compose networks
Practice questions
Try one before you open the answer. Pick an option and press Check; it's marked on the spot.
In a docker-compose.yml, service web has depends_on: [db]. What does this guarantee when you run docker-compose up?#
Options
Show answer
depends_on in docker-compose guarantees only startup order: the dependency container starts before the dependent one. It does not wait for the dependency to be ready or accepting connections. To wait for readiness you need a healthcheck plus the long-form condition: service_healthy syntax.
depends_on only controls the startup and shutdown order of containers — the dependency starts first. It does not perform health or readiness checks, so web may start while db is still booting and not yet accepting connections. The claim that Compose waits until db is accepting connections on its exposed port would require a healthcheck combined with the long-form depends_on condition: service_healthy syntax. The claim that the web container starts before the db container reverses the order. The claim that the db container is built from its image before the web container image is pulled confuses build/pull ordering with runtime dependency ordering.
In a docker-compose.yml that defines two services (web and db) but includes no networks: key at the top level or under either service, how can the web service reach the db service over the network?#
Options
Show answer
When no networks: key is present, docker-compose automatically creates a single default bridge network for the project and attaches every service to it. Services can reach one another using the service name as the hostname — for example, a web service can connect to a db service at the hostname db. No explicit network configuration is needed for this to work.
When no networks: key is specified, docker-compose automatically creates a default network named <project>_default and attaches every service to it. Containers on that network can resolve each other by their service name, so web can reach db at the hostname db. The services are not isolated, not on the host network, and no explicit network definition is required for basic inter-service communication.
A docker-compose.yml defines two services, web and db, with no explicit networks: configuration. Assuming both services are started with docker compose up, how can the web service reach the db service's PostgreSQL instance listening on port 5432?#
Options
Show answer
The web service connects to db:5432 directly. Docker Compose automatically creates a default user-defined bridge network for the project and attaches every service to it, providing built-in DNS so services resolve each other by service name. No links declaration or custom network configuration is needed.
When no networks: key is specified, Docker Compose automatically creates a single user-defined bridge network for the project and attaches every service to it. On a user-defined bridge network, Compose provides embedded DNS so each service is reachable by its service name — web can connect to db:5432 directly. Connecting to localhost:5432 is wrong because containers get their own network namespaces, not the host's. Connecting to db:5432 only if links: [db] is declared is wrong because links is a legacy feature and is not required for service-name DNS on a user-defined bridge network. Connecting to the db container's IP address directly is wrong because service-name DNS is a built-in feature of user-defined bridge networks — no overlay driver or manual network definition is needed.
In a docker-compose.yml, the services form a linear dependency chain: web lists depends_on: [api], api lists depends_on: [cache], and cache lists depends_on: [db]. No condition key is specified on any dependency. Place the four services in the order Docker Compose starts them when you run docker compose up — from first started to last started.#
Put these in order
Show answer
Docker Compose starts services in dependency order: db first, then cache, then api, then web. The depends_on directive ensures each declared dependency is started before the dependent service, so a linear chain produces a strict bottom-up startup sequence.
depends_on makes Compose start each dependency before the service that declares it. cache cannot start until db is up, api cannot start until cache is up, and web cannot start until api is up. Because the chain is linear with no parallel branches, the full startup order is db → cache → api → web.
Given the following docker-compose.yml, place the three services in the order Docker Compose starts them (first to last) when you run docker compose up:#
Put these in order
Show answer
Docker Compose starts postgres first, then migrator, then app. The condition settings (service_healthy, service_completed_successfully) control readiness gates — how long Compose waits before proceeding — but the underlying startup order is still determined by the depends_on dependency chain.
The condition key changes what Compose waits for (a healthy state or successful exit) but does not change the dependency-based startup order. migrator depends on postgres, and app depends on migrator, so Compose starts postgres first. It waits until postgres is service_healthy before starting migrator. It then waits until migrator exits with service_completed_successfully before starting app. The start sequence is therefore postgres → migrator → app.
Given the following docker-compose.yml using the short syntax for depends_on:#
Options
Show answer
With the short-list depends_on syntax, Compose starts the web container as soon as the db container is created and running — it does not wait for db's healthcheck to pass. The defined healthcheck is ignored for ordering unless you switch to the long-form syntax with condition: service_healthy. This is why apps often fail to connect on startup even though depends_on is set.
The short-list form of depends_on (depends_on: [db]) only guarantees that the db container is created and started before web — it does not wait for db to be ready to accept connections. Even though a healthcheck is defined on db, the short syntax never references it for ordering. To make web wait until db is healthy, you must use the long-form syntax: depends_on: db: condition: service_healthy. Therefore the claim that the web container starts as soon as the db container has been created and is running is correct and the claim that the web container starts only after the db container's healthcheck reports a healthy status is wrong. The claim that depends_on only affects shutdown order, not startup order is wrong because depends_on does affect startup order (not just shutdown). The claim that Compose ignores the healthcheck entirely because no condition key is present on depends_on, and the web container starts before db is wrong because web does start after db, not before — the healthcheck is defined but simply not consulted for dependency ordering.
Consider the following docker-compose.yml:#
Options
Show answer
api can resolve both web and db by service name, but web cannot resolve db. Docker Compose DNS resolution is scoped per user-defined network: two containers reach each other by service name only if they share at least one network. Since api is on both frontend and backend, it sees both peers; web and db share no network and cannot resolve each other.
Docker Compose service discovery works per-network: two containers can resolve each other by service name only when they share at least one user-defined network. Here api shares frontend with web and backend with db, so api can resolve both. web and db share no network, so neither can resolve the other. When services explicitly declare custom networks, Compose does not also attach them to the implicit default network, and one container does not relay DNS for another.
Consider the following docker-compose.yml (Compose Specification v2):#
Options
Show answer
The api service never starts. When depends_on uses condition: service_healthy, Compose blocks the dependent until the dependency's healthcheck reports healthy. If db exhausts its healthcheck retries and becomes unhealthy, the condition is never satisfied, so api is not launched and Compose reports the dependency as unhealthy. There is no fallback to start the dependent anyway.
With condition: service_healthy, Compose blocks the dependent service (api) from starting until the dependency (db) reports a healthy status from its healthcheck. If db exhausts all retries and transitions to unhealthy, the service_healthy condition is never satisfied, so api is never started and Compose surfaces an error indicating the dependency is unhealthy. The claim that condition: service_healthy only affects shutdown ordering, not startup is wrong because condition: service_healthy explicitly gates startup, not just shutdown order. The claim that after the healthcheck retries are exhausted Compose starts api anyway with a warning is wrong because Compose does not fall back to starting the dependent after healthcheck failure — the condition remains unsatisfied. The claim that condition is only honored when db also declares a restart policy is wrong because no restart policy is required for condition to be honored.
In Docker Compose, what is the practical difference between declaring a service on the default network versus declaring it on a custom named network defined under the top-level networks: key, specifically with respect to DNS-based service discovery and the default network driver?#
Show answer
Both use the same default bridge driver (bridge), so isolation behavior at the driver level is identical on a single host. The key difference is service-discovery scope: the implicit default network is auto-created per project (named <project>_default) and every service not assigned elsewhere lands on it, while a custom named network lets you segment services into separate DNS discovery domains. Services only resolve each other by service name if they share at least one user-defined network. The built-in bridge (the Docker daemon's default) does NOT provide automatic DNS resolution between containers; only user-defined networks do, and Compose always creates the default network as a user-defined bridge, so DNS works there too.
A common misconception is that the default network lacks DNS. Compose's auto-created default network IS a user-defined bridge, so DNS works. The real distinction is logical segmentation: custom networks let you control which services can discover each other by name, enabling multi-tier isolation (e.g., a front-end network and a back-end network) within the same compose project.
When a Docker Compose service is attached to two custom networks (e.g., frontend and backend), how does Docker's embedded DNS resolve that service's name, and what implication does this have for a peer service that is only on the backend network trying to reach it?#
Show answer
Docker's embedded DNS resolves a container's service name on EACH network it is attached to. A service attached to both frontend and backend is independently discoverable by its service name from peers on either network. A peer that is only on the backend network can resolve and reach it by service name because they share the backend network; it does NOT need to be on frontend. However, that peer cannot discover services that are ONLY on the frontend network, since DNS resolution is scoped per-network — a container only resolves names of other containers that share at least one common user-defined network with it.
Docker DNS resolution is per-network: each user-defined network maintains its own DNS entries for member containers. A container on multiple networks is listed in each network's DNS namespace. Cross-network communication requires shared membership on at least one user-defined network — there is no transitive routing between networks via DNS.
Related interview questions
Job market
See docker salaries and hiring demand from live job postings.
The other 7 questions
This page shows 10 and marks what you pick. That's as far as a page can go. A free account opens the other 7 and keeps every answer. What you miss comes back until it's right: after a day, then at longer gaps.
Free · the whole bank · 100 marked answers per 30 days · written feedback on the paid plan