Bind port address to single IP

Hello,

i have a docker swarm cluster and i need to bind some services (mysql, ftp, ecc) accessibile from eternal connection, but only from a specific IP address

which is the best way for that?

if i use
ports:
- “XXXX:XXXX”

the service work but works for any IP ADDRESS

if have tried this one without success:

ports:
- “A.B.C.D:XXXX:XXXX”

can you help me?

The syntax with “A.B.C.D:YYYY:XXXX” is meant to publish the containers port (XXXX) on the host’s IP A.B.C.D as port YYYY. Since you’re using a swarm cluster, there’s not a way to pin it to a particular swarm node’s IP while having the benefits of swarm (rescheduling the service on another node in case that node goes down). So while the docker-compose file format allows that syntax, it isn’t allowed using docker stack deploy and also not when you try it manually via docker service create.

If you’re looking to restrict who can access this service by client IP, you’ll probably want to front it with something like haproxy and use the haproxy config to restrict which clients can reach the service. Additionally, you’ll probably want to put the service you want to restrict access to an on “internal” network.

Setup (minus the actual haproxy configuration):

version: "3.0"
services:
  proxy:
    depends_on:
      - mysql
    image: haproxy:latest
    ports:
      - 3306:3306
    networks:
      - front
      - back
    volumes:
      proxycfg:/usr/local/etc/haproxy:ro

  svca:
    depends_on:
      - mysql
    image: myserviceaimage:latest
    environment:
      - "DB_HOST=mysql"
      - "DB_PORT=3306"
      - "DB_NAME=foo"
      - "DB_USER=bar"
      - "DB_PASSWD=neverputpasswordincomposefile"
    ports:
      - 80:80
    networks:
      - front
      - back
  mysql:
    image: mysql:latest
    environment:
      - "MYSQL_DATABASE=foo"
      - "MYSQL_USER=bar"
      - "MYSQL_PASSWORD=neverputpasswordincommposefile"
      - "MYSQL_RANDOM_ROOT_PASSWORD=yes"
    networks:
      - back
    volumes:
      - mysqldata:/var/lib/mysql

networks:
  front:
  back:
    internal: true

volumes:
  proxycfg:
  mysqldata: