2023-06-13 11:51:18 +02:00
|
|
|
# Alex
|
2021-09-13 12:02:06 +02:00
|
|
|
|
2023-06-13 11:51:18 +02:00
|
|
|
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.
|
2023-06-24 12:16:53 +02:00
|
|
|
This allows Alex to support additional commands that execute Rust code, notably
|
|
|
|
creating periodic backups.
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
Alex is distributed as statically compiled binaries for Linux amd64 and arm64.
|
|
|
|
These can be found
|
|
|
|
[here](https://git.rustybever.be/Chewing_Bever/alex/packages).
|
|
|
|
|
|
|
|
### Dockerfiles
|
|
|
|
|
|
|
|
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):
|
|
|
|
|
|
|
|
```dockerfile
|
|
|
|
ADD "https://git.rustybever.be/api/packages/Chewing_Bever/generic/alex/0.2.2/alex-linux-amd64" /bin/alex
|
|
|
|
```
|
2023-06-13 11:51:18 +02:00
|
|
|
|
|
|
|
## Why
|
|
|
|
|
|
|
|
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-off` and `save-all` to the server, before creating the tarball.
|
|
|
|
Afterwards, saving is enabled again with `save-on`.
|
|
|
|
|
|
|
|
## Features
|
|
|
|
|
|
|
|
* Create safe backups as gzip-compressed tarballs using the `backup` command
|
|
|
|
* Automatically create backups periodically
|
|
|
|
* Properly configures the process (working directory, optimisation flags)
|
|
|
|
* Configure everything as CLI arguments or environment variables
|
|
|
|
|
2023-06-24 12:16:53 +02:00
|
|
|
## Configuration
|
2023-06-13 11:51:18 +02:00
|
|
|
|
2023-06-24 12:16:53 +02:00
|
|
|
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>
|
|
|
|
|
|
|
|
Commands:
|
|
|
|
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)
|
|
|
|
|
|
|
|
Options:
|
|
|
|
--config <CONFIG_DIR>
|
|
|
|
Directory where configs are stored, and where the server will run [env: ALEX_CONFIG_DIR=] [default: .]
|
|
|
|
--world <WORLD_DIR>
|
|
|
|
Directory where world files will be saved [env: ALEX_WORLD_DIR=] [default: ../worlds]
|
|
|
|
--backup <BACKUP_DIR>
|
|
|
|
Directory where backups will be stored [env: ALEX_BACKUP_DIR=] [default: ../backups]
|
|
|
|
--layers <LAYERS>
|
|
|
|
What backup layers to employ, provided as a list of tuples name,frequency,chains,chain_len delimited by semicolons (;) [env: ALEX_LAYERS=]
|
|
|
|
--server <SERVER>
|
|
|
|
Type of server [env: ALEX_SERVER=] [default: unknown] [possible values: unknown, paper, forge, vanilla]
|
|
|
|
--server-version <SERVER_VERSION>
|
|
|
|
Version string for the server, e.g. 1.19.4-545 [env: ALEX_SERVER_VERSION=] [default: ]
|
|
|
|
-h, --help
|
|
|
|
Print help
|
|
|
|
-V, --version
|
|
|
|
Print version
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
### 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 `n-1`
|
|
|
|
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.
|