docker-minecraft-bedrock-server icon indicating copy to clipboard operation
docker-minecraft-bedrock-server copied to clipboard

Multiple instances

Open illiteratealliterator opened this issue 4 years ago • 15 comments

I've been trying, somewhat desperately, to get multiple instances of your excellent container running for my kids on a single machine. I've tried so many things... different ports, macvlan, multiple nics, but no luck for one reason or another.

Any chance you have any ideas why this isn't working?

version: "3.7"
services:
  minecraft-survival:
    image: itzg/minecraft-bedrock-server
    container_name: minecraft-survival
    environment:
      - UID=1000
      - GID=1000
      - EULA=TRUE
      - SERVER_NAME=Survival
      - GAMEMODE=survival
      - DIFFICULTY=easy
      - LEVEL_TYPE=default
      - ONLINE_MODE=false
      - ALLOW_CHEATS=true
      - LEVEL_SEED=1935762385
      - SERVER_PORT=19132
      - SERVER_PORT_V6=19133
    volumes:
      - /var/lib/minecraft-survival:/data
    ports:
      - '19132:19132/udp'
    restart: always
    stdin_open: true
    tty: true

  minecraft-creative:
    image: itzg/minecraft-bedrock-server
    container_name: minecraft-creative
    environment:
      - UID=1000
      - GID=1000
      - EULA=TRUE
      - SERVER_NAME=Creative
      - GAMEMODE=creative
      - DIFFICULTY=peaceful
      - LEVEL_TYPE=flat
      - ONLINE_MODE=false
      - ALLOW_CHEATS=true
      - SERVER_PORT=19134
      - SERVER_PORT_V6=19135
    volumes:
      - /var/lib/minecraft-creative:/data
    ports:
      - '19134:19134/udp'
    restart: always
    stdin_open: true
    tty: true

The servers start successfully:

Starting Bedrock server...
NO LOG FILE! - setting up server logging...
[2020-11-26 13:44:17 INFO] Starting Server
[2020-11-26 13:44:17 INFO] Version 1.16.101.1
[2020-11-26 13:44:17 INFO] Session ID d03d0207-ffb0-4617-adad-733dc1036219
[2020-11-26 13:44:17 INFO] Level Name: Bedrock level
[2020-11-26 13:44:17 INFO] Game mode: 0 Survival
[2020-11-26 13:44:17 INFO] Difficulty: 1 EASY
[INFO] opening worlds/Bedrock level/db
[INFO] IPv4 supported, port: 19132
[INFO] IPv6 not supported
[INFO] IPv4 supported, port: 59031
[INFO] IPv6 not supported
[INFO] Server started.
Starting Bedrock server...
NO LOG FILE! - setting up server logging...
[2020-11-26 13:44:17 INFO] Starting Server
[2020-11-26 13:44:17 INFO] Version 1.16.101.1
[2020-11-26 13:44:17 INFO] Session ID cc78b276-442f-4c94-b61f-a9bb81a8b947
[2020-11-26 13:44:17 INFO] Level Name: Bedrock level
[2020-11-26 13:44:17 INFO] Game mode: 1 Creative
[2020-11-26 13:44:17 INFO] Difficulty: 0 PEACEFUL
[INFO] opening worlds/Bedrock level/db
[INFO] IPv4 supported, port: 19134
[INFO] IPv6 not supported
[INFO] IPv4 supported, port: 19132
[INFO] IPv6 not supported
[INFO] Server started.

But for some reason the server always logs "IPv4 supported" twice, with different ports... the second one appears to be random. However, running "docker ps" gives me this:

5 minutes ago  Up 5 minutes (healthy)  0.0.0.0:19132->19132/udp                 minecraft-survival
5 minutes ago  Up 5 minutes (healthy)  19132/udp, 0.0.0.0:19134->19134/udp      minecraft-creative

The fact that 'minecraft-creative' mentions port 19132 in its mappings seems wrong... any idea why that is happening?

