5 exercises — Master the English vocabulary of Docker Compose: file structure, service dependencies, secrets management, volume types, and override patterns.
0 / 29 completed
1 / 29
A developer asks: "What are the three primary top-level sections in a docker-compose.yml file, and what does each define?"
Which answer is correct?
The three primary top-level keys are services, networks, and volumes.
A docker-compose.yml (or compose.yaml) has this structure:
• services — the core section; each named entry defines a container: its image or build context, environment variables, port mappings, volume mounts, networks, restart policy, health check, and service dependencies
• networks — defines custom Docker networks; if omitted, Compose creates a default bridge network named <project>_default
• volumes — defines named volumes; if a service references a named volume that isn't listed here, Compose creates it automatically
Optional top-level keys include configs and secrets — used primarily in Docker Swarm mode for configuration and credential management. The only mandatory section is services.
Key vocabulary:
• compose.yaml — the Compose file; defines the full multi-container application
• service — a named container workload definition in the Compose file
• named volume — a Docker-managed persistent storage volume defined in the top-level volumes section
• top-level key — a root-level section in the Compose YAML (services, networks, volumes, configs, secrets)
2 / 29
A Compose stack uses depends_on: [database] for the API service. After deploying, the API crashes immediately with a "connection refused" error — the database container is running but PostgreSQL hasn't finished its initialisation yet.
What change correctly fixes this race condition?
depends_on with condition: service_healthy waits for the application to be ready, not just the container.
depends_on: [database] (or condition: service_started) only ensures the database container has been started — it doesn't wait for PostgreSQL to be ready to accept connections. This is a classic race condition.
The fix requires two things:
1. A HEALTHCHECK in the database service (or image) — e.g., pg_isready -U postgres
2. condition: service_healthy in the dependent service's depends_on block
Compose will poll the health check until it reports healthy before starting the API. Option B (sleep) is fragile — the right sleep duration varies by environment and will eventually break. links (D) is deprecated in Compose v2.
Key vocabulary:
• depends_on — a Compose directive declaring service startup order dependencies
• condition: service_healthy — waits for the dependency's health check to pass before starting the dependent service
• service_started — the default condition; container has started but the application may not be ready
• race condition — a timing bug where the outcome depends on relative startup speeds
• health check — a command Compose/Docker runs to determine if a service is ready to accept traffic
3 / 29
A code review comment reads: "Don't put the database password inline in the environment: block — it will appear in docker compose config output and could end up in git history. Use env_file: with a .env file that's in .gitignore."
What is the recommended practice for managing secrets in Docker Compose development environments?
env_file + .gitignore is the standard dev-environment secret practice.
Inline credentials in the environment: block are exposed in:
• docker compose config (prints the resolved YAML)
• docker inspect <container>
• Any git commit that includes the Compose file
The pattern: create a .env file with DB_PASSWORD=supersecret and reference it with env_file: - .env. The .env file is added to .gitignore so it is never committed. Developers copy a .env.example with placeholder values from the repo.
For production: Compose supports a secrets: top-level section backed by Docker Swarm encrypted secrets, AWS Secrets Manager, or Vault. Base64 encoding (C) provides zero security — it is trivially reversible and easily detected by secret scanning tools like truffleHog or gitleaks.
Key vocabulary:
• env_file — a Compose directive pointing to a file of KEY=VALUE pairs loaded as environment variables
• .env file — a local environment config file; by convention excluded from version control
• .gitignore — a git config file listing paths that should not be tracked in version control
• docker compose secrets — an encrypted secret mechanism for production deployments
• secret scanning — automated detection of accidentally committed credentials in code repositories
4 / 29
A teammate asks: "Should I use a named volume or a bind mount for the PostgreSQL data directory in our Compose stack? And which is better for mounting local source code during development?"
Which answer correctly distinguishes the two?
Named volumes are for persistent data; bind mounts are for development workflows requiring host-path access.
Named volume (volumes: db_data:/var/lib/postgresql/data):
• Docker manages the storage location on the host
• Data persists independently of the container lifecycle
• Not tied to a specific host path — portable across machines
• Supports volume drivers (NFS, EBS, Ceph) for backup and migration
• Best for: database data, file uploads, any stateful application data
Bind mount (volumes: ./src:/app/src):
• Maps a specific host directory into the container
• Changes on the host are immediately visible inside the container — enables live-reload / hot-reload dev workflows
• Host-path-dependent — the same Compose file works differently on different machines if paths vary
• Best for: source code during development, configuration overrides
Key vocabulary:
• named volume — Docker-managed storage referenced by name; data persists beyond the container lifecycle
• bind mount — maps a specific host filesystem path into the container
• volume driver — a plugin implementing the storage backend (NFS, AWS EBS, Ceph)
• persistence — data surviving container restarts and removals; provided by named volumes
• live reload — seeing code changes immediately without rebuilding; enabled by bind-mounting source code
5 / 29
A developer notices that running docker compose up in a project directory automatically merges settings from both docker-compose.yml and docker-compose.override.yml — even though only one file was specified in mind. They ask: "Why does Compose use the override file automatically?"
The override file is a built-in Compose convention — automatically merged with the base file on docker compose up.
Docker Compose has first-class support for the override pattern:
• docker-compose.yml (or compose.yaml) — base configuration, usually production-aligned
• docker-compose.override.yml — automatically merged when present; holds dev-only differences
Common dev overrides include: bind-mounting source code for live reload, exposing additional debug ports, enabling watch mode, overriding the startup command, or injecting debug environment variables.
For CI or staging, you can explicitly combine specific files: docker compose -f docker-compose.yml -f docker-compose.ci.yml up — the -f flag controls which files are merged and in what order. There is no --no-merge flag; use -f to specify exactly which files to use.
Key vocabulary:
• compose override file — docker-compose.override.yml; automatically merged with the base file by Compose
• merge — Compose's process of combining settings from multiple files; arrays are appended, scalar values override
• -f flag — the docker compose -f option explicitly specifying which Compose files to use and their merge order
• dev vs prod config — pattern of keeping prod settings in the base file and dev differences in the override
• compose watch — a Compose v2.22+ feature for live code sync without bind mounts
6 / 29
During a code review of the `docker-compose.yml` file for a new microservice, Sarah points out: 'Hey, we're using the `ports` directive to expose port 8080 on the service directly to the host machine. This isn't ideal; it exposes our internal application directly and makes it vulnerable to external attacks. Shouldn't we be using an exposed proxy instead?' Which of the following best describes Sarah's concern and the recommended approach?
Incorrectly exposing ports can create security vulnerabilities.
Sarah correctly identifies that directly exposing ports creates a security vulnerability. While a reverse proxy *is* a valid solution for mitigating this risk by acting as an intermediary, simply stating it doesn't fully explain the problem or the best practice. Option A is too strong and suggests immediate action without considering other factors. Option D incorrectly implies the `ports` directive is always acceptable. Option B misses the key point of why direct exposure is dangerous. The correct answer highlights that a reverse proxy is a suitable solution, but also encourages further review – demonstrating a more complete understanding of the situation.
7 / 29
During a standup meeting, Mark says: "I've been struggling to get my new service to connect to the database. I'm using Docker Compose and it keeps failing with a DNS resolution error." He suspects the issue might be related to how services within the stack communicate. Which of the following is the MOST likely root cause, given this scenario?
Mark's problem points to DNS resolution failing within the Docker Compose network. Containers within the same network are typically joined through a custom bridge network created by Docker Compose. If the hostname specified in the API service's configuration doesn't resolve correctly within this network, it will fail to connect. Options B and C represent potential networking issues but don't directly address the core DNS resolution problem; option D is less likely given the scenario description.
8 / 29
Liam is reviewing a Docker Compose file for a new web application. The `services` section defines a service named 'web' that uses an image called 'nginx:latest'. The configuration includes the following line: ports: - "80:80". A senior developer, Maya, comments: 'Liam, I'm not entirely comfortable with exposing port 80 directly to the host machine like this. While it works for simple demos, it significantly increases our attack surface. We should be using a reverse proxy – something like Nginx itself – to handle incoming requests and forward them to the 'web' service on its internal port.' What is Maya's primary concern regarding this configuration?
Maya's concern centers on the direct exposure of port 80. This creates a significant security vulnerability by allowing external actors to directly access the 'web' service. By using a reverse proxy (like another Nginx instance), incoming requests are handled and filtered before reaching the application, reducing the attack surface considerably. The primary issue isn't the image itself or performance, but rather the direct exposure of the web service.
9 / 29
During a code review of the `docker-compose.yml` file for a new microservice, Sarah points out: 'Hey, we're using the `ports` directive to expose port 8080 on the service directly to the host machine. This isn't ideal; it exposes our internal application directly and makes it vulnerable to external attacks. Shouldn't we be using an exposed proxy instead?' Which of the following best describes Sarah's concern and the recommended approach?
Incorrectly exposing ports can create security vulnerabilities.
Sarah correctly identifies that directly exposing ports creates a security vulnerability. While a reverse proxy *is* a valid solution for mitigating this risk by acting as an intermediary, simply stating it doesn't fully explain the problem or the best practice. Option A is too strong and suggests immediate action without considering other factors. Option D incorrectly implies the `ports` directive is always acceptable. Option B misses the key point of why direct exposure is dangerous. The correct answer highlights that a reverse proxy is a suitable solution, but also encourages further review – demonstrating a more complete understanding of the situation.
10 / 29
During a standup meeting, Mark says: "I've been struggling to get my new service to connect to the database. I'm using Docker Compose and it keeps failing with a DNS resolution error." He suspects the issue might be related to how services within the stack communicate. Which of the following is the MOST likely root cause, given this scenario?
Mark's problem points to DNS resolution failing within the Docker Compose network. Containers within the same network are typically joined through a custom bridge network created by Docker Compose. If the hostname specified in the API service's configuration doesn't resolve correctly within this network, it will fail to connect. Options B and C represent potential networking issues but don't directly address the core DNS resolution problem; option D is less likely given the scenario description.
11 / 29
Liam is reviewing a Docker Compose file for a new web application. The `services` section defines a service named 'web' that uses an image called 'nginx:latest'. The configuration includes the following line: ports: - "80:80". A senior developer, Maya, comments: 'Liam, I'm not entirely comfortable with exposing port 80 directly to the host machine like this. While it works for simple demos, it significantly increases our attack surface. We should be using a reverse proxy – something like Nginx itself – to handle incoming requests and forward them to the 'web' service on its internal port.' What is Maya's primary concern regarding this configuration?
Maya's concern centers on the direct exposure of port 80. This creates a significant security vulnerability by allowing external actors to directly access the 'web' service. By using a reverse proxy (like another Nginx instance), incoming requests are handled and filtered before reaching the application, reducing the attack surface considerably. The primary issue isn't the image itself or performance, but rather the direct exposure of the web service.
12 / 29
During a code review of the `docker-compose.yml` file for a new microservice, Sarah points out: 'Hey, we're using the `ports` directive to expose port 8080 on the service directly to the host machine. This isn't ideal; it exposes our internal application directly and makes it vulnerable to external attacks. Shouldn't we be using an exposed proxy instead?' Which of the following best describes Sarah's concern and the recommended approach?
Incorrectly exposing ports can create security vulnerabilities.
Sarah correctly identifies that directly exposing ports creates a security vulnerability. While a reverse proxy *is* a valid solution for mitigating this risk by acting as an intermediary, simply stating it doesn't fully explain the problem or the best practice. Option A is too strong and suggests immediate action without considering other factors. Option D incorrectly implies the `ports` directive is always acceptable. Option B misses the key point of why direct exposure is dangerous. The correct answer highlights that a reverse proxy is a suitable solution, but also encourages further review – demonstrating a more complete understanding of the situation.
13 / 29
During a standup meeting, Mark says: "I've been struggling to get my new service to connect to the database. I'm using Docker Compose and it keeps failing with a DNS resolution error." He suspects the issue might be related to how services within the stack communicate. Which of the following is the MOST likely root cause, given this scenario?
Mark's problem points to DNS resolution failing within the Docker Compose network. Containers within the same network are typically joined through a custom bridge network created by Docker Compose. If the hostname specified in the API service's configuration doesn't resolve correctly within this network, it will fail to connect. Options B and C represent potential networking issues but don't directly address the core DNS resolution problem; option D is less likely given the scenario description.
14 / 29
Liam is reviewing a Docker Compose file for a new web application. The `services` section defines a service named 'web' that uses an image called 'nginx:latest'. The configuration includes the following line: ports: - "80:80". A senior developer, Maya, comments: 'Liam, I'm not entirely comfortable with exposing port 80 directly to the host machine like this. While it works for simple demos, it significantly increases our attack surface. We should be using a reverse proxy – something like Nginx itself – to handle incoming requests and forward them to the 'web' service on its internal port.' What is Maya's primary concern regarding this configuration?
Maya's concern centers on the direct exposure of port 80. This creates a significant security vulnerability by allowing external actors to directly access the 'web' service. By using a reverse proxy (like another Nginx instance), incoming requests are handled and filtered before reaching the application, reducing the attack surface considerably. The primary issue isn't the image itself or performance, but rather the direct exposure of the web service.
15 / 29
During a code review of the `docker-compose.yml` file for a new microservice, Sarah points out: 'Hey, we're using the `ports` directive to expose port 8080 on the service directly to the host machine. This isn't ideal; it exposes our internal application directly and makes it vulnerable to external attacks. Shouldn't we be using an exposed proxy instead?' Which of the following best describes Sarah's concern and the recommended approach?
Incorrectly exposing ports can create security vulnerabilities.
Sarah correctly identifies that directly exposing ports creates a security vulnerability. While a reverse proxy *is* a valid solution for mitigating this risk by acting as an intermediary, simply stating it doesn't fully explain the problem or the best practice. Option A is too strong and suggests immediate action without considering other factors. Option D incorrectly implies the `ports` directive is always acceptable. Option B misses the key point of why direct exposure is dangerous. The correct answer highlights that a reverse proxy is a suitable solution, but also encourages further review – demonstrating a more complete understanding of the situation.
16 / 29
During a standup meeting, Mark says: "I've been struggling to get my new service to connect to the database. I'm using Docker Compose and it keeps failing with a DNS resolution error." He suspects the issue might be related to how services within the stack communicate. Which of the following is the MOST likely root cause, given this scenario?
Mark's problem points to DNS resolution failing within the Docker Compose network. Containers within the same network are typically joined through a custom bridge network created by Docker Compose. If the hostname specified in the API service's configuration doesn't resolve correctly within this network, it will fail to connect. Options B and C represent potential networking issues but don't directly address the core DNS resolution problem; option D is less likely given the scenario description.
17 / 29
Liam is reviewing a Docker Compose file for a new web application. The `services` section defines a service named 'web' that uses an image called 'nginx:latest'. The configuration includes the following line: ports: - "80:80". A senior developer, Maya, comments: 'Liam, I'm not entirely comfortable with exposing port 80 directly to the host machine like this. While it works for simple demos, it significantly increases our attack surface. We should be using a reverse proxy – something like Nginx itself – to handle incoming requests and forward them to the 'web' service on its internal port.' What is Maya's primary concern regarding this configuration?
Maya's concern centers on the direct exposure of port 80. This creates a significant security vulnerability by allowing external actors to directly access the 'web' service. By using a reverse proxy (like another Nginx instance), incoming requests are handled and filtered before reaching the application, reducing the attack surface considerably. The primary issue isn't the image itself or performance, but rather the direct exposure of the web service.
18 / 29
During a Slack discussion about deploying a new microservice, David asks: 'I'm trying to run my Docker Compose stack locally, but I keep getting an error saying 'failed to start container'. I've checked the logs and it seems like the service isn't waiting for the database to be ready. What's the best approach to ensure the services start in the correct order?' Which response is most appropriate?
The depends_on directive is crucial for ensuring services start in the correct order within a Compose stack. It explicitly defines dependencies between services, preventing issues where a service tries to connect to a database that hasn't yet been initialized. Using `docker compose up --build` might force a rebuild but doesn't guarantee dependency resolution; increased logging simply provides more information without addressing the core problem.
19 / 29
You're writing a PR description for updating your Docker Compose file. You've added a new `environment` variable to your service definition: `DATABASE_URL=postgres://user:password@db:5432/mydb`. Which of the following best describes how this variable is being used and its potential impact?
Environment variables are commonly used to dynamically configure services. In this case, `DATABASE_URL` provides a flexible way to manage the database connection string without hardcoding it in the Docker Compose file. This simplifies deployments and allows for easy configuration changes.
20 / 29
Liam is reviewing a Docker Compose file for a new web application. The `services` section defines a service named 'web' that uses an image called 'nginx:latest'. The configuration includes the following line: ports: - 8080:80. What potential issue might this configuration present, and how could it be addressed?
Exposing port 80 directly to the host machine can be a security risk. While it may seem straightforward, this approach exposes the Nginx web server directly to external traffic without any routing or firewall rules. A more secure practice would involve using `proxy_pass` or appropriate network configurations.
21 / 29
During a code review of a Docker Compose file for a new API service, Emily comments: 'I noticed you're using the `depends_on` directive on Service A to start before Service B. While this works, it tightly couples them. Consider using a healthcheck instead to ensure Service B isn't started until Service A is ready.' What does Emily *primarily* mean in this context?
services:
- name: service_a
image: myapp/service_a
…
Emily is highlighting a potential issue with tight coupling between services. Using `depends_on` can lead to cascading failures if Service A becomes unavailable before Service B. A healthcheck provides a more reliable mechanism for determining when a service is ready, decoupling the startup order and improving overall system resilience. The incorrect options either misinterpret the purpose of `depends_on` or suggest an inappropriate solution.
22 / 29
In a Slack channel discussing deployment issues, Alex writes: 'My Docker Compose stack isn't starting. The error message says 'Error response from daemon: Error creating container myapp_web: Driver failed attach...'. I've checked the image and ports are correct but it still fails.' What is Alex *most likely* experiencing?
#docker-compose channelAlex: 'My Docker Compose stack isn't starting…'
Alex's error message 'Error creating container…' strongly suggests that the Docker daemon is unable to resolve the specified image name or pull it from its source. This could be due to DNS resolution problems, a network outage, or an incorrectly configured registry URL – all common causes for this particular error message. The other options represent alternative failure modes but aren't as directly indicated by the provided error.
23 / 29
During a daily stand-up meeting, David says: 'I'm running into issues getting my new microservice to communicate with the message queue. I'm using Docker Compose and I suspect there might be a problem with the network configuration between the services.' What *specific* aspect of the environment is David most likely investigating?
You're writing a PR description…
David's suspicion about 'network configuration' points directly to the underlying networking setup within Docker Compose. Docker Compose creates a default network bridge that services can use to communicate. If this network isn't correctly configured (e.g., not properly connected or with incorrect subnet settings), services won't be able to find each other, leading to communication failures. The other options represent potential issues in service configuration but don't directly address the core networking problem.
24 / 29
Sarah is reviewing a Docker Compose file for a new application and notices this configuration: `volumes: - ./data:/app/data`. What does Sarah *primarily* mean when she comments on this line?
Liam is reviewing…
The `- ./data:/app/data` syntax specifies volume mounting. This means that the directory `./data` on the host machine is directly linked into the container's filesystem at `/app/data`. Changes made in one location are immediately reflected in the other – a key distinction from simply copying files, which would only create a snapshot at build time. The incorrect options misinterpret how volume mounting works or describe alternative file system operations.
25 / 29
During a Slack discussion about troubleshooting a failing Docker Compose stack, Ben writes: 'The container isn't starting. The error message says 'failed to start container'. I've checked the logs and they show a problem with the network configuration.' Which of the following best describes what Ben is likely encountering regarding virtualization within his Docker Compose setup?
A. A misconfigured DNS server preventing service discovery.
B. An issue with the host machine's firewall blocking container communication.
C. The containers are not properly linked together, leading to dependency issues.
D. Insufficient resources (CPU or memory) allocated to the containers.
Ben is focusing on network connectivity, a crucial aspect of Docker Compose and virtualization. Containers need to be able to resolve hostnames and communicate with each other over networks. Option A specifically addresses DNS resolution, which is frequently the root cause of container startup failures. Options B, C, and D represent other potential problems but don't directly relate to Ben's initial description about network configuration.
26 / 29
You are reviewing a Docker Compose file for a new service called 'api'. The `environment` section contains the following: `API_KEY=your_secret_key`. A colleague comments: 'While this is functional, storing sensitive information directly in the environment variables isn't best practice. It could be exposed if the container image is accidentally shared or compromised.' What does this comment primarily highlight regarding virtualization and security?
A. The need to use a Dockerfile to build the image.
B. The importance of using volumes for persistent data storage.
C. The potential risks associated with exposing sensitive configurations within container environments.
D. The requirement to configure network policies for the service.
The comment underscores a key security concern when deploying applications in Dockerized environments – namely, the exposure of secrets like API keys directly within environment variables. This practice can lead to vulnerabilities if the container image is inadvertently shared or compromised. Options A, B, and D are related to other aspects of deployment but don't address this specific security issue.
27 / 29
During a code review, Emily notices the following in a Docker Compose file:
```yaml
services:
web:
image: myapp/web
ports: [8080]
depends_on: [db]
```
She asks: 'Why is the `web` service directly exposing port 8080? Shouldn't we be using a reverse proxy or load balancer?' What primary issue does Emily identify concerning virtualization and application architecture?
A. The lack of a defined network configuration for the container.
B. The direct exposure of the service to external traffic, bypassing architectural best practices.
C. The absence of an environment variable specifying the database connection string.
D. The failure to define resource limits (CPU and memory) for the container.
Emily is correctly pointing out a common anti-pattern: exposing services directly to external ports without using a reverse proxy or load balancer. This bypasses architectural best practices like traffic management, security, and scalability. While options A, C, and D represent valid concerns in other contexts, they aren't the core issue Emily raises regarding virtualization.
28 / 29
Liam is reviewing a Docker Compose file for a microservice. The `volumes` section includes this line: `volumes: - ./data:/app/data`. He asks his team lead: 'What's the *primary* reason we're using a volume here, instead of just mounting the directory directly?'
A. To automatically update the container image whenever changes are made to the host machine.
B. To ensure data persistence even if the container is restarted or deleted.
C. To improve the performance of file operations within the container.
D. To simplify the deployment process by eliminating the need for a Dockerfile.
The use of volumes in this scenario primarily addresses data persistence. Volumes provide a way to store data separately from the container's filesystem, ensuring that changes made to the data are preserved even if the container is stopped or removed. Options A, C, and D represent different benefits of using volumes but don't capture the core purpose here.
29 / 29
During a Slack discussion about debugging a Docker Compose stack that won't start, Alex writes: 'I'm seeing an error that says 'Error response from daemon: Error creating container myapp_web: Driver failed attach...'. What is the *most* likely root cause of this issue?
A. The Docker image doesn't have a valid entrypoint defined.
B. The network configuration within the Docker Compose file is incorrect, preventing the container from attaching to the host's network interface.
C. The Docker daemon isn't running on the host machine.
D. The application inside the container has a critical error that prevents it from starting.
The 'Driver failed attach…' error message strongly suggests a networking problem within the Docker Compose configuration. This typically indicates an issue with how the container is connected to the host's network – whether it's attempting to use the wrong IP address or lacking proper network permissions. Options A, C, and D represent alternative causes for container startup failures but don't align with this specific error message.
What does the "Docker Compose Vocabulary" exercise practise?
Practice Docker Compose vocabulary in English: file structure, service dependencies, env_file vs environment, named volumes, and override file patterns. 5 intermediate exercises.
How many questions are in this exercise?
This exercise has 29 questions, each multiple-choice with a full explanation shown after you answer.
What English level is this exercise for?
This exercise is tagged Intermediate. If the vocabulary feels difficult, browse the Containers & Virtualization category page for an easier module to start with.
Is this exercise free to use?
Yes. Every exercise on CoderSlingo, including this one, is free with no account, sign-up, or paywall.
Do I get feedback if I answer incorrectly?
Yes — whichever option you choose, right or wrong, you'll immediately see an explanation clarifying the correct term and why the other options don't fit.
Can I retry this exercise?
Yes — once you finish all the questions, a "Try again" button on the results screen resets the exercise so you can practise as many times as you like.
Do I need an account to track my progress?
No account is required. Your progress bar and score for this session are tracked in the browser as you go, but nothing is saved once you leave the page.
Is "Docker Compose Vocabulary" part of a larger series?
Yes — it's one exercise in the Containers & Virtualization category on CoderSlingo. See the category page for the full list of related exercises on similar terminology.
Can I link directly to this exercise?
Yes — this exercise has its own permanent URL, so you can bookmark it or share the link directly with a colleague or study partner.
Where can I find more exercises like this one?
See the Containers & Virtualization category page for related exercises, or browse the main Exercises hub for other IT English topics.