Quiz
Click "Answer" to reveal the correct answer and explanation.
Containers
Q1. A container is "an isolated process sharing the host kernel". Which Linux features provide, respectively, its isolated view of the system and its resource limits?
- A. Hypervisor and guest OS
- B. Namespaces and cgroups
- C. OverlayFS and iptables
- D. chroot and swap
Answer
B β Namespaces and cgroups.
Namespaces give the process its own view of process IDs, network interfaces, mounts and hostname β that is why your app is PID 1 inside the container and has its own IP address. cgroups limit and account for CPU, memory and I/O (docker run --memory 512m). OverlayFS provides the layered filesystem, not isolation; a hypervisor and guest OS are what a virtual machine uses, which is exactly what containers avoid.
Docker
Q2. What is the key difference between a Docker image and a container?
- A. An image runs in the foreground; a container runs in the background
- B. An image is an immutable snapshot; a container is a running instance of that image
- C. An image includes the host OS kernel; a container uses its own kernel
- D. An image is stored in the registry; a container is stored on the host filesystem
Answer
B β Image = immutable snapshot; container = running instance.
An image is built once from a Dockerfile and stored as a read-only artifact. A container is a live process created from that image β it has its own writable layer on top of the image layers. Multiple containers can run from the same image simultaneously without interfering with each other.
Q3. What is the primary benefit of a multi-stage Dockerfile build?
- A. It runs all build stages in parallel, reducing total build time
- B. It allows multiple base images to be used simultaneously in one container
- C. The final image contains only runtime artifacts, not the build toolchain β producing a smaller and more secure image
- D. It enables the same image to run on multiple operating systems
Answer
C β Smaller final image without the build toolchain.
In a Java project, the build stage needs Maven and JDK; the runtime only needs JRE and the compiled JAR. Multi-stage builds discard everything from intermediate stages β Maven, source code, test dependencies β leaving an image that is several times smaller (a JRE on Alpine instead of a full JDK plus Maven and its repository) and has a reduced attack surface.
Q4. To maximise Docker layer caching, where should COPY src ./src appear relative to dependency installation?
- A. Before β so the source is available when downloading dependencies
- B. After β a source change rebuilds only the
COPY srclayer and the ones after it, leaving the cached dependency layer intact - C. It makes no difference; Docker caches all layers equally
- D. At the very beginning, before any other instruction
Answer
B β After dependency installation.
Docker rebuilds all layers from the first changed layer onward. If COPY src comes before RUN mvn dependency:go-offline, every source code change forces a fresh dependency download. Placing the source copy after dependency installation means the slow dependency step is only re-run when pom.xml changes.
Q5. What is the difference between a named volume and a bind mount?
- A. A named volume is faster; a bind mount is more durable
- B. A named volume is managed by Docker and persists beyond container removal; a bind mount maps a specific host path into the container
- C. A bind mount requires the Docker daemon; a named volume does not
- D. They are identical β the terms are interchangeable
Answer
B β Named volume = Docker-managed and persistent; bind mount = specific host path.
Named volumes are created and managed by Docker, survive docker rm, and do not depend on the host's directory layout. Bind mounts directly expose a host directory β useful in development for hot-reload (changes on the host immediately reflect in the container) but tied to the host's filesystem layout.
Q6. Which Docker network driver allows containers on the same network to reach each other by service name?
- A.
hostβ containers share the host network stack - B.
noneβ containers are fully isolated - C.
overlayβ used for Swarm mode multi-host networking - D. A user-defined
bridgenetwork β containers attached to it resolve each other by name
Answer
D β A user-defined bridge network.
On a user-defined bridge network (docker network create β¦), Docker's embedded DNS server resolves container names to their IP addresses. The default bridge network (used when you pass no --network) does not provide name resolution β containers there can only use IP addresses. Docker Compose creates a user-defined network for each project, which is how services reach each other by service name (db, app, gateway) without any hardcoded IP addresses.
Q7. A Dockerfile contains EXPOSE 8080, and you start the container with docker run -d store/account:1.0. Why does http://localhost:8080 in your browser not answer?
- A.
EXPOSEonly works with Docker Compose - B.
EXPOSEis documentation; the port must be published with-p 8080:8080to be reachable from the host - C. The application must listen on port 80 inside a container
- D. Containers can never be reached from the host's browser
Answer
B β EXPOSE documents, -p publishes.
EXPOSE records which port the application listens on, but does not open anything on the host. docker run -p 8080:8080 (format host:container) maps a host port to the container port; in Compose the same is done with ports:. Other containers on the same network can reach port 8080 without any publishing.
Docker Compose
Q8. What does depends_on with condition: service_healthy do that plain depends_on does not?
- A. It sets a timeout after which the dependent service starts regardless
- B. It delays the dependent service until the dependency passes its
healthcheck, not just until the container process starts - C. It causes Compose to restart the dependency if it becomes unhealthy after startup
- D. It runs the dependency in a separate isolated network
Answer
B β Waits for healthcheck to pass, not just container start.
Plain depends_on only waits for the dependency container to be running (process started). The database process might be running but not yet ready to accept connections. condition: service_healthy waits until the healthcheck command inside the dependency returns exit code 0 β e.g., pg_isready -U myapp.
Q9. Why should credentials never be hard-coded in compose.yaml?
- A. Docker Compose does not support plain-text values in environment blocks
- B. Compose strips plain-text values during the build phase for security
- C. Credentials committed to version control are a security incident;
.envfiles allow per-environment secrets outside the repository - D. Hard-coded values prevent the service from reading them at runtime
Answer
C β Credentials in VCS = security incident.
Once a secret is committed to a repository β even a private one β it can be retrieved from history even after deletion. .env files are added to .gitignore and never committed, allowing each environment (dev, staging, production) to have different secrets without them ever appearing in the codebase.
Q10. What does docker compose down -v do that docker compose down does not?
- A. It stops containers more forcefully using
SIGKILLinstead ofSIGTERM - B. It rebuilds all images before stopping
- C. It also removes named volumes, permanently deleting any persisted data
- D. It removes the project network but keeps the containers stopped
Answer
C β Also removes named volumes.
docker compose down stops and removes containers and networks but leaves named volumes intact (the database data survives). Adding -v also removes named volumes β permanently deleting all persisted data. This is irreversible, so use it only when you genuinely want a clean slate.
Q11. Inside a Docker Compose network, how do services address each other?
- A. By the container's full image name and tag
- B. By the host machine's IP address and the mapped port
- C. By the service name defined in
compose.yamlβ Compose provides DNS resolution by service name - D. By the container ID assigned at runtime
Answer
C β By service name.
Compose automatically creates a network and configures DNS so that each service is reachable by its name in compose.yaml. A Spring Boot app configured with SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/store will resolve db to the PostgreSQL container's IP without any manual configuration.
Q12. Which two mechanisms control startup ordering in Docker Compose? Select the most complete answer.
- A.
restart: alwaysretries until all dependencies are up;priorityfield sets integer startup order - B.
depends_onfor basic ordering;healthcheckwithcondition: service_healthyfor readiness-gated ordering - C.
order:field involumes:block;links:for legacy dependency declaration - D. Environment variable injection order; port mapping order in
ports:block
Answer
B β depends_on + healthcheck with condition: service_healthy.
depends_on guarantees that container B starts after container A is running. Adding condition: service_healthy guarantees that B waits until A passes its healthcheck and is actually ready. The combination is essential for databases, which take several seconds to initialise after the process starts.
Q13. The account service works when started from the IDE with spring.datasource.url=jdbc:postgresql://localhost:5432/store. Packaged as a container in the same compose.yaml as the db service, it fails with Connection refused. What is the fix?
- A. Publish port 5432 of
dbwithports: - 5432:5432 - B. Use
network_mode: hostfor every service - C. Point the URL to the service name:
jdbc:postgresql://db:5432/store, passed as an environment variable - D. Add
depends_on: - dbto the account service
Answer
C β Use the service name.
Inside a container, localhost is the container itself β there is no PostgreSQL there. Compose's DNS resolves the service name db to the database container, which listens on its container port 5432. Publishing the port (A) only helps clients on the host; depends_on (D) orders the start but does not change the address. Passing the URL through an environment variable (e.g. SPRING_DATASOURCE_URL) keeps the same image working in the IDE, in Compose and in Kubernetes.
Q14. A project has a .env file with DB_PASSWORD=devpass next to compose.yaml. Which statement is correct?
- A. Every variable in
.envis automatically injected into every container - B.
.envis used to fill${DB_PASSWORD}placeholders incompose.yaml; to inject a whole file into a container you useenv_file: - C.
.envis ignored unless you pass--env-file .envtodocker compose up - D. Values in
.envalways override variables exported in your shell
Answer
B β .env is for interpolation; env_file: injects into a container.
Compose reads .env from the project directory automatically and uses it to substitute ${...} in compose.yaml β a container only receives a value if the file maps it, for example POSTGRES_PASSWORD: ${DB_PASSWORD}. To pass every KEY=value of a file to a container, use env_file: on the service. Variables already set in the shell take precedence over .env (D is false).