Thanks!

illiteratealliterator avatar Nov 26 '20 13:11 illiteratealliterator

I have this working for 3 instances. I am using a macvlan and specifying the IPv4 address in the compose file. Leave the ports to the defaults and the client will be able to discover it. You’ll have to create the macvlan outside of compose and mark it as external in the compose file. I tried various things like you listed but the macvlan worked for me.

On Thu, Nov 26, 2020 at 7:51 AM illiteratealliterator < [email protected]> wrote:

I've been trying, somewhat desperately, to get multiple instances of your excellent container running for my kids on a single machine. I've tried so many things... different ports, macvlan, multiple nics, but no luck for one reason or another.

Any chance you have any ideas why this isn't working?

version: "3.7" services: minecraft-survival: image: itzg/minecraft-bedrock-server container_name: minecraft-survival environment: - UID=1000 - GID=1000 - EULA=TRUE - SERVER_NAME=Survival - GAMEMODE=survival - DIFFICULTY=easy - LEVEL_TYPE=default - ONLINE_MODE=false - ALLOW_CHEATS=true - LEVEL_SEED=1935762385 - SERVER_PORT=19132 - SERVER_PORT_V6=19133 volumes: - /var/lib/minecraft-survival:/data ports: - '19132:19132/udp' restart: always stdin_open: true tty: true

minecraft-creative: image: itzg/minecraft-bedrock-server container_name: minecraft-creative environment: - UID=1000 - GID=1000 - EULA=TRUE - SERVER_NAME=Creative - GAMEMODE=creative - DIFFICULTY=peaceful - LEVEL_TYPE=flat - ONLINE_MODE=false - ALLOW_CHEATS=true - SERVER_PORT=19134 - SERVER_PORT_V6=19135 volumes: - /var/lib/minecraft-creative:/data ports: - '19134:19134/udp' restart: always stdin_open: true tty: true

The servers start successfully:

Starting Bedrock server... NO LOG FILE! - setting up server logging... [2020-11-26 13:44:17 INFO] Starting Server [2020-11-26 13:44:17 INFO] Version 1.16.101.1 [2020-11-26 13:44:17 INFO] Session ID d03d0207-ffb0-4617-adad-733dc1036219 [2020-11-26 13:44:17 INFO] Level Name: Bedrock level [2020-11-26 13:44:17 INFO] Game mode: 0 Survival [2020-11-26 13:44:17 INFO] Difficulty: 1 EASY [INFO] opening worlds/Bedrock level/db [INFO] IPv4 supported, port: 19132 [INFO] IPv6 not supported [INFO] IPv4 supported, port: 59031 [INFO] IPv6 not supported [INFO] Server started.

Starting Bedrock server... NO LOG FILE! - setting up server logging... [2020-11-26 13:44:17 INFO] Starting Server [2020-11-26 13:44:17 INFO] Version 1.16.101.1 [2020-11-26 13:44:17 INFO] Session ID cc78b276-442f-4c94-b61f-a9bb81a8b947 [2020-11-26 13:44:17 INFO] Level Name: Bedrock level [2020-11-26 13:44:17 INFO] Game mode: 1 Creative [2020-11-26 13:44:17 INFO] Difficulty: 0 PEACEFUL [INFO] opening worlds/Bedrock level/db [INFO] IPv4 supported, port: 19134 [INFO] IPv6 not supported [INFO] IPv4 supported, port: 19132 [INFO] IPv6 not supported [INFO] Server started.

But for some reason the server always logs "IPv4 supported" twice, with different ports... the second one appears to be random. However, running "docker ps" gives me this:

5 minutes ago Up 5 minutes (healthy) 0.0.0.0:19132->19132/udp minecraft-survival 5 minutes ago Up 5 minutes (healthy) 19132/udp, 0.0.0.0:19134->19134/udp minecraft-creative

