Exposing a port in traefik

Maybe i am misunderstanding something here.
When i create an entrypoint like

entryPoints:
  mysql:
    address: :3306

Shouldnt that be enough that 'ss -tpln' would display this port as exposed on the docker host system?

I just tested and apparently its not enough. So i created a compose file:

version: '3.1'

services:
  mysql:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.tcp.routers.mysql.rule=HostSNI(`*`)
      - traefik.tcp.routers.mysql.entrypoints=mysql
      - traefik.tcp.routers.mysql.service=mysql
      - traefik.tcp.services.mysql.loadbalancer.server.port=3306
networks:
  proxy:
    external: true

My understanding is that i have a 'mysql' service attached to the entrypoint defined within the traefik configuration. The traefik webif shows everything green, i have a service i have a router the mysql container exposes port 3306 correctly - accessible in the docker host on the internal ip 172.18.0.3:3306

And still the port is not exposed on the host and therefore not accessible from another host on the same subnet. Why?

root@dckr ~ ❯ ss -tpln                                                                                                                                                                                                                              15:40:25
State           Recv-Q          Send-Q                   Local Address:Port                   Peer Address:Port         Process                                                                                                                              
LISTEN          0               4096                           0.0.0.0:111                         0.0.0.0:*             users:(("rpcbind",pid=651,fd=4),("systemd",pid=1,fd=143))                                                                           
LISTEN          0               4096                           0.0.0.0:80                          0.0.0.0:*             users:(("docker-proxy",pid=802256,fd=4))                                                                                            
LISTEN          0               4096                     127.0.0.53%lo:53                          0.0.0.0:*             users:(("systemd-resolve",pid=636746,fd=14))                                                                                        
LISTEN          0               511                            0.0.0.0:8085                        0.0.0.0:*             users:(("nginx",pid=821,fd=6),("nginx",pid=820,fd=6),("nginx",pid=819,fd=6),("nginx",pid=818,fd=6),("nginx",pid=817,fd=6))          
LISTEN          0               4096                         127.0.0.1:8086                        0.0.0.0:*             users:(("docker-proxy",pid=2196,fd=4))                                                                                              
LISTEN          0               128                            0.0.0.0:22                          0.0.0.0:*             users:(("sshd",pid=806,fd=3))                                                                                                       
LISTEN          0               4096                           0.0.0.0:443                         0.0.0.0:*             users:(("docker-proxy",pid=802234,fd=4))                                                                                            
LISTEN          0               4096                              [::]:111                            [::]:*             users:(("rpcbind",pid=651,fd=6),("systemd",pid=1,fd=145))                                                                           
LISTEN          0               4096                              [::]:80                             [::]:*             users:(("docker-proxy",pid=802264,fd=4))                                                                                            
LISTEN          0               128                               [::]:22                             [::]:*             users:(("sshd",pid=806,fd=4))                                                                                                       
LISTEN          0               4096                              [::]:443                            [::]:*             users:(("docker-proxy",pid=802241,fd=4))                                                                                            
root@dckr ~ ❯  

What am i missing?

No, you need to expose the port using ports in docker-compose.yml. You can see the port used inside the container, when only using entrypoint.

Thanks for your post.
I thought traefik handles all this 'automagically'.
I have a couple of docker stacks running on that host, not a single one requires the 'ports' block within its compose file. All of them are http/https services though.
This time i would like to publish a non http/https service via traefik.
Correct me if i am wrong but exposing the port via the 'ports' block does not use traefik at all, does it?

Docker is for containerization, it "wraps" the task/service in a secure "environment", you can't just access outside resources like ports or files. You explicitly need to tell Docker to forward a hosts port to a container or declare to use the full host network.

You only need "ports" with Traefik, all other services don't need to expose ports. For plain TCP with TLS/SSL use TCP router with HostSNI() rule and a loadbalancer.server.port.

If it's plain TCP (without TLS/SSL), then you need to use HostSNI(`*`) and can not route by domain, but only have a single service on that entrypoint.

Hm, that still doesnt answer my question.

What is the difference between this two compose files then?
Both of them expose port 3306 to the world.
What benefit do i get, using the first one?

version: '3.1'

services:
  mysql:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
    networks:
      - proxy
    ports:
      - 3306:3306
    labels:
      - traefik.enable=true
      - traefik.docker.network=proxy
      - traefik.tcp.routers.mysql.rule=HostSNI(`*`)
      - traefik.tcp.routers.mysql.entrypoints=mysql
      - traefik.tcp.routers.mysql.service=mysql
      - traefik.tcp.services.mysql.loadbalancer.server.port=3306
networks:
  proxy:
    external: true
version: '3.1'

services:
  mysql:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
    networks:
      - mysql
    ports:
      - 3306:3306
networks:
  mysql:
    external: true

If both (Traefik, MySQL) run on the same server there is no real difference. Only one should use external port 3306.

Usually Traefik is used for TLS termination and/or to route to different services on the same port, based on Host and Path. When using http, you can add middlewares like user/pass check.

Advantage of Traefik for plain TCP is that you can forward requests to other nodes, so the service can run on a different server, you can have only one server exposed to the Internet.