From 10b337d20a85f28744434e08a5c43300b0198369 Mon Sep 17 00:00:00 2001 From: Kappeh Date: Fri, 28 Mar 2025 14:39:49 +0000 Subject: [PATCH] Add script for creating backups --- .gitignore | 3 ++ README.md | 8 ++-- backups/.keep | 0 docker-compose.yml | 13 ++--- scripts/run_backup.sh | 109 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 10 deletions(-) create mode 100755 backups/.keep create mode 100755 scripts/run_backup.sh diff --git a/.gitignore b/.gitignore index a44c201..b9c2d66 100755 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ !/fabric/data/config/worldedit/schematics !/fabric/data/config/worldedit/schematics/.keep +# Backups +/backups/** +!/backups/.keep diff --git a/README.md b/README.md index db50606..5c7e32a 100755 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ Follow these steps to set up and configure the project: cp path/to/world fabric/data/world ``` -5. **Adjust permissions (recommended)**: Run the following commands in the root of the repository, replacing `UID` and `GID` 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 UID:GID . + sudo chown -R PUID:PGID . sudo chmod -R 770 . ``` @@ -64,8 +64,8 @@ Then, open `.env` in a text editor and set appropriate values for your setup. |**Environment Variable**|**Description**| |---|---| -|`UID`|The user ID that should be used for file ownership within the project.| -|`GID`|The group ID that should be used for file ownership within the project.| +|`PUID`|The user ID that should be used for file ownership within the project.| +|`PGID`|The group ID that should be used for file ownership within the project.| |`VELOCITY_PORT`|The port number where the Velocity proxy service will listen. Default is set to `25565`.| |`RCON_PASSWORD`|The password for Remote Console (RCON) access. This should be a secure password.| |`FORWARDING_SECRET`|A secret key for forwarding data between services or to the proxy. This should be a secure password.| diff --git a/backups/.keep b/backups/.keep new file mode 100755 index 0000000..e69de29 diff --git a/docker-compose.yml b/docker-compose.yml index c04bb01..36e9b52 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ services: velocity: image: itzg/mc-proxy:java21-2025.1.0 container_name: illegal_crime_velocity - user: "${UID}:${GID}" + user: "${PUID}:${PGID}" restart: unless-stopped depends_on: fabric: @@ -82,8 +82,8 @@ services: - ./paper/plugins:/plugins:ro - ./schematics:/data/plugins/WorldEdit/schematics:rw environment: - UID: "${UID}" - GID: "${GID}" + UID: "${PUID}" + GID: "${PGID}" EULA: true TYPE: PAPER @@ -166,8 +166,8 @@ services: - ./fabric/config:/config:ro - ./schematics:/data/config/worldedit/schematics:rw environment: - UID: "${UID}" - GID: "${GID}" + UID: "${PUID}" + GID: "${PGID}" EULA: true TYPE: FABRIC @@ -250,7 +250,7 @@ services: luckperms_db: image: postgres:17.4 container_name: illegal_crime_luckperms_db - user: "${UID}:${GID}" + user: "${PUID}:${PGID}" restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U luckperms -d luckperms"] @@ -268,6 +268,7 @@ services: volumes: - /etc/passwd:/etc/passwd:ro - ./luckperms/data:/var/lib/postgresql/data:rw + - ./backups:/backups:rw environment: POSTGRES_PASSWORD_FILE: /run/secrets/luckperms_db_password POSTGRES_USER: luckperms diff --git a/scripts/run_backup.sh b/scripts/run_backup.sh new file mode 100755 index 0000000..e7c8426 --- /dev/null +++ b/scripts/run_backup.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +# This script is to be run in the root of the repository + +set -e + +PROJECT_DIR="." +BACKUPS_DIR_HOST="$PROJECT_DIR/backups" +BACKUPS_TO_KEEP=24 + +# Load environment variables from .env file +# Used for PUID and PGID +set -a # automatically export all variables +source "$PROJECT_DIR/.env" +set +a + +# Create backup directory +DATE="$(date +\%Y-\%m-\%d_\%H-\%M-\%S)" +BACKUP_DIR_HOST="$BACKUPS_DIR_HOST/$DATE" + +mkdir -p "$BACKUP_DIR_HOST" +mkdir -p "$BACKUP_DIR_HOST/fabric/data" +mkdir -p "$BACKUP_DIR_HOST/paper/data" +mkdir -p "$BACKUP_DIR_HOST/paper/data/plugins/Multiverse-Core" +mkdir -p "$BACKUP_DIR_HOST/paper/data/plugins/Multiverse-Inventories" +mkdir -p "$BACKUP_DIR_HOST/velocity/data/plugins/dclink-velocity" + +chown -R "$PUID:$PGID" "$BACKUP_DIR_HOST" +chmod -R 770 "$BACKUP_DIR_HOST" + +# Announce backup is starting +docker exec illegal_crime_fabric rcon-cli "tellraw @a [{\"text\":\"Server\",\"color\":\"light_purple\"},{\"text\":\": Backup is starting\",\"color\":\"white\"}]" +docker exec illegal_crime_paper rcon-cli "tellraw @a [{\"text\":\"Server\",\"color\":\"light_purple\"},{\"text\":\": Backup is starting\",\"color\":\"white\"}]" + +# Disable autosaving +docker exec illegal_crime_fabric rcon-cli save-off +docker exec illegal_crime_paper rcon-cli save-off + +# Manually save to ensure recent changes are included in backup +docker exec illegal_crime_fabric rcon-cli save-all +docker exec illegal_crime_paper rcon-cli save-all + +# Dump luckperms database +PG_USER="luckperms" +PG_DB="luckperms" +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" + +# Copy WorldEdit schematics +cp -r "$PROJECT_DIR/schematics" "$BACKUP_DIR_HOST/" + +# Copy dclink database +cp "$PROJECT_DIR/velocity/data/plugins/dclink-velocity/dclink.db" "$BACKUP_DIR_HOST/velocity/data/plugins/dclink-velocity/" + +# Copy Multiverse files +cp -r "$PROJECT_DIR/paper/data/plugins/Multiverse-Core/worlds.yml" "$BACKUP_DIR_HOST/paper/data/plugins/Multiverse-Core/" +cp -r "$PROJECT_DIR/paper/data/plugins/Multiverse-Inventories/groups.yml" "$BACKUP_DIR_HOST/paper/data/plugins/Multiverse-Inventories/" +cp -r "$PROJECT_DIR/paper/data/plugins/Multiverse-Inventories/groups" "$BACKUP_DIR_HOST/paper/data/plugins/Multiverse-Inventories/" +cp -r "$PROJECT_DIR/paper/data/plugins/Multiverse-Inventories/players" "$BACKUP_DIR_HOST/paper/data/plugins/Multiverse-Inventories/" +cp -r "$PROJECT_DIR/paper/data/plugins/Multiverse-Inventories/worlds" "$BACKUP_DIR_HOST/paper/data/plugins/Multiverse-Inventories/" + +# Copy Minecraft worlds +cp -r "$PROJECT_DIR/fabric/data/world" "$BACKUP_DIR_HOST/fabric/data/" +cp -r "$PROJECT_DIR/paper/data/survival" "$BACKUP_DIR_HOST/paper/data/" +cp -r "$PROJECT_DIR/paper/data/survival_nether" "$BACKUP_DIR_HOST/paper/data/" +cp -r "$PROJECT_DIR/paper/data/survival_the_end" "$BACKUP_DIR_HOST/paper/data/" + +# Enable autosaving +docker exec illegal_crime_fabric rcon-cli save-on +docker exec illegal_crime_paper rcon-cli save-on + +# Announce backup is complete +docker exec illegal_crime_fabric rcon-cli "tellraw @a [{\"text\":\"Server\",\"color\":\"light_purple\"},{\"text\":\": Backup is complete\",\"color\":\"white\"}]" +docker exec illegal_crime_paper rcon-cli "tellraw @a [{\"text\":\"Server\",\"color\":\"light_purple\"},{\"text\":\": Backup is complete\",\"color\":\"white\"}]" + +# Create or update symlink pointing to latest backup +mkdir -p "$BACKUPS_DIR_HOST/markers" +LATEST_SYMLINK="$BACKUPS_DIR_HOST/markers/latest" +if [ -L "$LATEST_SYMLINK" ]; then + # Symlink exists. Updating it. + rm "$LATEST_SYMLINK" + ln -s "../$DATE" "$LATEST_SYMLINK" +elif [ -e "$LATEST_SYMLINK" ]; then + # File exists but it's not a symlink. + rm -f "$LATEST_SYMLINK" + ln -s "../$DATE" "$LATEST_SYMLINK" +else + # Symlink does not exists. Creating it. + ln -s "../$DATE" "$LATEST_SYMLINK" +fi + +# Remove old backups +BACKUP_DIRS=$(find "$BACKUPS_DIR_HOST" -mindepth 1 -maxdepth 1 -type d ! -name "markers" | sort) +TOTAL_BACKUPS=$(echo "$BACKUP_DIRS" | wc -l) + +echo "TOTAL_BACKUPS: $TOTAL_BACKUPS, BACKUPS_TO_KEEP: $BACKUPS_TO_KEEP" + +if ((TOTAL_BACKUPS > BACKUPS_TO_KEEP)); then + BACKUPS_TO_REMOVE=$((TOTAL_BACKUPS - BACKUPS_TO_KEEP)) + BACKUPS_TO_DELETE=$(echo "$BACKUP_DIRS" | head -n "$BACKUPS_TO_REMOVE") + for BACKUP in $BACKUPS_TO_DELETE; do + echo "Removing $BACKUP" + rm -r "$BACKUP" + done +fi + +# Update permissions of backed up files +chown -R "$PUID:$PGID" "$BACKUPS_DIR_HOST" +chmod -R 770 "$BACKUPS_DIR_HOST" +