Docker Swarm Access Container to Container on Published Port?
The swarm makes the service accessible at the published port on every swarm node. If an external host connects to that port on any swarm node, the routing mesh ...
First, on docker swarm, you use
docker stack deploy not
docker compose to deploy services.
Docker swarm manages service connections with overlay networks: When you deploy a stack (
docker stack deploy) an overlay network is implicitly created and the services are attached to it. All services attached to an overlay network can discover each other using docker's mesh networking dns discovery.
So, in practical terms, you could deploy your smtp service with a stack file modified to look more like this:
version: "3.9" networks: public: attachable: true driver: overlay name: smtp services: smtp: image: ... command: .... --listen :25 networks: - public ports: - 2525:25 healthcheck: test: netstat -l | grep 25 ...
Further caveats: there is no port remapping when services connect to each other using dockers bridge or overlay networks. The "ports" directive only applies to ingress, that is, packets arriving on the docker nodes from outside the swarm, that need to be routed to services. So, for service-to-service traffic to communicate over :25, then the smtp container needs to be configured to listen on :25.
Once that is done you can connect to smtp from containers and services by specifying the target network.
With that in mind, and assuming the smtp service can be configured to listen on :25 I attach the service explicitly to a network called "public" in the compose file. This network is created with the global name "smtp", and it is marked as attachable so ad-hoc containers can be attached to it. Its explicitly declared as "overlay" as docker compose would deploy this compose and try and create it as a
Then, to verify that this works, the netshoot container can be used. Simply attach it to the now available network and verify that dns resolves the "smtp" name on that network, and port 25 is reachable.
docker run --network smtp --rm -it nicolaka/netshoot $ telnet smtp 25 ...
Other services that need to consume smtp would then be attached to the smtp public network:
version: "3.9" networks: smtp: external: true services: some-other-service: image: ... command: .... environment: SMTP_URL: smtp://smtp:25 networks: - default - smtp
Here I am explicitly attaching this service to the implicit default stack network in case there are other services its talking to, in addition to the smtp network.
Click Here to Visit