The fact that 'minecraft-creative' mentions port 19132 in its mappings seems wrong... any idea why that is happening?

Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/itzg/docker-minecraft-bedrock-server/issues/110, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABLBAKJIWOPTCMIBT3LXYN3SRZMNTANCNFSM4UDYJKPA .

-- Patrick Double "Ye must be born again." - John 3:7

double16 avatar Nov 26 '20 14:11 double16

This is a popular problem :) Check out https://github.com/itzg/docker-minecraft-bedrock-server/issues/52, which points to https://github.com/itzg/docker-minecraft-bedrock-server/issues/28, for some ideas.

itzg avatar Nov 26 '20 15:11 itzg

@double16 Thanks, you give me hope! However, I have tried various macvlan configurations and have had no luck. I ended up finding people with similar issues saying it had to do with the network adapter not being in promiscuous mode. I tried enabling that, but I'm running Ubuntu 20.04 in a VM under VMWare ESXi, and that may be the reason it's not working for me. I tried enabling promiscuous mode in the virtual switch/portgroup, but that isn't a long term solution for performance reasons, and it didn't work anyway. I then figured the simplest thing would be to just give the VM two NICs... and bind each Minecraft instance to a different IP. Despite that working perfectly for other containers (e.g. I could switch my smokeping container from one IP to the other successfully), this did not work for my minecraft containers.

@itzg Thanks Geoff, I have unfortunately already read both of those threads and tried many different configurations. I feel like there's something suspicious here, and I'm wondering if it can somehow be a clue to why this is so difficult:

5 minutes ago  Up 5 minutes (healthy)  0.0.0.0:19132->19132/udp                 minecraft-survival
5 minutes ago  Up 5 minutes (healthy)  19132/udp, 0.0.0.0:19134->19134/udp      minecraft-creative

Why would the 'minecraft-creative' container mention port 19132 in its "docker ps" output, when it's configured like this:

       - SERVER_PORT=19134
       - SERVER_PORT_V6=19135
     ports:
       - '19134:19134/udp'

Inside the container, it should be running on 19134 (and I've configured the v6 port to 19135 just to ensure it's not somehow the problem). Outside the container, the same port is being mapped. There should be no mention of 19132 for this container, correct? Yet the logs for the container show this:

 [INFO] opening worlds/Bedrock level/db
 [INFO] IPv4 supported, port: 19134
 [INFO] IPv6 not supported
 [INFO] IPv4 supported, port: 19132
 [INFO] IPv6 not supported
 [INFO] Server started.

Are those logs coming from your container, or from the minecraft server itself? Any idea why there are two "Pv4 supported" logs, one for the correct port, and one for the incorrect port?

In fact, if I change my compose file so that neither container uses port 19132 at all:

  minecraft-survival:
      - SERVER_PORT=19133
      - SERVER_PORT_V6=19134
      - '19133:19133/udp'

  minecraft-creative:
      - SERVER_PORT=19135
      - SERVER_PORT_V6=19136
      - '19135:19135/udp'

This is what I see from "docker ps":

Up About a minute (healthy)   19132/udp, 0.0.0.0:19133->19133/udp  minecraft-survival
Up About a minute (healthy)   19132/udp, 0.0.0.0:19135->19135/udp  minecraft-creative

Where is that 19132 coming from?

If you have time, I'd really appreciate it if you could try and reproduce my results and try and find an explanation.

Thanks,

Andy

illiteratealliterator avatar Nov 26 '20 23:11 illiteratealliterator

@itzg Update on this... I found this line in the Dockerfile:

EXPOSE 19132/udp

I removed that and rebuilt the image, and that appears to have solved the 'docker ps' mystery. I can now revert to just using a port mapping and leave the minecraft servers internally on the default ports.

Up 8 minutes (healthy)   0.0.0.0:60150->19132/udp   minecraft-survival
Up 8 minutes (healthy)   0.0.0.0:60160->19132/udp   minecraft-creative

