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

New /data volume prevents server startup

Open double16 opened this issue 5 years ago • 5 comments

Creating a new container with a new volume, such as when starting the compose stack for the first time, does not start the server. The reason is /data is owned by root. In case of empty /data, ownership should be changed to $UID:$GID before demoting.

double16 avatar Jul 16 '20 18:07 double16

Unlike my java edition server image I really wanted to stay out of the chown'ing business with this image since it always left the source of truth for file ownership somewhat ambiguous: should the volume ownership match the intended (UID) user or should the final user match the volume ownership? If the container itself is started as a non-root user and the intended (UID) user is a different non-root user, can the first user even chown the volume to the latter?

Given that docker and in turn docker-compose doesn't have a way to specify named volume ownership, then I appear to be forced to be forced to support all the permutations :( .

I need to think about this some more...

itzg avatar Jul 16 '20 20:07 itzg

I'm still not sure what was preventing your container from starting up at all since the provided example compose file works fine. Can you provide the compose file you attempted?

In general though I found a workaround that I can add to the README.

You start by pre-creating the named volume with the desired ownership, such as uid=1000, gid=1000:

docker run --rm -v bedrock:/data alpine chown 1000:1000 /data

In the compose file the volume needs to be declared external and referencing that pre-created volume:

version: "3.8"

services:
  bedrock:
    image: itzg/minecraft-bedrock-server
    environment:
      EULA: "TRUE"
    ports:
    - 19132:19132/udp
    volumes:
    - bedrock:/data

volumes:
  bedrock:
    external:
      name: bedrock

With that the server process is demoted to uid=1000,gid=1000 as seen here:

time="2020-07-18T13:54:31Z" level=debug msg="Using /data to match uid and gid"
time="2020-07-18T13:54:31Z" level=debug msg="Resolved UID=1000 from match path"
time="2020-07-18T13:54:31Z" level=debug msg="Resolved GID=1000 from match path"
time="2020-07-18T13:54:31Z" level=debug msg="stdin is detached, so forwarding is disabled"
Downloading Bedrock server version 1.16.1.02 ...
Starting Bedrock server...

itzg avatar Jul 18 '20 13:07 itzg

The example compose file uses root. I've modified the example to specify UID/GID. It fails.

version: '3.4'

services:
  bds:
    image: itzg/minecraft-bedrock-server
    environment:
      EULA: "TRUE"
      GAMEMODE: survival
      DIFFICULTY: normal
      UID: 1000
      GID: 1000
    ports:
      - 19132:19132/udp
    volumes:
      - bds:/data
    stdin_open: true
    tty: true

volumes:
  bds: {}
bds_1  | checkdir error:  cannot create structures
bds_1  |                  Permission denied
bds_1  |                  unable to process structures/bastion/bridge/ramparts/rampart_1.nbt.
bds_1  | checkdir error:  cannot create structures
bds_1  |                  Permission denied
bds_1  |                  unable to process structures/bastion/bridge/ramparts/rampart_0.nbt.
...

It would be nice to start the stack using only the compose file. I was thinking for this case of an empty volume, a chown would be trivial because there isn't data there. Perhaps if $(find /data -type f | wc -l) == 0; then chown $UID:$GID /data; fi, or something like that.

double16 avatar Jul 22 '20 18:07 double16

I agree it would be nice to do it one-shot with the compose file and UID/GID variables; however, the container's user gets "demoted" at entrypoint time:

https://github.com/itzg/docker-minecraft-bedrock-server/blob/891eea45017b51aa206e6cfe99aed4481565f449/Dockerfile#L20

I will need to enhance endtrypoint-demoter to do the chowning, which is quite doable. It's just a level of complexity/confusion I was hoping to avoid when designing this strategy.

itzg avatar Jul 23 '20 00:07 itzg

I have the exact same issue. The container tries to start and in the logs I get:

minecraft    | Starting Bedrock server...
minecraft    | DEBU[0000] Using /data to match uid and gid
minecraft    | DEBU[0000] Resolved UID=1000 from match path
minecraft    | DEBU[0000] Resolved GID=1000 from match path
minecraft    | Starting Bedrock server...
minecraft    | DEBU[0000] Forwarding signal                             signal="child exited"
minecraft    | ERRO[0000] Failed to signal sub-command                  error="os: process already finished"

My compose.yaml file looks like this:

version: '3.7'
services:
  minecraft:
    image: itzg/minecraft-bedrock-server:latest
    container_name: minecraft
    restart: always
    ports:
      - 19132:19132/udp
    volumes:
      - /home/user/docker/minecraft:/data
    environment:
      EULA: "TRUE"
      VERSION: LATEST
      PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    stdin_open: true
    tty: true
    env_file:
      - docker.env

I'm not sure how to adapt the external volume 🤔

TheZoker avatar Aug 06 '20 21:08 TheZoker