Skip to content

Reverse proxy

Pavel Erokhin edited this page Oct 19, 2026 · 1 revision

WorldAPI speaks plain HTTP on port 8110. Opened to the internet as it is, it sends every token and panel password as readable text: anyone on the way, from a café's Wi-Fi to a hosting provider's network, can copy them and run your server. A port scanner also finds it within hours.

WorldAPI notices such requests and warns in the console and in the panel. Only you can close the door: keep 8110 private and put a reverse proxy with HTTPS in front of it.

1. Tell WorldAPI to trust the proxy

http:
  trustForwardedFor: true   # count real visitors in rate limits

Only addresses in http.trustedProxies may set X-Forwarded-For. The default list covers localhost and private networks, which fits a proxy on the same machine or in Docker.

2. Set up the proxy

Each example serves the API and the panel at https://mc.example.com/worldapi/. X-Forwarded-Prefix tells the panel where it lives.

Caddy gets a certificate by itself. A Caddyfile:

mc.example.com {
    handle_path /worldapi/* {
        reverse_proxy minecraft:8110 {
            header_up X-Forwarded-Prefix /worldapi
        }
    }
}

nginx, with a certificate you already have:

location /worldapi/ {
    proxy_pass http://minecraft:8110/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;     # the WebSocket
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-Prefix /worldapi;
}

Docker Compose, the whole server with Caddy in front. Only 25565 and the web ports face the internet; 8110 stays on the compose network:

services:
  minecraft:
    image: itzg/minecraft-server:java25
    environment:
      EULA: "TRUE"
      TYPE: PAPER
      VERSION: "26.3"
      MODRINTH_PROJECTS: |
        worldapi
    ports: ["25565:25565"]
    volumes: ["./data:/data"]

  caddy:
    image: caddy:2
    ports: ["80:80", "443:443"]
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy:/data

volumes:
  caddy:

3. Point the panel's links at it

panel:
  publicUrl: https://mc.example.com/worldapi

No domain?

Reach WorldAPI through an SSH tunnel instead, and nothing needs to be public:

ssh -L 8110:localhost:8110 you@your-server
# then open http://localhost:8110/admin/ on your own machine

Next: Security.

Clone this wiki locally