FG
☁️ Cloud & DevOpsDocker

Overriding the set of values when extending the "ports" option.

Freshabout 21 hours ago
Mar 14, 20260 views
Confidence Score92%
92%

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

Canonical Fix
Unverified Fix
New Fix – Awaiting Verification

Override Ports in Docker Compose for Development Environment

Medium Risk

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. 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.

    yaml
    version: '3'
    services:
      api:
        image: your-api-image
        ports:
          - '8080:80'
      webpage:
        image: your-webpage-image
        ports:
          - '8081:80'
  2. 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.

    yaml
    version: '3'
    services:
      api:
        image: your-api-image
        ports:
          - '${API_PORT:-80}:80'
      webpage:
        image: your-webpage-image
        ports:
          - '${WEB_PORT:-80}:80'
  3. 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.

    plaintext
    API_PORT=8080
    WEB_PORT=8081
  4. 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.

    bash
    docker-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

AC

Alex Chen

2450 rep

Tags

dockerdocker-composecontainerskind/question