ci/woodpecker/tag/release Pipeline was successful Details
ci/woodpecker/push/lint Pipeline was successful Details
ci/woodpecker/push/clippy Pipeline was successful Details
ci/woodpecker/push/build Pipeline was successful Details
Alex is a wrapper around a typical Minecraft server process. It acts as the parent process, and sits in between the user's input and the server's stdin. This allows Alex to support additional commands that execute Rust code, notably creating periodic backups.
Alex is distributed as statically compiled binaries for Linux amd64 and arm64. These can be found here.
Arch users can install prebuilt
aarch64 packages from my
repository. Add the following at the bottom of your
Server = https://arch.r8r.be/$repo/$arch
SigLevel = Optional
If you prefer building the package yourself, the PKGBUILD can be found here.
You can easily install alex in your Docker images by letting Docker download it for you. Add the following to your Dockerfile (replace with your required version & architecture):
ADD "https://git.rustybever.be/api/packages/Chewing_Bever/generic/alex/0.2.2/alex-linux-amd64" /bin/alex
The primary usecase for this is backups. A common problem I've had with
Minecraft backups is that they fail, because the server is writing to one of
the region files as the backup is being created. Alex solves this be sending
save-all to the server, before creating the tarball.
Afterwards, saving is enabled again with
- Create safe backups as gzip-compressed tarballs using the
- Automatically create backups periodically
- Properly configures the process (working directory, optimisation flags)
- Configure everything as CLI arguments or environment variables
Most information can be retrieved easily by looking at the help command:
Wrapper around Minecraft server processes, designed to complement Docker image installations.
Usage: alex [OPTIONS] <COMMAND>
run Run the server
backup Interact with the backup system without starting a server
help Print this message or the help of the given subcommand(s)
Directory where configs are stored, and where the server will run [env: ALEX_CONFIG_DIR=] [default: .]
Directory where world files will be saved [env: ALEX_WORLD_DIR=] [default: ../worlds]
Directory where backups will be stored [env: ALEX_BACKUP_DIR=] [default: ../backups]
What backup layers to employ, provided as a list of tuples name,frequency,chains,chain_len delimited by semicolons (;) [env: ALEX_LAYERS=]
Type of server [env: ALEX_SERVER=] [default: unknown] [possible values: unknown, paper, forge, vanilla]
Version string for the server, e.g. 1.19.4-545 [env: ALEX_SERVER_VERSION=] [default: ]
Choosing layer parameters
One part of the configuration that does require some clarification is the layer system. Alex can manage an arbitrary number of backup layers, each having its own configuration. These layers can either use incremental or full backups, depending on how they're configured.
These layers mostly correspond to the grandfather-father-son backup rotation scheme. For example, one could have a layer that creates incremental backups every 30 minutes, which are stored for 24 hours. This gives you 24 hours of granular rollback in case your server suffers a crash. A second layer might create a full backup every 24 hours, with backups being stored for 7 days. This gives you 7 days worth of backups with the granularity of 24 hours. This approach allows for greater versatility, while not having to store a large amount of data. Thanks to incremental backups, frequent backups don't have to take long at all.
A layer consists of 4 pieces of metadata:
- A name, which will be used in the file system and the in-game notifications
- The frequency, which describes in minutes how frequently a backup should be created
- How many chains should be kept at all times
- How long each chain should be
These last two require some clarification. In Alex, a "chain" describes an initial full backup and zero or more incremental backups that are created from that initial full backup. This concept exists because an incremental backup has no real meaning if its ancestors are not known. To restore one of these chains, all backups in the chain need to be restored in-order. Note that a chain length of 1 disables incremental backups entirely.
How many backups to keep is defined by how many chains should be stored. Because an incremental backup needs to have its ancestors in order to be restored, we can't simply "keep the last n backups", as this would break these chains. Therefore, you configure how many backups to store using these chains.
For example, if you configure a layer to store 5 chains of length 4, you will
have 20 archive files on disk, namely 5 full backups and 15 incremental
backups. Note that Alex applies these rules to full chains. An in-progress
chain does not count towards this total. Therefore, you can have up to
additional archive files, with
n being the chain length, on disk.
To look at it from another perspective, say we wish to have a granularity of 30 minutes for a timespan of 24 hours. Then we could configure the layer to only save a single chain, with a chain length of 48. If we prefer to have a few full backups instead of a long chain of incremental backups, we could instead use a chain length of 12 and store 4 chains. Either way, the total comes out to 48, which spans 24 hours if we make a backup every 30 minutes.