How to Access Docker Swarm Services Across Different Stacks Using Internal DNS


2 views

When working with Docker Swarm multi-stack deployments, developers often need to establish communication between services in different stacks. While the obvious solution is exposing ports, this approach introduces unnecessary security risks and complicates network architecture.

Docker Swarm provides a built-in DNS server (127.0.0.11) that automatically resolves service names within the same stack. For cross-stack communication, the naming convention follows this pattern:

service_name.stack_name

The documentation you referenced applies specifically to Docker Cloud (now deprecated), not current Docker Swarm implementations. In modern Docker Swarm:

  • Cross-stack DNS only works when using overlay networks attached to both stacks
  • The stacks must share at least one common overlay network
  • Services must be connected to this shared network

Here's how to properly configure your stacks:

# First, create an overlay network accessible to both stacks
docker network create --driver overlay --attachable shared_net

# Deploy your stacks with network configuration
# main-stack.yml
version: "3.8"
services:
  my_app:
    image: my_app_image
    networks:
      - shared_net
networks:
  shared_net:
    external: true

# mon-stack.yml
version: "3.8"
services:
  grafana:
    image: grafana/grafana
    networks:
      - shared_net
networks:
  shared_net:
    external: true

After deployment, you can verify connectivity from within a container in the main stack:

# Access a container in the main stack
docker exec -it main_stack_container sh

# Test DNS resolution
nslookup grafana.mon
# Should return the proper IP

# Test connectivity
curl http://grafana.mon:3000

If you can't use shared networks, consider:

  1. Ambassador Pattern: Create a proxy service in the target stack
  2. API Gateway: Implement a centralized access point
  3. Service Mesh: Use tools like Linkerd or Istio

If DNS resolution still fails:

  • Verify both services are running: docker service ls
  • Check network attachments: docker network inspect shared_net
  • Test basic connectivity between containers
  • Inspect DNS configuration: cat /etc/resolv.conf inside containers

When working with multi-stack deployments in Docker Swarm, accessing services across stack boundaries presents unique challenges. The traditional approach of exposing ports creates security vulnerabilities and complicates network architecture. Let me share a practical solution I've implemented in production environments.

The 127.0.0.11 DNS resolver is Docker's magic sauce for service discovery. However, its cross-stack capabilities aren't immediately obvious. Here's what actually works:


# This won't work cross-stack:
ping grafana.mon

# The proper FQDN format for cross-stack access:
ping tasks.grafana_mon

For cross-stack communication to function, both stacks must share the same overlay network. Here's how to set it up:


# Create the shared network (run once)
docker network create --driver overlay --attachable shared_net

# In your compose files:
services:
  grafana:
    networks:
      - shared_net

networks:
  shared_net:
    external: true

Let's examine a complete solution for accessing Grafana from another stack:


# main-stack.yml
version: "3.8"
services:
  exporter:
    image: prom/node-exporter
    networks:
      - shared_net

networks:
  shared_net:
    external: true

# mon-stack.yml 
version: "3.8"
services:
  grafana:
    image: grafana/grafana
    networks:
      - shared_net

networks:
  shared_net:
    external: true

To confirm everything works as expected:


# From a container in main stack:
docker exec -it main_exporter_1 ping tasks.grafana_mon

# Expected output:
PING tasks.grafana_mon (10.0.1.23): 56 data bytes
64 bytes from 10.0.1.23: seq=0 ttl=64 time=0.123 ms

For production environments, consider these enhancements:

  • Implement network policies for security
  • Use Docker secrets for authentication
  • Configure health checks for reliability

The key takeaway is that tasks.serviceName_stackName is the reliable pattern for cross-stack discovery when using shared overlay networks. This approach maintains security while providing the connectivity needed for microservices architectures.