Overriding the set of values when extending the "ports" option.
Problem
The default behavior when extending a service or overriding a whole docker-compose.yml file is to concatenate the sets of values on the multi-value options: ports, expose, external_links, dns and dns_search. The problem appears when for example you have two production hosts both serving on the port 80 and a single machine for development, there is no way of extending or overriding the services for a development environment that avoids the port collision on the host. An example: lets assume there are two servers one is a REST API and the other is a webpage that uses the API, both listen on port 80 on the production host - compose.yml on host A: [code block] - compose.yml on host B: [code block] On a development environment where you want to test this setup you would define: - compose.override.yml on dev for A: [code block] - compose.override.yml on dev for B: [code block] Of course the "ports" option is concatenated with the production and there is no way of running both containers on the same host because both try to bind to port 80. Is there any workaround or yml specific syntax for this use case?
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Override Ports in Docker Compose for Development Environment
Docker Compose concatenates multi-value options like 'ports', 'expose', etc., when extending or overriding configurations. This behavior leads to port collisions when multiple services are defined to bind to the same host port, especially in development environments where multiple instances of services are needed.
Awaiting Verification
Be the first to verify this fix
- 1
Define Unique Ports for Development
In your development override YAML file, explicitly define unique ports for each service to avoid collisions. Use a different port mapping for development compared to production.
yamlversion: '3' services: api: image: your-api-image ports: - '8080:80' webpage: image: your-webpage-image ports: - '8081:80' - 2
Use Environment Variables for Port Configuration
Utilize environment variables to dynamically set the ports based on the environment. This allows you to easily switch between production and development configurations without hardcoding values.
yamlversion: '3' services: api: image: your-api-image ports: - '${API_PORT:-80}:80' webpage: image: your-webpage-image ports: - '${WEB_PORT:-80}:80' - 3
Create a .env File for Development
Create a .env file in your development directory to specify the port values. This file will be read by Docker Compose to set the environment variables defined in the docker-compose.override.yml.
plaintextAPI_PORT=8080 WEB_PORT=8081 - 4
Run Docker Compose with Override
When running your containers, ensure you use the override file to apply the development settings. This can be done by simply running 'docker-compose up' as Docker Compose automatically looks for the override file.
bashdocker-compose up
Validation
Confirm the fix by running 'docker-compose up' and ensuring that both services start without port conflicts. You can check the logs or use 'docker ps' to verify that the containers are running on the specified unique ports.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep