0

I have a Docker Swarm with four physical systems in it. With the following docker-compose.yml file

version: '3.9'
services:
  web1:
    image: nginx
    ports:
      - 8080:80 

I can create a web server with the command

docker stack deploy -c docker-compose.yml test

and the service is created and responds to port 8080 on all four IP addresses owned by the four physical systems. This is exactly what the Docker documentation says it will do by creating an overlay network that does mesh routing across all the nodes in the swarm.

However that is not what I want. What I want is to bind port 8080 to only one IP address on one of the nodes and direct traffic via DNS to that one address. This will allow me to use port 8080 on the other three nodes for other services. Is there a way to do this?

I have seen this question asked before, and typically the question is years old and no usable answer. One solution offered was to use iptables rules in each host to get the intended behavior, but I see this as a maintenance problem.

AlanObject
  • 9,613
  • 19
  • 86
  • 142
  • 1
    What if you [publish the port in host mode](https://docs.docker.com/engine/swarm/services/#publish-a-services-ports-directly-on-the-swarm-node), and pin the service to a single node? That would let you run a single copy of the service on that node, at the cost of the service failing if that node goes down. – Nick ODell Nov 30 '21 at 01:36
  • @NickODell What you suggest will probably work, but in addition to the tradeoff you mention it won't allow the container to replicate. I still want the mesh to load balance ingress traffic across n containers distributed in the swarm. – AlanObject Nov 30 '21 at 02:02
  • 1
    It sounds like you really want a reverse proxy like traefik. It would receive the requests on any node and forward to your replicated service based on the hostname in the http request. – BMitch Nov 30 '21 at 09:24
  • @BMitch Right that is Plan B. You can do that with nginx or apache of course but a Docker feature to do this would be more convenient. – AlanObject Nov 30 '21 at 16:41
  • I dont think docker is going to implement a feature that will make HA literally impossible. traefik is the go to for hostname based routing, if you really want/need to handle connections to swarm for a non SNI compatible service like ms-sql, then you might want to use keepalived and virtual ips associated with services that are rotated by a pool of docker nodes, and some fancy keepalived rules to do port remapping, so unique ports on docker, get unique ips via keepalived. – Chris Becke Nov 30 '21 at 18:39

0 Answers0