'docker compose override a ports property instead of merging it

My docker compose configs look like this:

docker-compose.yml

version: '3.5'

services:
    nginx:
        ports:
            - 8080:8080

docker-compose.prod.yml

version: '3.5'

services:
    nginx:
        ports:
            - 80:80

Now, when I run command: docker-compose -f docker-compose.yml -f docker-compose.prod.yml up the nginx exposes on host machine two ports: 8000 and 80, because it merges ports properties:

version: '3.5'

services:
    nginx:
        ports:
            - 8080:8080
            - 80:80

Is there a way to override it? I want to expose only port 80.



Solution 1:[1]

it isn't possible a the moment but I found quite good way to fix this issue using the command yq. You need to remove the ports from the original file.

Example:
Be careful this command will remove the nginx ports from your current docker-compose.yml (because of the -i option)

yq e -i 'del(.services.nginx.ports)' docker-compose.yml

You can execute this command on your deployment script or manually before your docker-compose up -d

There's also an open issue on docker-compose, that you may want to check once in a while.

Solution 2:[2]

Just keep the docker-compose.yml super simple and add the ports in another file docker-compose.develop.yml, then run it like docker-compose -f docker-compose.yml -f docker-compose.develop.yml up. This way you can separate it from your docker-compose.override.yml file.

So you will have three files:

|- docker-compose.yml # no ports specified
|- docker-compose.override.yml # ports 8080:8080
|- docker-compose.develop.yml #ports 80:80

Refer to this post for longer explanation: https://mindbyte.nl/2018/04/04/overwrite-ports-in-docker-compose.html

Solution 3:[3]

I've faced the same problem. The proposed solution with docker-compose.override.yml sounds pretty well and is also an official one.

Although for some of my own projects I've applied the erb template engine to make docker-compose.yml.erb file compile for multiple environments. In short I use:

COMPOSE_TEMPLATE_ENV=production erb docker-compose.yml.erb > docker-compose.yml
COMPOSE_TEMPLATE_ENV=production erb docker-compose.yml.erb > docker-compose-production.yml

And then I can use the ENV['COMPOSE_TEMPLATE_ENV'] in my template and also the syntax of ERB, so only one file to configure and no worries about piplening them properly. Here's the short post article I've written about it

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 zinovyev