Forbid docker-swarm node from publish ports on WAN interface

I have configured single node/manager docker-swarm + portainer on remote machine with WAN and internal VLAN interfaces. I’ve configured first stack:

version: '3.8'
services:
  django-postgresql:
    image: postgres:14.5-bullseye
    hostname: psql
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASSWORD}
    networks:
      - django-backend
    ports:
      - "127.0.0.1:5432:5432"
    expose:
      - 5432
    volumes: 
      - postgresql-django-data:/var/lib/postgresql/data
      - postgresql-django-scripts:/opt/postgresql-django-scripts

I DO NOT want my services accessible on WAN interface! How can i make docker-swarm bind ports on selected interfaces? (localhost or private vlan)?

Swarm doesn’t allow to map port using the host-ip:host-port:container-port, it only allows host-port:container-port. Swarm is intended as multi-node orchestrator. As mapping a host ip in this scenario doesn’t make sense, it was never implemented for swarm.

You have plenty of options:

  • use plain docker with docker compose, or run a single node Kubernetes cluster with a distro like k3s instead
  • do not publish ports, and create your own rules for iptables to map host ports to container ports (you are on your own here)
  • use host network for your containers and block traffic from the wan-interface (you are on your own here)

The easiest solution would be to use plain docker with docker compose and use host-ip:host-port:container-port mapping.