The iOS client will not find these servers automatically via LAN games, but I can now add both these servers manually to the iOS client under 'Servers' and join them successfully by hitting the 'Join Server' button. After adding them to the servers list, they sometimes appear under the 'Friends' list (LAN games), but you can not successfully join them from there.

It looks if you set any SERVER_PORT other than the default of 19132, the server will open 19132 anyway, likely for discovery. However, with multiple instances this seems to cause issues when trying to join a server (even manually). Blocking this by removing the 'EXPOSE' command from the Dockerfile seems to fix this issue (but breaks discovery).

I found this bug report discussing the issue: https://bugs.mojang.com/browse/BDS-1094

Andy

illiteratealliterator avatar Nov 27 '20 00:11 illiteratealliterator

Oops, apparently I clicked the close button instead of just commenting. Ah yes, you found what I was going explain about the container's baked in declaration of 19132. That particular aspect could be ignored, but then if the bedrock server itself is weird about it then that's a different issue..as you found.

As for the "Friends" tab where it does LAN server discovery, the client is sending out a packet to the multicast IP address (typically the *.255 address on your subnet), as I could confirm using sudo tcpdump -i eno1 -v udp port 19132:

Client multicast packet

01:49:26.436845 IP (tos 0x0, ttl 64, id 24499, offset 0, flags [none], proto UDP (17), length 61)
    Geoffs-iPhone.59912 > 192.168.50.255.19132: UDP, length 33

Server response:

01:54:00.152670 IP (tos 0x0, ttl 64, id 19524, offset 0, flags [DF], proto UDP (17), length 161)
    nuc.19132 > Geoffs-iPhone.51862: UDP, length 133

Since it is using multicast, I suspect that makes the multi-homing a little bit more complicated to support all the way.

