Reverse proxy minecraft server

Hi, I just want to reverse proxy my minecraft server so that when I connect to my external IP on port 25565, traefik forwards my packets to an internal ip address at port 25565

Do you need TLS on the port? Will the Minecraft server create a certificate?

From my research, Minecraft uses a version of TCP that doesn't support TLS. So no.

Any ideas on how to achieve this?

Create a Traefik container listening on your port, create a dynamic config file to proxy/forward any incoming connection on that entrypoint to a target service.

minecraft Docker service is a fake inside Docker network. But you can just adjust the target IP:port in the dynamic config file, even to outside Docker network.

docker-compose.yml:

services:
  traefik:
    image: traefik:v3
    volumes:
      - ./traefik-dynamic.yml:/traefik-dynamic.yml
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik-certificates:/certificates
    ports:
      - 80:80
      - 443:443
      - 25565:25565
    networks:
      - proxy
    command:
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=proxy
      - --providers.file.filename=/traefik-dynamic.yml
      - --providers.file.watch=true
      - --entryPoints.web.address=:80
      - --entryPoints.web.http.redirections.entryPoint.to=websecure
      - --entryPoints.web.http.redirections.entryPoint.scheme=https
      - --entryPoints.websecure.address=:443
      - --entryPoints.websecure.http.tls.certResolver=myresolver
      - --entryPoints.minecraft.address=:25565
      - --api.debug=true
      - --api.dashboard=true
      - --log.level=INFO
      - --accesslog=true
      - --certificatesResolvers.myresolver.acme.email=mail@example.com
      - --certificatesResolvers.myresolver.acme.storage=/certificates/acme.json
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
    labels:
      - traefik.enable=true
      - traefik.http.routers.api.entrypoints=websecure
      - traefik.http.routers.api.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
      - traefik.http.routers.api.service=api@internal
      - traefik.http.routers.api.middlewares=auth
      - 'traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/'

  whoami:
    image: traefik/whoami:v1.10
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.http.routers.whoami.entrypoints=websecure
      - traefik.http.routers.whoami.rule=Host(`whoami.example.com`)
      - traefik.http.services.whoami.loadbalancer.server.port=80

  minecraft:
    image: traefik/whoami:v1.10
    networks:
      - proxy

volumes:
  traefik-certificates:

networks:
  proxy:
    name: proxy
    attachable: true

traefik-dynamic.yml:

tcp:
  routers:
    forward:
      entrypoints:
        - minecraft
      rule: HostSNI(`*`)
      service: forward

  services:
    forward:
      loadBalancer:
        servers:
          - address: minecraft:80

I am stuck with that configuration.
As it seems there is no way around to expose one additional port beside 80 and 443 I tried to adapt the above posted configuration but I do get errors which I unfortunately cannot understand.

Within my traefik compose file I've added the Minecraft entrypoint
- "--entrypoints.minecraft.address=:19132"
and added as well the port

- "19132:19132"

In addition I've adjusted the rules

tcp:
   routers:
    minecraft:
      entrypoints:
        - minecraft
      rule: HostSNI(`*`)
      service: minecraft-service

  services:
    minecraft:
      loadBalancer:
        servers:
          - address: "192.168.2.2:19132" ##address of my Server##

while my labels within docker compose of minecraft is being equipped with respective labels


    labels:
      - "traefik.enable=true"
      #- "traefik.udp.routers.minecraft.entrypoints=minecraft"
      #- "traefik.udp.routers.minecraft.service=minecraft-service"
      #- "traefik.udp.services.minecraft-service.loadbalancer.server.port=19132"
      - "traefik.http.routers.minecraft.entrypoints=websecure"
      - "traefik.http.routers.minecraft.rule=Host(`mc.test.de`)"
      - "traefik.http.services.minecraft.loadbalancer.server.port=19132"

Appreciate any help :slight_smile:

Why do you create a tcp and http router to the same target service port?