Skip to content

Commit 612fb24

Browse files
authored
Wire optional graceful announce-before-stop into the entrypoint (#651)
1 parent c4d868e commit 612fb24

3 files changed

Lines changed: 45 additions & 1 deletion

File tree

Dockerfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ VOLUME ["/data"]
1818

1919
WORKDIR /data
2020

21-
ENTRYPOINT ["/usr/local/bin/entrypoint-demoter", "--match", "/data", "--debug", "--stdin-on-term", "stop", "/opt/bedrock-entry.sh"]
21+
# demoter-entry.sh execs into entrypoint-demoter (PID 1). By default it builds the
22+
# same args as before (--match /data --debug --stdin-on-term stop /opt/bedrock-entry.sh);
23+
# set STOP_SERVER_ANNOUNCE_DELAY to opt into a graceful announce-then-wait before stop.
24+
ENTRYPOINT ["/opt/demoter-entry.sh"]
2225

2326
ARG APPS_REV=1
2427
ARG GITHUB_BASEURL=https://github.com

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ For Minecraft Java Edition you'll need to use this image instead:
7474
- `MC_PACK` (no default): Path inside the container to a single archive file (e.g. `.mcpack`, `.mcworld`, `.mctemplate`, `.mcaddon`, or any zip) or to a directory with the same layout. At startup the archive is unpacked (or the directory is read): top-level `behavior_packs/` is merged into `behavior_packs/`, top-level `resource_packs/` into `resource_packs/`, and all other content (when `level.dat` is present) into `worlds/{LEVEL_NAME}`. For `.mcaddon` archives, which use root-level `data/` (behavior) and `resources/` (resource) folders instead of `behavior_packs/` and `resource_packs/`, these are detected and installed automatically using the pack UUID from each manifest as the folder name.
7575
- `FORCE_WORLD_COPY` (default `false`): When `MC_PACK` contains a world (`level.dat`), set to `true` to remove and replace the existing `worlds/{LEVEL_NAME}` on every startup; otherwise the world is copied only when it does not exist.
7676
- `FORCE_PACK_COPY` (default `false`): When `MC_PACK` contains `behavior_packs/` or `resource_packs/`, set to `true` to remove and replace existing pack folders with the same name on every startup; otherwise each pack is copied only when it does not already exist.
77+
- `STOP_SERVER_ANNOUNCE_DELAY` (no default — disabled): opt into a graceful shutdown announcement. When set to a positive whole number of seconds, a heads-up line is written to the server console on container stop (`SIGTERM`); after that many seconds the server is sent `stop` (the usual clean-save shutdown). Unset or `0` keeps the previous behavior of stopping immediately. A second `SIGTERM` skips the remaining wait. Keep the value shorter than the container's stop grace period (e.g. `docker stop -t`, ECS `stopTimeout`, or an EC2 Spot interruption's ~2‑minute window) so the world save isn't cut short by `SIGKILL`.
78+
- `STOP_SERVER_ANNOUNCE` (default `say Server shutting down in %delay% seconds`): the console line written as the announcement when `STOP_SERVER_ANNOUNCE_DELAY` is active. The `%delay%` token is replaced with the delay's whole-second value. Any server command works (e.g. a `say` or `tellraw`).
7779

7880

7981
### Server Properties

demoter-entry.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
set -eo pipefail
4+
5+
# Entrypoint wrapper that launches entrypoint-demoter (as PID 1) for the Bedrock
6+
# server, optionally enabling a graceful "announce, wait, then stop" on SIGTERM.
7+
#
8+
# Why a wrapper: entrypoint-demoter is PID 1 and handles SIGTERM by writing the
9+
# --stdin-on-term message ("stop") to the server's stdin (the save-clean path).
10+
# To also warn players first, its v0.5.0 --stdin-on-term-announce / -delay flags
11+
# must be present on the command line *before* the process starts, so we build the
12+
# argument list here from the environment and exec into it.
13+
#
14+
# Default behaviour is UNCHANGED: with no env set, SIGTERM still sends "stop"
15+
# immediately (same args as the previous static ENTRYPOINT).
16+
#
17+
# Opt-in graceful shutdown:
18+
# STOP_SERVER_ANNOUNCE_DELAY Whole seconds to wait between the announce and the
19+
# stop. Unset or 0 => disabled (immediate stop).
20+
# Keep it shorter than the container's stop grace
21+
# period (docker `stop -t` / ECS stopTimeout / a Spot
22+
# interruption's 2-minute window) so the world save
23+
# isn't cut short by SIGKILL.
24+
# STOP_SERVER_ANNOUNCE Console line written as the heads-up. The %delay%
25+
# token is replaced by entrypoint-demoter with the
26+
# whole-second value of the delay.
27+
# Default: "say Server shutting down in %delay% seconds"
28+
29+
demoterArgs=(--match /data --debug)
30+
31+
delay="${STOP_SERVER_ANNOUNCE_DELAY:-0}"
32+
if [[ "${delay}" =~ ^[0-9]+$ ]] && (( delay > 0 )); then
33+
announce="${STOP_SERVER_ANNOUNCE:-say Server shutting down in %delay% seconds}"
34+
demoterArgs+=(--stdin-on-term-announce "${announce}" --stdin-on-term-delay "${delay}s")
35+
fi
36+
37+
demoterArgs+=(--stdin-on-term stop)
38+
39+
exec /usr/local/bin/entrypoint-demoter "${demoterArgs[@]}" /opt/bedrock-entry.sh

0 commit comments

Comments
 (0)