Skip to content
This repository has been archived by the owner on Dec 3, 2023. It is now read-only.

Commit

Permalink
Stop the server gracefully when SIGTERM is sent (as docker stop does)
Browse files Browse the repository at this point in the history
`docker stop` sends the `SIGTERM` signal to the process to stop it, but the
Minecraft server process handles this by quitting immediately, not saving the
world first. This differs from when the `stop` Minecraft command is used, as
that will save the world first before quitting.

This change adds a script (`start.sh`) which catches the `SIGTERM` signal and
handles it by sending the `stop` command to the Minecraft server. As a bonus,
`sendcommand` is now able to send commands to the server directly (by using a
named pipe) rather than using RCON.
  • Loading branch information
t9t committed Apr 29, 2017
1 parent b8af7bb commit ee8195f
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 15 deletions.
12 changes: 7 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ RUN mkdir /mc

ADD https://s3.amazonaws.com/Minecraft.Download/versions/${minecraft_version}/minecraft_server.${minecraft_version}.jar /mc/minecraft_server.jar
ADD "https://search.maven.org/remotecontent?filepath=com/github/t9t/minecraft-rcon-client/minecraft-rcon-client/${rcon_client_version}/minecraft-rcon-client-${rcon_client_version}.jar" /mc/minecraft-rcon-client.jar
ADD sendcommand.sh /mc/sendcommand.sh
RUN ln -s /mc/sendcommand.sh /usr/local/bin/sendcommand

WORKDIR /world
ADD rcon.sh sendcommand.sh start.sh /mc/

EXPOSE 25565
RUN ln -s /mc/sendcommand.sh /usr/local/bin/sendcommand
RUN ln -s /mc/rcon.sh /usr/local/bin/rcon

CMD java -Xms${JAVA_MIN_MEMORY} -Xmx${JAVA_MAX_MEMORY} -jar /mc/minecraft_server.jar nogui
WORKDIR /world
VOLUME /world
EXPOSE 25565 25575

CMD /mc/start.sh
41 changes: 34 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,55 @@
- Source: https://github.com/t9t/minecraft-server-docker-image
- Report issues: https://github.com/t9t/minecraft-server-docker-image/issues

This image uses a volume to store the Minecraft world data, which also contains configuration files such as `server.properties`, `banned-ips.json`, `banned-players.json`, `ops.json`, and `whitelist.json`.
This image uses a volume to store the Minecraft world data, which also contains configuration files such as
`server.properties`, `banned-ips.json`, `banned-players.json`, `ops.json`, and `whitelist.json`.

# Start an instance
To start an instance, use something like the following:

```
docker run -d --name minecraft-server -v /var/lib/minecraft/world/:/world -p 25565:25565 t9t9t/minecraft-server
docker run \
--init --detach \
--name=minecraft-server \
--publish=25565:25565 \
--restart=on-failure:5 \
--stop-timeout=30 \
--volume=/var/lib/minecraft/world/:/world \
t9t9t/minecraft-server
```


This will use the directory `/var/lib/minecraft/world` as the world directory.

If it does not contain a valid `eula.txt` yet, the server will be shut down immediately. Make sure you agree to the [EULA](https://account.mojang.com/documents/minecraft_eula), then add `eula=true` to `eula.txt`.
If it does not contain a valid `eula.txt` yet, the server will be shut down immediately. Make sure you agree to the
[EULA](https://account.mojang.com/documents/minecraft_eula), then add `eula=true` to `eula.txt`.

If it does not contain a `server.properties`, the server will create a default one. It is recommended that you tweak all
settings though.

If it does not contain a `server.properties`, the server will create a default one. It is recommended that you tweak all settings though.
You can configure the Java minimum and maximum memory usage using the environment variables `JAVA_MIN_MEMORY` and
`JAVA_MAX_MEMORY` environment variables respectively. The defaults are `128M` and `2048M` respectively.

# Sending commands

To send commands to the server, first ensure that the RCON console is enabled (by adding `enable-rcon=true` to `server.properties` and setting `rcon.password` to some password). Then use the following command:
To send commands to the server, use the `sendcommand` script:

```
docker exec minecraft-server sendcommand 'say Teleporting skankhunt42 to (0,200,0)'
docker exec minecraft-server sendcommand teleport skankhunt42 0 200 0
```

Note that any output will be sent to the standard output of the Minecraft server, which will end up in the docker logs
and the Minecraft logs in `logs` directory.

Alternatively, you may enable RCON (by adding `enable-rcon=true` to `server.properties` and setting `rcon.password`
to some password), and use the `rcon` command:

```
docker exec minecraft-server sendcommand rconpassword 'say Teleporting skankhunt42 to (0,200,0)' 'teleport skankhunt42 0 200 0'
```

This assumes that the RCON port is set to the default of `25575` (you may of course expose it using any other port by using the `-p` option of `docker run`).
Quotes are mandatory in this case, because the `rcon` can accept multiple commands. This will return the output to the
standard output of `docker exec`.

This assumes that the RCON port is set to the default of `25575` (you may of course expose it using any other port by
using the `-p` option of `docker run`).
8 changes: 8 additions & 0 deletions rcon.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

if [ $# -lt 2 ]; then
echo "Usage: rcon <password> <commands>"
exit 1
fi

java -jar /mc/minecraft-rcon-client.jar 127.0.0.1:25575 "$@"
6 changes: 3 additions & 3 deletions sendcommand.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/bin/sh

if [ $# -lt 2 ]; then
echo "Usage: sendcommand <password> <commands>"
if [ $# -lt 1 ]; then
echo "Usage: sendcommand <command>"
exit 1
fi

java -jar /mc/minecraft-rcon-client.jar 127.0.0.1:25575 "$@"
echo $* > /minecraft_stdin
26 changes: 26 additions & 0 deletions start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh

_stop_server() {
echo Received SIGTERM, stopping
echo stop > /minecraft_stdin
wait ${JAVA_PID}
exit
}

mkfifo /minecraft_stdin
trap "_stop_server" TERM

cd /world

java -Xms${JAVA_MIN_MEMORY} -Xmx${JAVA_MAX_MEMORY} -jar /mc/minecraft_server.jar nogui < /minecraft_stdin &
JAVA_PID=$!

# See: https://unix.stackexchange.com/questions/72962/getting-stdin-from-a-named-pipe
exec 3> /minecraft_stdin

# See: https://veithen.github.io/2014/11/16/sigterm-propagation.html
wait ${JAVA_PID}
trap - TERM INT
wait ${JAVA_PID}

exec 3>&-

0 comments on commit ee8195f

Please sign in to comment.