Running a server

Restarting the server when a plugin asks

On this page

A plugin can ask the server to restart, for example a gamemode with wipes at the end of a season. The server cannot start itself again. What it does is stop exactly as /stop does, with every plugin told the server is stopping and then stopped, and the world and everybody in it saved, and then end with exit code 75 instead of 0. Whatever started the server reads that code and starts it again.

Exit codeMeaningWhat to do
0Stopped (/stop, Ctrl+C, the management API).Stay stopped.
75A plugin asked for a restart; everything was saved.Start it again.
1, 2Refused to start: a bad rustmc.yml, an unknown generator, a world that could not be made.Read the log; starting again will fail the same way.
anything elseIt crashed.Your choice; a loop that restarts on everything hides crashes.

When a plugin asks, the console logs RESTART: plugin <name> asked for the server to restart (...) with the plugin's reason. Everybody online is disconnected with that reason ("the server is restarting" if it gave none), each saved as they leave. The stop waits up to five seconds for them to go, then saves whoever is still there. A second request while a restart is under way is ignored.

A start script

Two start scripts in the tools folder of the rustmc repository, run-with-restarts.sh (Linux, macOS, Git Bash) and run-with-restarts.ps1 (Windows), run the server and start it again, after a two-second pause for the port to be let go of, whenever it ends with 75, and only then:

tools/run-with-restarts.sh ./rustmc-server --survival
powershell -File tools\run-with-restarts.ps1 .\rustmc-server.exe --survival

Both pass their arguments to the server unchanged, and end with the server's own exit code when it ends with anything other than 75.

Under systemd

No script is needed. RestartForceExitStatus restarts on exactly that code, and a normal stop (code 0) stays stopped:

[Service]
ExecStart=/opt/rustmc/rustmc-server --survival
WorkingDirectory=/opt/rustmc
Restart=no
RestartForceExitStatus=75
SuccessExitStatus=75

In Docker

restart: unless-stopped restarts after any exit, including a deliberate /stop. To restart only when a plugin asked, run the start script as the container's command instead.

A world reset on the next start

A plugin can also ask for the world to be made fresh on the next start. That is off by default, and refused unless you allow it in rustmc.yml:

world-reset:
  allow-plugins: true

The default is false. With it off, a plugin's request is refused, and a reset asked for earlier is left undone, with the console saying so at every start.

A request is the file rustmc-reset-requested.json in the world's folder, and the console says when one is made. Delete the file to take the reset back; the plugin can also take it back itself.

On the next start, before the world opens, the world's folder is renamed to <world>-reset-<yyyymmdd>-<hhmmss> beside it (with -2, -3 and so on if that name is taken). Nothing is deleted. A fresh world is then made from server.properties with the seed the plugin named, or a random one, never level-seed, which would make the same world again. The generator is whichever rustmc.yml chooses. The console prints where the old world is kept and the new seed.

The renamed folder keeps everything that was in the world: builds, player files, the Nether and the End, and the request itself, renamed with .done on the end. Delete it when you are sure. On a server started with a world path, the server's own files and plugin data are kept in the world's folder, so they move aside with it.

If the folder cannot be renamed, the world opens as it is and the reset is tried again at the next start. A server started with --no-generate does not reset.

From docs/restarting.md in the RustMC repository at bbd81209ad.