After getting the two containers running, you may need to visually trace through sudo iptables -vL output to narrow down what Docker is attempting to do to wire up the two containers.`

Sorry, I don't have any definitive information so far, but hopefully some of these bits will at least with help with some more google searching.

itzg avatar Nov 27 '20 02:11 itzg

Can you share your understanding of what the EXPOSE command does? If I'm reading the docs correctly, it seems like it should have no effect unless you use "docker run" with the -P option. It only seems to appear in the "docker ps" output if you use a non-standard SERVER_PORT on the internal minecraft server. I have no idea why that would be, but I'm thinking it's probably a red herring.

I did a test with a single minecraft container on a non-standard internal port, but standard external port:

      - SERVER_PORT=60500
    ports:
      - '19132:60500/udp'

I see the multicast packets coming from the client, I see the response to the client, and the server appears on iOS. However, when I try and join the server, it fails to connect. Again, not sure why that would be, but I don't think it really matters... I shouldn't need to run the internal server on anything other than the default port.

If I change the above example to run internally on 19132, the iOS client connects without problem.

I haven't had any luck getting macvlan to work, I assume because of my network/vm setup... so I may just have to continue running the second server in a separate VM (which is what I've been trying to get rid of).

illiteratealliterator avatar Nov 27 '20 04:11 illiteratealliterator

Can you share your understanding of what the EXPOSE command does? If I'm reading the docs correctly, it seems like it should have no effect unless you use "docker run" with the -P option. It only seems to appear in the "docker ps" output if you use a non-standard SERVER_PORT on the internal minecraft server. I have no idea why that would be, but I'm thinking it's probably a red herring.

Yes, your understanding of EXPOSE is correct and you can ignore that.

itzg avatar Nov 27 '20 17:11 itzg

The bit I wasn't understanding was why 19132 was appearing in the "docker ps" output if it was meant to have no effect without using the -P option to docker run. Turns out that's not quite correct. I found this in the docker-compose docs:

As with docker run, options specified in the Dockerfile, such as CMD, EXPOSE, VOLUME, ENV, are respected by default - you don’t need to specify them again in docker-compose.yml.

Then further down:

Expose ports without publishing them to the host machine - they’ll only be accessible to linked services.

I was missing the detail that there's a difference between 'exposing' a port, and 'publishing an exposed port'. The "docker ps" command shows both of these states on the same line:

PORTS
19132/udp, 0.0.0.0:60601->60601/udp

Using 'docker inspect' shows the difference:

            "Ports": {
                "19132/udp": null,
                "60601/udp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "60601"
                    }
                ]
            },

Ideally, using the SERVER_PORT env var would somehow update or remove the EXPOSE directive, just to avoid this confusion. But I don't know enough about docker to know if that's even possible (the EXPOSE is in the Dockerfile, so I guess that means it's baked into the image?).

Anyway, it's definitely not causing a problem. I have an idea of how to solve my multiple servers issue, will try it when I have some more time.

illiteratealliterator avatar Nov 29 '20 01:11 illiteratealliterator

I've put together a proof of concept of the idea I had. It's basically a separate container that listens for a Minecraft client ping on 19132 and responds with multiple pongs from a set of registered Minecraft servers. Might help others that can't run macvlan or multiple nics in their VMs. Any chance you could test it for me and let me know if it works for you? I've never made an image (or even a github repo) before, so it's highly likely I've messed something up! :)

https://github.com/illiteratealliterator/manymine

illiteratealliterator avatar Nov 29 '20 09:11 illiteratealliterator

@illiteratealliterator I haven't tested it out, but reading through your code, etc everything looks great.

In your example compose file though, I'm curious why you needed to set SERVER_PORT different for each and publish ports for each since your manymine container seems to work as a proxy to each backend container?

itzg avatar Nov 29 '20 16:11 itzg

The Minecraft client sends out a broadcast ping on 19132, and the pong that the servers send in response contains a 'ServerName' string that looks like this:

MCPE;Creative Test;419;1.16.101;0;10;11049514815015922850;Bedrock level;Creative;1;60601;65535;

This pong is the only thing my code acts as a proxy for - it's this packet that is used to update the list of LAN games shown in the 'Friends' tab. The Minecraft client pulls the server's port from this string, and it's that port which is used when you join the game. When you set a SERVER_PORT other than 19132, the Minecraft server also starts 19132 to use for this purpose:

 [INFO] opening worlds/Bedrock level/db
 [INFO] IPv4 supported, port: 19134
 [INFO] IPv6 not supported
 [INFO] IPv4 supported, port: 19132
 [INFO] IPv6 not supported
 [INFO] Server started.

So you still need to have your Minecraft servers available to your clients, mapped on whatever port you like (e.g. 60601). Currently with my code, you also need to set SERVER PORT to that same port number, because I'm simply proxying that ServerName string back to the client. I may add some code to remove that requirement by editing the port listed in that string, so you could leave your servers on the default port internally, and just use the port mapping to move them to another port:

    ports:
      - '60601:19132/udp'

illiteratealliterator avatar Nov 29 '20 21:11 illiteratealliterator

Oh, your manymine doesn't fully proxy the client connections, just the discovery/broadcast ping? That now makes sense why the port exposing and SERVER_PORT setting.

itzg avatar Nov 30 '20 13:11 itzg

Yes, thankfully the Minecraft clients don't have a problem with two different pongs being returned from the same IP, and they correctly read the ports to use from each packet. I'll clean it up and document it a bit when I get some more time.

illiteratealliterator avatar Dec 01 '20 01:12 illiteratealliterator

@illiteratealliterator I cloned your repo, built the docker image, & tested your docker-compose file and can confirm that I was able to connect to both worlds from MCPE on my phone. Your app would allow me to quit having to use the macvlan and taking up multiple IPs on my home network.

claflico avatar Dec 05 '20 03:12 claflico

Thank you @illiteratealliterator!! and thank you @itzg!! Been trying to set this up for my son and me, but being just knowledgeable enough to be dangerous, rather than good with docker and coding this was a life saver. Thanks again.

echofire26 avatar Jun 28 '21 14:06 echofire26