Update backup script
This commit is contained in:
31
README.md
31
README.md
@@ -7,43 +7,43 @@ The configuration files for the Illegal Crime Minecraft server.
|
|||||||
Follow these steps to set up and configure the project:
|
Follow these steps to set up and configure the project:
|
||||||
|
|
||||||
1. **Clone the repository**:
|
1. **Clone the repository**:
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://gitea.leaf.home.kappeh.org/Homelab/minecraft_server.git
|
git clone https://gitea.leaf.home.kappeh.org/Homelab/minecraft_server.git
|
||||||
cd minecraft_server
|
cd minecraft_server
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Create required directories**: See [Directory Setup](#directory-setup) for details.
|
2. **Create required directories**: See [Directory Setup](#directory-setup) for details.
|
||||||
|
|
||||||
3. **Set up environment variables**: See [Environment Variables](#environment-variables) for details.
|
3. **Set up environment variables**: See [Environment Variables](#environment-variables) for details.
|
||||||
|
|
||||||
4. **Import world files**:
|
4. **Import world files**:
|
||||||
|
|
||||||
The world for the Fabric server is located at `fabric/data/world`. If you want to use an existing world, copy it to this location before running the container:
|
The world for the Fabric server is located at `fabric/data/world`. If you want to use an existing world, copy it to this location before running the container:
|
||||||
|
|
||||||
```
|
```
|
||||||
cp path/to/world fabric/data/world
|
cp path/to/world fabric/data/world
|
||||||
```
|
```
|
||||||
|
|
||||||
5. **Adjust permissions (recommended)**: Run the following commands in the root of the repository, replacing `PUID` and `PGID` with the corresponding values from your `.env` file:
|
5. **Adjust permissions (recommended)**: Run the following commands in the root of the repository, replacing `PUID` and `PGID` with the corresponding values from your `.env` file:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo chown -R PUID:PGID .
|
sudo chown -R PUID:PGID .
|
||||||
sudo chmod -R 770 .
|
sudo chmod -R 770 .
|
||||||
```
|
```
|
||||||
|
|
||||||
6. **Start the Docker Compose stack**: To start the services in detached mode, run:
|
6. **Start the Docker Compose stack**: To start the services in detached mode, run:
|
||||||
|
|
||||||
```
|
```
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
7. **Stop the Docker Compose stack**: To stop and remove the running containers, use:
|
7. **Stop the Docker Compose stack**: To stop and remove the running containers, use:
|
||||||
|
|
||||||
```
|
```
|
||||||
docker compose down
|
docker compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
## Directory Setup
|
## Directory Setup
|
||||||
|
|
||||||
Make a directory called `schematics` in the root of the repository. This directory is used for storing [WorldEdit](https://worldedit.org/) schematic files. To create it, run:
|
Make a directory called `schematics` in the root of the repository. This directory is used for storing [WorldEdit](https://worldedit.org/) schematic files. To create it, run:
|
||||||
@@ -73,12 +73,11 @@ Then, open `.env` in a text editor and set appropriate values for your setup.
|
|||||||
|`DCLINK_CHANNEL`|The Discord channel ID where the bot will operate. See [dclink](#dclink) for more information.|
|
|`DCLINK_CHANNEL`|The Discord channel ID where the bot will operate. See [dclink](#dclink) for more information.|
|
||||||
|`DCLINK_ROLE`|The ID of the role that the bot will give to Discord members when they link their accounts. See [dclink](#dclink) for more information.|
|
|`DCLINK_ROLE`|The ID of the role that the bot will give to Discord members when they link their accounts. See [dclink](#dclink) for more information.|
|
||||||
|`DCLINK_TOKEN`|The bot token used for authentication with Discord's API. Ensure this is kept secret and secure.|
|
|`DCLINK_TOKEN`|The bot token used for authentication with Discord's API. Ensure this is kept secret and secure.|
|
||||||
|`LUCKPERMS_DB_PASSWORD`|The password for the LuckPerms database. This should be a secure password.|
|
|`LUCKPERMS_PASSWORD`|The password for the LuckPerms database. This should be a secure password.|
|
||||||
|
|
||||||
Instead of using environment variables, the secrets section of `docker-compose.yml` can be modified to read files instead. This method will likely be used by default in future.
|
Instead of using environment variables, the secrets section of `docker-compose.yml` can be modified to read files instead. This method will likely be used by default in future.
|
||||||
|
|
||||||
## dclink
|
## dclink
|
||||||
This configuration uses [dclink](https://github.com/Kalimero2Team/dclink) to link users' Minecraft accounts and Discord accounts. This is so that a user can gain access to the Minecraft server if they are a member of the configured Discord server.
|
This configuration uses [dclink](https://github.com/Kalimero2Team/dclink) to link users' Minecraft accounts and Discord accounts. This is so that a user can gain access to the Minecraft server if they are a member of the configured Discord server.
|
||||||
|
|
||||||
For this to work you must first [setup a discord bot](https://github.com/Kalimero2Team/dclink/wiki/Setup-Discord-Bot). Then set the relevant [Environment Variables](#environment-variables).
|
For this to work you must first [setup a discord bot](https://github.com/Kalimero2Team/dclink/wiki/Setup-Discord-Bot). Then set the relevant [Environment Variables](#environment-variables).
|
||||||
|
|
||||||
|
|||||||
72
compose.yml
72
compose.yml
@@ -5,9 +5,10 @@ services:
|
|||||||
user: 2015:2015 # minecraft_server:minecraft_server
|
user: 2015:2015 # minecraft_server:minecraft_server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
init_volumes:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
luckperms_db:
|
restart: true
|
||||||
|
luckperms:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
restart: true
|
restart: true
|
||||||
fabric:
|
fabric:
|
||||||
@@ -20,7 +21,7 @@ services:
|
|||||||
- rcon_password
|
- rcon_password
|
||||||
- forwarding_secret
|
- forwarding_secret
|
||||||
- dclink_token
|
- dclink_token
|
||||||
- luckperms_db_password
|
- luckperms_password
|
||||||
networks:
|
networks:
|
||||||
minecraft_server_network:
|
minecraft_server_network:
|
||||||
ipv4_address: "10.100.1.3"
|
ipv4_address: "10.100.1.3"
|
||||||
@@ -48,7 +49,7 @@ services:
|
|||||||
CFG_DCLINK_CHANNEL: ${DCLINK_CHANNEL}
|
CFG_DCLINK_CHANNEL: ${DCLINK_CHANNEL}
|
||||||
CFG_DCLINK_ROLE: ${DCLINK_ROLE}
|
CFG_DCLINK_ROLE: ${DCLINK_ROLE}
|
||||||
CFG_DCLINK_TOKEN_FILE: /run/secrets/dclink_token
|
CFG_DCLINK_TOKEN_FILE: /run/secrets/dclink_token
|
||||||
CFG_LUCKPERMS_DB_PASSWORD_FILE: /run/secrets/luckperms_db_password
|
CFG_LUCKPERMS_PASSWORD_FILE: /run/secrets/luckperms_password
|
||||||
|
|
||||||
PLUGINS: |
|
PLUGINS: |
|
||||||
https://github.com/dbkynd-minecraft/VelocityPlayerList/releases/download/v1.0/PlayerList-1.0.jar
|
https://github.com/dbkynd-minecraft/VelocityPlayerList/releases/download/v1.0/PlayerList-1.0.jar
|
||||||
@@ -65,8 +66,9 @@ services:
|
|||||||
user: 2015:2015 # minecraft_server:minecraft_server
|
user: 2015:2015 # minecraft_server:minecraft_server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
init_volumes:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
|
restart: true
|
||||||
fabric:
|
fabric:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
restart: true
|
restart: true
|
||||||
@@ -90,9 +92,10 @@ services:
|
|||||||
container_name: minecraft_server_paper
|
container_name: minecraft_server_paper
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
init_volumes:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
luckperms_db:
|
restart: true
|
||||||
|
luckperms:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
restart: true
|
restart: true
|
||||||
healthcheck:
|
healthcheck:
|
||||||
@@ -103,7 +106,7 @@ services:
|
|||||||
secrets:
|
secrets:
|
||||||
- rcon_password
|
- rcon_password
|
||||||
- forwarding_secret
|
- forwarding_secret
|
||||||
- luckperms_db_password
|
- luckperms_password
|
||||||
networks:
|
networks:
|
||||||
minecraft_server_network:
|
minecraft_server_network:
|
||||||
ipv4_address: "10.100.1.4"
|
ipv4_address: "10.100.1.4"
|
||||||
@@ -166,7 +169,7 @@ services:
|
|||||||
|
|
||||||
CFG_RCON_PASSWORD_FILE: /run/secrets/rcon_password
|
CFG_RCON_PASSWORD_FILE: /run/secrets/rcon_password
|
||||||
CFG_FORWARDING_SECRET_FILE: /run/secrets/forwarding_secret
|
CFG_FORWARDING_SECRET_FILE: /run/secrets/forwarding_secret
|
||||||
CFG_LUCKPERMS_DB_PASSWORD_FILE: /run/secrets/luckperms_db_password
|
CFG_LUCKPERMS_PASSWORD_FILE: /run/secrets/luckperms_password
|
||||||
|
|
||||||
PLUGINS: |
|
PLUGINS: |
|
||||||
https://github.com/EssentialsX/Essentials/releases/download/2.20.1/EssentialsX-2.20.1.jar
|
https://github.com/EssentialsX/Essentials/releases/download/2.20.1/EssentialsX-2.20.1.jar
|
||||||
@@ -189,9 +192,10 @@ services:
|
|||||||
container_name: minecraft_server_fabric
|
container_name: minecraft_server_fabric
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
init_volumes:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
luckperms_db:
|
restart: true
|
||||||
|
luckperms:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
restart: true
|
restart: true
|
||||||
healthcheck:
|
healthcheck:
|
||||||
@@ -202,7 +206,7 @@ services:
|
|||||||
secrets:
|
secrets:
|
||||||
- rcon_password
|
- rcon_password
|
||||||
- forwarding_secret
|
- forwarding_secret
|
||||||
- luckperms_db_password
|
- luckperms_password
|
||||||
networks:
|
networks:
|
||||||
minecraft_server_network:
|
minecraft_server_network:
|
||||||
ipv4_address: "10.100.1.5"
|
ipv4_address: "10.100.1.5"
|
||||||
@@ -260,7 +264,7 @@ services:
|
|||||||
|
|
||||||
CFG_RCON_PASSWORD_FILE: /run/secrets/rcon_password
|
CFG_RCON_PASSWORD_FILE: /run/secrets/rcon_password
|
||||||
CFG_FORWARDING_SECRET_FILE: /run/secrets/forwarding_secret
|
CFG_FORWARDING_SECRET_FILE: /run/secrets/forwarding_secret
|
||||||
CFG_LUCKPERMS_DB_PASSWORD_FILE: /run/secrets/luckperms_db_password
|
CFG_LUCKPERMS_PASSWORD_FILE: /run/secrets/luckperms_password
|
||||||
|
|
||||||
MODRINTH_PROJECTS: |
|
MODRINTH_PROJECTS: |
|
||||||
badpackets:hjhT2sMz
|
badpackets:hjhT2sMz
|
||||||
@@ -298,14 +302,15 @@ services:
|
|||||||
vanilla-permissions:7awQNHzw
|
vanilla-permissions:7awQNHzw
|
||||||
worldedit:3TQ8W0Ar
|
worldedit:3TQ8W0Ar
|
||||||
|
|
||||||
luckperms_db:
|
luckperms:
|
||||||
image: postgres:17.4
|
image: postgres:17.4
|
||||||
container_name: minecraft_server_luckperms_db
|
container_name: minecraft_server_luckperms
|
||||||
user: 2015:2015 # minecraft_server:minecraft_server
|
user: 2015:2015 # minecraft_server:minecraft_server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
init_volumes:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
|
restart: true
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U luckperms -d luckperms"]
|
test: ["CMD-SHELL", "pg_isready -U luckperms -d luckperms"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
@@ -313,7 +318,7 @@ services:
|
|||||||
start_period: 30s
|
start_period: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
secrets:
|
secrets:
|
||||||
- luckperms_db_password
|
- luckperms_password
|
||||||
networks:
|
networks:
|
||||||
minecraft_server_network:
|
minecraft_server_network:
|
||||||
ipv4_address: "10.100.1.2"
|
ipv4_address: "10.100.1.2"
|
||||||
@@ -321,23 +326,35 @@ services:
|
|||||||
- ${LUCKPERMS_PORT}:5432
|
- ${LUCKPERMS_PORT}:5432
|
||||||
volumes:
|
volumes:
|
||||||
- luckperms_data:/var/lib/postgresql/data:rw
|
- luckperms_data:/var/lib/postgresql/data:rw
|
||||||
|
- backups:/backups:rw
|
||||||
- /etc/passwd:/etc/passwd:ro
|
- /etc/passwd:/etc/passwd:ro
|
||||||
# - ./backups:/backups:rw
|
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD_FILE: /run/secrets/luckperms_db_password
|
POSTGRES_PASSWORD_FILE: /run/secrets/luckperms_password
|
||||||
POSTGRES_USER: luckperms
|
POSTGRES_USER: luckperms
|
||||||
POSTGRES_DB: luckperms
|
POSTGRES_DB: luckperms
|
||||||
PGDATA: /var/lib/postgresql/data/pgdata
|
PGDATA: /var/lib/postgresql/data/pgdata
|
||||||
|
|
||||||
init_volumes:
|
# Helper for dumping sqlite databases during backups
|
||||||
container_name: minecraft_server_init_volumes
|
sqlite_helper:
|
||||||
image: busybox:1.37.0
|
container_name: minecraft_server_sqlite_helper
|
||||||
user: root:root
|
image: grepular/sqlite3:3.51.2
|
||||||
command: /init_volumes.sh
|
user: 0:0
|
||||||
restart: no
|
restart: no
|
||||||
network_mode: none
|
network_mode: none
|
||||||
volumes:
|
volumes:
|
||||||
- ./scripts/init_volumes.sh:/init_volumes.sh:ro
|
- backups:/backups:rw
|
||||||
|
- velocity_data:/velocity_data:ro
|
||||||
|
|
||||||
|
init:
|
||||||
|
container_name: minecraft_server_init
|
||||||
|
image: busybox:1.37.0
|
||||||
|
user: root:root
|
||||||
|
command: /init.sh
|
||||||
|
restart: no
|
||||||
|
network_mode: none
|
||||||
|
volumes:
|
||||||
|
- ./scripts/init.sh:/init.sh:ro
|
||||||
|
- backups:/backups:rw
|
||||||
# Used for resolving user and group names within the init script
|
# Used for resolving user and group names within the init script
|
||||||
- /etc/passwd:/etc/passwd:ro
|
- /etc/passwd:/etc/passwd:ro
|
||||||
- /etc/group:/etc/group:ro
|
- /etc/group:/etc/group:ro
|
||||||
@@ -368,8 +385,8 @@ secrets:
|
|||||||
environment: FORWARDING_SECRET
|
environment: FORWARDING_SECRET
|
||||||
dclink_token:
|
dclink_token:
|
||||||
environment: DCLINK_TOKEN
|
environment: DCLINK_TOKEN
|
||||||
luckperms_db_password:
|
luckperms_password:
|
||||||
environment: LUCKPERMS_DB_PASSWORD
|
environment: LUCKPERMS_PASSWORD
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
velocity_data:
|
velocity_data:
|
||||||
@@ -380,3 +397,4 @@ volumes:
|
|||||||
paper_data:
|
paper_data:
|
||||||
fabric_data:
|
fabric_data:
|
||||||
luckperms_data:
|
luckperms_data:
|
||||||
|
backups:
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ data {
|
|||||||
|
|
||||||
# Credentials for the database.
|
# Credentials for the database.
|
||||||
username = "luckperms"
|
username = "luckperms"
|
||||||
password = "${CFG_LUCKPERMS_DB_PASSWORD}"
|
password = "${CFG_LUCKPERMS_PASSWORD}"
|
||||||
|
|
||||||
# These settings apply to the MySQL connection pool.
|
# These settings apply to the MySQL connection pool.
|
||||||
# - The default values will be suitable for the majority of users.
|
# - The default values will be suitable for the majority of users.
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ data:
|
|||||||
|
|
||||||
# Credentials for the database.
|
# Credentials for the database.
|
||||||
username: luckperms
|
username: luckperms
|
||||||
password: '${CFG_LUCKPERMS_DB_PASSWORD}'
|
password: '${CFG_LUCKPERMS_PASSWORD}'
|
||||||
|
|
||||||
# These settings apply to the MySQL connection pool.
|
# These settings apply to the MySQL connection pool.
|
||||||
# - The default values will be suitable for the majority of users.
|
# - The default values will be suitable for the majority of users.
|
||||||
|
|||||||
273
scripts/backup.sh
Executable file
273
scripts/backup.sh
Executable file
@@ -0,0 +1,273 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Adjustable parameters
|
||||||
|
## The number of backups to keep
|
||||||
|
BACKUPS_KEEP=24
|
||||||
|
|
||||||
|
# Global variables (Do NOT change)
|
||||||
|
CLEANUP_FABRIC=false
|
||||||
|
CLEANUP_LUCKPERMS=false
|
||||||
|
CLEANUP_PAPER=false
|
||||||
|
|
||||||
|
main() {
|
||||||
|
log_info "=== Backup run started at $(date -u '+%Y-%m-%dT%H:%M:%SZ') ==="
|
||||||
|
log_info "Keeping last $BACKUPS_KEEP backups"
|
||||||
|
|
||||||
|
check_root_permissions
|
||||||
|
init_backup
|
||||||
|
|
||||||
|
broadcast_status started
|
||||||
|
|
||||||
|
backup_bluemap || cleanup_failure
|
||||||
|
backup_fabric || cleanup_failure
|
||||||
|
backup_luckperms || cleanup_failure
|
||||||
|
backup_paper || cleanup_failure
|
||||||
|
backup_schematics || cleanup_failure
|
||||||
|
backup_velocity || cleanup_failure
|
||||||
|
|
||||||
|
finalize_backup || cleanup_failure
|
||||||
|
prune_backups
|
||||||
|
cleanup_success
|
||||||
|
|
||||||
|
broadcast_status finished
|
||||||
|
|
||||||
|
log_info "=== Backup run completed successfully at $(date -u '+%Y-%m-%dT%H:%M:%SZ') ==="
|
||||||
|
}
|
||||||
|
|
||||||
|
check_root_permissions() {
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
log_error "This script must be run by the root user"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Running as root (EUID=$EUID)"
|
||||||
|
}
|
||||||
|
|
||||||
|
init_backup() {
|
||||||
|
BACKUP_ID="$(date -u +%Y-%m-%dT%H-%M-%SZ)"
|
||||||
|
BACKUP_DIR="/backups/$BACKUP_ID"
|
||||||
|
|
||||||
|
log_info "Creating backup directory: $BACKUP_DIR"
|
||||||
|
|
||||||
|
docker compose run --rm init sh -c '
|
||||||
|
mkdir -p "$1" &&
|
||||||
|
chown minecraft_server:minecraft_server "$1"
|
||||||
|
' -- "$BACKUP_DIR" || {
|
||||||
|
log_error "Failed to create backup directory $BACKUP_DIR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info "Backup directory created and ownership set"
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcast_status() {
|
||||||
|
STATUS="$1"
|
||||||
|
log_info "Broadcasting backup status: $STATUS"
|
||||||
|
|
||||||
|
if docker compose exec -T fabric true > /dev/null 2>&1; then
|
||||||
|
docker compose exec -T fabric rcon-cli "tellraw @a [{\"text\":\"Server\",\"color\":\"light_purple\"},{\"text\":\": Backup $STATUS.\",\"color\":\"white\"}]" > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
if docker compose exec -T paper true > /dev/null 2>&1; then
|
||||||
|
docker compose exec -T paper rcon-cli "tellraw @a [{\"text\":\"Server\",\"color\":\"light_purple\"},{\"text\":\": Backup $STATUS.\",\"color\":\"white\"}]" > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_bluemap() {
|
||||||
|
log_info "Starting Bluemap backup..."
|
||||||
|
|
||||||
|
docker compose run --rm init sh -c '
|
||||||
|
cp -a --reflink=auto /bluemap_data "$1" &&
|
||||||
|
cp -a --reflink=auto /bluemap_maps "$1" &&
|
||||||
|
cp -a --reflink=auto /bluemap_web "$1"
|
||||||
|
' -- "$BACKUP_DIR" || return 1
|
||||||
|
|
||||||
|
log_info "Finished Bluemap backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_fabric() {
|
||||||
|
log_info "Starting Fabric backup..."
|
||||||
|
|
||||||
|
CLEANUP_FABRIC=false
|
||||||
|
if docker compose exec -T fabric true > /dev/null 2>&1; then
|
||||||
|
CLEANUP_FABRIC=true
|
||||||
|
log_info "Fabric server detected, disabling saves"
|
||||||
|
|
||||||
|
docker compose exec -T fabric rcon-cli save-off > /dev/null 2>&1
|
||||||
|
docker compose exec -T fabric rcon-cli save-all > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker compose run --rm init sh -c '
|
||||||
|
mkdir -p "$1"/fabric_data &&
|
||||||
|
cp -a --reflink=auto /fabric_data/g4mespeed "$1"/fabric_data &&
|
||||||
|
cp -a --reflink=auto /fabric_data/fabric-essentials.json "$1"/fabric_data &&
|
||||||
|
cp -a --reflink=auto /fabric_data/world "$1"/fabric_data
|
||||||
|
' -- "$BACKUP_DIR" || return 1
|
||||||
|
|
||||||
|
log_info "Finished Fabric backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_luckperms() {
|
||||||
|
log_info "Starting LuckPerms backup..."
|
||||||
|
|
||||||
|
CLEANUP_LUCKPERMS=false
|
||||||
|
if ! docker compose exec -T luckperms true > /dev/null 2>&1; then
|
||||||
|
CLEANUP_LUCKPERMS=true
|
||||||
|
log_info "LuckPerms not running, starting temporary container"
|
||||||
|
|
||||||
|
docker compose up --wait luckperms > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker compose exec luckperms sh -c '
|
||||||
|
pg_dump -U luckperms luckperms > "$1"/luckperms.sql
|
||||||
|
' -- "$BACKUP_DIR" || return 1
|
||||||
|
|
||||||
|
log_info "Finished LuckPerms backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_paper() {
|
||||||
|
log_info "Starting Paper backup..."
|
||||||
|
|
||||||
|
CLEANUP_PAPER=false
|
||||||
|
if docker compose exec -T paper true > /dev/null 2>&1; then
|
||||||
|
CLEANUP_PAPER=true
|
||||||
|
log_info "Paper server detected, disabling saves"
|
||||||
|
|
||||||
|
docker compose exec -T paper rcon-cli save-off > /dev/null 2>&1
|
||||||
|
docker compose exec -T paper rcon-cli save-all > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker compose run --rm init sh -c '
|
||||||
|
mkdir -p "$1"/paper_data/plugins &&
|
||||||
|
cp -a --reflink=auto /paper_data/plugins/Multiverse-Inventories "$1"/paper_data/plugins &&
|
||||||
|
cp -a --reflink=auto /paper_data/plugins/Essentials "$1"/paper_data/plugins &&
|
||||||
|
cp -a --reflink=auto /paper_data/plugins/PlotSquared "$1"/paper_data/plugins &&
|
||||||
|
cp -a --reflink=auto /paper_data/creative "$1"/paper_data &&
|
||||||
|
cp -a --reflink=auto /paper_data/creative_nether "$1"/paper_data &&
|
||||||
|
cp -a --reflink=auto /paper_data/survival "$1"/paper_data &&
|
||||||
|
cp -a --reflink=auto /paper_data/survival_nether "$1"/paper_data &&
|
||||||
|
cp -a --reflink=auto /paper_data/survival_the_end "$1"/paper_data
|
||||||
|
' -- "$BACKUP_DIR" || return 1
|
||||||
|
|
||||||
|
log_info "Finished Paper backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_schematics() {
|
||||||
|
log_info "Starting schematics backup..."
|
||||||
|
|
||||||
|
docker compose run --rm init sh -c '
|
||||||
|
cp -a --reflink=auto /schematics "$1"
|
||||||
|
' -- "$BACKUP_DIR" || return 1
|
||||||
|
|
||||||
|
log_info "Finished schematics backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_velocity() {
|
||||||
|
log_info "Starting Velocity backup..."
|
||||||
|
|
||||||
|
docker compose run --rm init sh -c 'mkdir -p "$1"/velocity_data/plugins/dclink-velocity' -- "$BACKUP_DIR" || return 1
|
||||||
|
|
||||||
|
docker compose run --rm sqlite_helper \
|
||||||
|
/velocity_data/plugins/dclink-velocity/dclink.db \
|
||||||
|
".backup $BACKUP_DIR/velocity_data/plugins/dclink-velocity/dclink.db" || return 1
|
||||||
|
|
||||||
|
log_info "Finished Velocity backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize_backup() {
|
||||||
|
log_info "Finalizing backup $BACKUP_ID"
|
||||||
|
|
||||||
|
docker compose run --rm init chown -R minecraft_server:minecraft_server "$BACKUP_DIR" || {
|
||||||
|
log_error "Failed to update ownership of backup files"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info "Backup ownership updated"
|
||||||
|
|
||||||
|
docker compose run --rm init sh -c '
|
||||||
|
ln -sfn "$1" /backups/.latest_tmp &&
|
||||||
|
mv -Tf /backups/.latest_tmp /backups/latest
|
||||||
|
' -- "$BACKUP_DIR" || {
|
||||||
|
log_error "Failed to update /backups/latest symlink"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info "Updated /backups/latest symlink"
|
||||||
|
}
|
||||||
|
|
||||||
|
prune_backups() {
|
||||||
|
BACKUPS_ALL=$(docker compose run --rm init sh -c '
|
||||||
|
find /backups -mindepth 1 -maxdepth 1 -type d \
|
||||||
|
-name "????-??-??T??-??-??Z" | sort
|
||||||
|
')
|
||||||
|
|
||||||
|
BACKUPS_TOTAL=$(echo "$BACKUPS_ALL" | wc -l)
|
||||||
|
BACKUPS_PRUNE=$((BACKUPS_TOTAL - BACKUPS_KEEP))
|
||||||
|
|
||||||
|
[ "$BACKUPS_PRUNE" -le 0 ] && BACKUPS_PRUNE=0
|
||||||
|
|
||||||
|
log_info "Total backups found: $BACKUPS_TOTAL"
|
||||||
|
log_info "Backups to prune: $BACKUPS_PRUNE"
|
||||||
|
|
||||||
|
echo "$BACKUPS_ALL" | head -n "$BACKUPS_PRUNE" | while read -r OLD_BACKUP_DIR; do
|
||||||
|
log_info "Removing old backup: $OLD_BACKUP_DIR"
|
||||||
|
docker compose run --rm init rm -rf "$OLD_BACKUP_DIR"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup_trap HUP INT QUIT ABRT TERM
|
||||||
|
cleanup_trap() {
|
||||||
|
log_info "Backup cancelled by signal"
|
||||||
|
broadcast_status cancelled
|
||||||
|
cleanup
|
||||||
|
delete_backup
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_failure() {
|
||||||
|
log_info "Running cleanup due to failure"
|
||||||
|
broadcast_status failed
|
||||||
|
cleanup
|
||||||
|
delete_backup
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_success() {
|
||||||
|
log_info "Running cleanup"
|
||||||
|
cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
# Ignore specified conditions to ensure cleanup runs to completion uninterrupted
|
||||||
|
trap '' HUP INT QUIT ABRT TERM
|
||||||
|
|
||||||
|
if [ "$CLEANUP_FABRIC" = true ]; then
|
||||||
|
log_info "Re-enabling Fabric saves"
|
||||||
|
docker compose exec -T fabric rcon-cli save-on > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CLEANUP_LUCKPERMS" = true ]; then
|
||||||
|
log_info "Bringing down temporary LuckPerms container"
|
||||||
|
docker compose stop luckperms > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CLEANUP_PAPER" = true ]; then
|
||||||
|
log_info "Re-enabling Paper saves"
|
||||||
|
docker compose exec -T paper rcon-cli save-on > /dev/null 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_backup() {
|
||||||
|
if ! docker compose run --rm init rm -rf "$BACKUP_DIR"; then
|
||||||
|
log_error "Failed to remove $BACKUP_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info() {
|
||||||
|
echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] INFO: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] ERROR: $*" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
45
scripts/init.sh
Executable file
45
scripts/init.sh
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Define a helper function that runs a command
|
||||||
|
# If the command fails, the script prints an error message
|
||||||
|
# and exits immediately.
|
||||||
|
run() {
|
||||||
|
# "$@" expands to all arguments passed to this function
|
||||||
|
# and preserves proper word splitting and quoting.
|
||||||
|
"$@" || {
|
||||||
|
echo "Error: command failed: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make sure volumes have correct permissions
|
||||||
|
run chown minecraft_server:minecraft_server /bluemap_data
|
||||||
|
run chown minecraft_server:minecraft_server /bluemap_web
|
||||||
|
run chown minecraft_server:minecraft_server /bluemap_maps
|
||||||
|
run chown minecraft_server:minecraft_server /fabric_data
|
||||||
|
run chown minecraft_server:minecraft_server /luckperms_data
|
||||||
|
run chown minecraft_server:minecraft_server /paper_data
|
||||||
|
run chown minecraft_server:minecraft_server /schematics
|
||||||
|
run chown minecraft_server:minecraft_server /velocity_data
|
||||||
|
|
||||||
|
# Make sure nested volume mount points exist
|
||||||
|
run mkdir -p /fabric_data/bluemap/web/maps
|
||||||
|
run chown minecraft_server:minecraft_server /fabric_data/bluemap
|
||||||
|
run chown minecraft_server:minecraft_server /fabric_data/bluemap/web
|
||||||
|
run chown minecraft_server:minecraft_server /fabric_data/bluemap/web/maps
|
||||||
|
|
||||||
|
run mkdir -p /fabric_data/config/worldedit/schematics
|
||||||
|
run chown minecraft_server:minecraft_server /fabric_data/config
|
||||||
|
run chown minecraft_server:minecraft_server /fabric_data/config/worldedit
|
||||||
|
run chown minecraft_server:minecraft_server /fabric_data/config/worldedit/schematics
|
||||||
|
|
||||||
|
run mkdir -p /paper_data/bluemap/web/maps
|
||||||
|
run chown minecraft_server:minecraft_server /paper_data/bluemap
|
||||||
|
run chown minecraft_server:minecraft_server /paper_data/bluemap/web
|
||||||
|
run chown minecraft_server:minecraft_server /paper_data/bluemap/web/maps
|
||||||
|
|
||||||
|
run mkdir -p /paper_data/plugins/WorldEdit/schematics
|
||||||
|
run chown minecraft_server:minecraft_server /paper_data/plugins
|
||||||
|
run chown minecraft_server:minecraft_server /paper_data/plugins/WorldEdit
|
||||||
|
run chown minecraft_server:minecraft_server /paper_data/plugins/WorldEdit/schematics
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
# Define a helper function that runs a command
|
|
||||||
# If the command fails, the script prints an error message
|
|
||||||
# and exits immediately.
|
|
||||||
run() {
|
|
||||||
# "$@" expands to all arguments passed to this function
|
|
||||||
# and preserves proper word splitting and quoting.
|
|
||||||
"$@" || {
|
|
||||||
echo "Error: command failed: $*" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ensure required directories exist
|
|
||||||
run mkdir -p /fabric_data/bluemap/web/maps
|
|
||||||
run mkdir -p /fabric_data/config/worldedit/schematics
|
|
||||||
run mkdir -p /paper_data/bluemap/web/maps
|
|
||||||
run mkdir -p /paper_data/plugins/WorldEdit/schematics
|
|
||||||
|
|
||||||
# Ensure correct permissions of docker volumes
|
|
||||||
run chown -R minecraft_server:minecraft_server /bluemap_data
|
|
||||||
run chown -R minecraft_server:minecraft_server /bluemap_web
|
|
||||||
run chown -R minecraft_server:minecraft_server /bluemap_maps
|
|
||||||
run chown -R minecraft_server:minecraft_server /fabric_data
|
|
||||||
run chown -R minecraft_server:minecraft_server /luckperms_data
|
|
||||||
run chown -R minecraft_server:minecraft_server /paper_data
|
|
||||||
run chown -R minecraft_server:minecraft_server /schematics
|
|
||||||
run chown -R minecraft_server:minecraft_server /velocity_data
|
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ docker exec illegal_crime_paper rcon-cli save-all
|
|||||||
PG_USER="luckperms"
|
PG_USER="luckperms"
|
||||||
PG_DB="luckperms"
|
PG_DB="luckperms"
|
||||||
BACKUP_DIR_CONTAINER="/backups/$DATE"
|
BACKUP_DIR_CONTAINER="/backups/$DATE"
|
||||||
docker exec illegal_crime_luckperms_db pg_dump -U "$PG_USER" -F c -b -v -f "$BACKUP_DIR_CONTAINER/luckperms.sql" "$PG_DB"
|
docker exec illegal_crime_luckperms pg_dump -U "$PG_USER" -F c -b -v -f "$BACKUP_DIR_CONTAINER/luckperms.sql" "$PG_DB"
|
||||||
|
|
||||||
# Copy WorldEdit schematics
|
# Copy WorldEdit schematics
|
||||||
cp -r "$PROJECT_DIR/schematics" "$BACKUP_DIR_HOST/"
|
cp -r "$PROJECT_DIR/schematics" "$BACKUP_DIR_HOST/"
|
||||||
@@ -109,4 +109,3 @@ fi
|
|||||||
# Update permissions of backed up files
|
# Update permissions of backed up files
|
||||||
chown -R "$PUID:$PGID" "$BACKUPS_DIR_HOST"
|
chown -R "$PUID:$PGID" "$BACKUPS_DIR_HOST"
|
||||||
chmod -R 770 "$BACKUPS_DIR_HOST"
|
chmod -R 770 "$BACKUPS_DIR_HOST"
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,5 @@ DCLINK_GUILD=${CFG_DCLINK_GUILD}
|
|||||||
DCLINK_CHANNEL=${CFG_DCLINK_CHANNEL}
|
DCLINK_CHANNEL=${CFG_DCLINK_CHANNEL}
|
||||||
DCLINK_ROLE=${CFG_DCLINK_ROLE}
|
DCLINK_ROLE=${CFG_DCLINK_ROLE}
|
||||||
DCLINK_TOKEN=${CFG_DCLINK_TOKEN}
|
DCLINK_TOKEN=${CFG_DCLINK_TOKEN}
|
||||||
LUCKPERMS_DB_PASSWORD=${CFG_LUCKPERMS_DB_PASSWORD}
|
LUCKPERMS_PASSWORD=${CFG_LUCKPERMS_PASSWORD}
|
||||||
LUCKPERMS_PORT=${CFG_LUCKPERMS_PORT}
|
LUCKPERMS_PORT=${CFG_LUCKPERMS_PORT}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ data:
|
|||||||
|
|
||||||
# Credentials for the database.
|
# Credentials for the database.
|
||||||
username: luckperms
|
username: luckperms
|
||||||
password: '${CFG_LUCKPERMS_DB_PASSWORD}'
|
password: '${CFG_LUCKPERMS_PASSWORD}'
|
||||||
|
|
||||||
# These settings apply to the MySQL connection pool.
|
# These settings apply to the MySQL connection pool.
|
||||||
# - The default values will be suitable for the majority of users.
|
# - The default values will be suitable for the majority of users.
|
||||||
|
|||||||
Reference in New Issue
Block a user