Add script for creating backups

This commit is contained in:
2025-03-28 14:39:49 +00:00
parent 19def3ae12
commit 10b337d20a
5 changed files with 123 additions and 10 deletions

3
.gitignore vendored
View File

@@ -27,3 +27,6 @@
!/fabric/data/config/worldedit/schematics !/fabric/data/config/worldedit/schematics
!/fabric/data/config/worldedit/schematics/.keep !/fabric/data/config/worldedit/schematics/.keep
# Backups
/backups/**
!/backups/.keep

View File

@@ -25,10 +25,10 @@ Follow these steps to set up and configure the project:
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 `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 . 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**| |**Environment Variable**|**Description**|
|---|---| |---|---|
|`UID`|The user 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.|
|`GID`|The group 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`.| |`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.| |`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.| |`FORWARDING_SECRET`|A secret key for forwarding data between services or to the proxy. This should be a secure password.|

0
backups/.keep Executable file
View File

View File

@@ -2,7 +2,7 @@ services:
velocity: velocity:
image: itzg/mc-proxy:java21-2025.1.0 image: itzg/mc-proxy:java21-2025.1.0
container_name: illegal_crime_velocity container_name: illegal_crime_velocity
user: "${UID}:${GID}" user: "${PUID}:${PGID}"
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
fabric: fabric:
@@ -82,8 +82,8 @@ services:
- ./paper/plugins:/plugins:ro - ./paper/plugins:/plugins:ro
- ./schematics:/data/plugins/WorldEdit/schematics:rw - ./schematics:/data/plugins/WorldEdit/schematics:rw
environment: environment:
UID: "${UID}" UID: "${PUID}"
GID: "${GID}" GID: "${PGID}"
EULA: true EULA: true
TYPE: PAPER TYPE: PAPER
@@ -166,8 +166,8 @@ services:
- ./fabric/config:/config:ro - ./fabric/config:/config:ro
- ./schematics:/data/config/worldedit/schematics:rw - ./schematics:/data/config/worldedit/schematics:rw
environment: environment:
UID: "${UID}" UID: "${PUID}"
GID: "${GID}" GID: "${PGID}"
EULA: true EULA: true
TYPE: FABRIC TYPE: FABRIC
@@ -250,7 +250,7 @@ services:
luckperms_db: luckperms_db:
image: postgres:17.4 image: postgres:17.4
container_name: illegal_crime_luckperms_db container_name: illegal_crime_luckperms_db
user: "${UID}:${GID}" user: "${PUID}:${PGID}"
restart: unless-stopped restart: unless-stopped
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U luckperms -d luckperms"] test: ["CMD-SHELL", "pg_isready -U luckperms -d luckperms"]
@@ -268,6 +268,7 @@ services:
volumes: volumes:
- /etc/passwd:/etc/passwd:ro - /etc/passwd:/etc/passwd:ro
- ./luckperms/data:/var/lib/postgresql/data:rw - ./luckperms/data:/var/lib/postgresql/data:rw
- ./backups:/backups:rw
environment: environment:
POSTGRES_PASSWORD_FILE: /run/secrets/luckperms_db_password POSTGRES_PASSWORD_FILE: /run/secrets/luckperms_db_password
POSTGRES_USER: luckperms POSTGRES_USER: luckperms

109
scripts/run_backup.sh Executable file
View File

@@ -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"