Conflict in multiple Docker-Compose

I’m attempting to run two services using two different docker-compose.yml files with nginx-load balancer.

services:
  nlb: 
    image: "nlb:318" # nginx load balancer using default alpine-slim
    container_name: "nlb.app1"
    ports:
      - "51501:51501" 
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app1

app1:
  ...
  deploy:
    replicas: 3
  ports:
    - "51501"

nginx.conf as follow…

events { workder_connections 1024; }
http
{
  upstream nlb.app1 { server app1:51501 }
  server
  {
    listen 51501;
    location /
    {
      proxy_pass http://nlb:app1;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}

The docker-compose.yml and nginx.conf files for the second service are similar with ports specified as 51502 and app1 tags becomes app2, nlb.app1 becomes nlb.app2 etc.

app1 start up working perfectly, however I observed the when I run docker ps, under the PORTS showed 80/tcp, 0.0.0.0:51501->51501/tcp.

When I run docker-compose.yml file for the second service, nlb.app1 is destroyed and nlb.app2 is created points to 51502!

I suspect it’s because of the 80/tcp port conflict detection when starting app2 that triggers the destruction of nlb.app1

I’ve not specified nlb.app1 or nlb.app2 to listen to port 80/tcp.
Is there a way to remove port 80/tcp explicitly?
Thanks for any suggestion to assist my attempt to run multiple services via multiple docker-compose.yml files.

Please use 3 backticks in front and after your config to make it more readable. In yaml every space matters.

Using standard 2 spaces as single indent.

That’s fine, before every line was left aligned. The compose still seems broken, lower part starts left, but can’t be “root”.

Anyway, what are you trying to do? To me it looks like you try to run 3 containers using the same port 51501 - that’s just not possible.

You have two services using port 51501 and one service should even create 2 replicas.

Are you using Docker Swarm? Otherwise you can’t use multiple replicas when exposing a port.

Usually only the LB or reverse proxy would open the ports, all other services are only using a Docker network and do not expose ports. Within Docker network every container gets an IP and ports are automatically available. See simple Traefik example, I don’t have something for nginx.

I’m running app1 with 3 replicas and using nginx as load balancer, no Docker Swarm, just Docker on a Debian Bookworm host.

app1 started correctly and running docker ps shows the following…

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
662e2eace0d1 nlb:318 “/docker-entrypoint.…” 14 minutes ago Up 14 minutes 80/tcp, 0.0.0.0:51501->51501/tcp nlb.app1
e37fcf1a029f app1:3914.1050 “/app/App.WS” 14 minutes ago Up 14 minutes 0.0.0.0:32788->51501/tcp app1-app1-1
944c32eeb1ea app1:3914.1050 “/app/App.WS” 14 minutes ago Up 14 minutes 0.0.0.0:32789->51501/tcp app1-app1-2
971dafd0f535 app1:3914.1050 “/app/App.WS” 14 minutes ago Up 14 minutes 0.0.0.0:32790->51501/tcp app1-app1-3

I didn’t specify 80/tcp for the load balancer, it should contain only 0.0.0.0:51501->51501/tcp like those for replicas.
Is there any method that I can rid 80/tcp?

The replicas seems to work fine, as when I access the load balancer, each replica is accessed in round-robin pattern, observable via docker stats and responded correctly.

The simple 80/tcp means that the Dockerfile includes an EXPOSE 80 statement. This indicates (by Dockerfile) that port 80 is used. But the port is not necessarily used by an application inside the container or automatically exposed externally by the container.