docker-minecraft-bedrock-server
docker-minecraft-bedrock-server copied to clipboard
New /data volume prevents server startup
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.
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...
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...
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.
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.
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 🤔