backup scripts

This commit is contained in:
Mayel de Borniol 2025-04-21 15:17:05 +01:00
parent d52472eb3b
commit 853832355a
4 changed files with 148 additions and 52 deletions

View File

@ -1,4 +1,4 @@
export APP_ENTRYPOINT_VERSION=v1
export PG_BACKUP_VERSION=v2
export MEILI_BACKUP_VERSION=v2
export PG_BACKUP_VERSION=v4
export MEILI_BACKUP_VERSION=v4

View File

@ -9,7 +9,7 @@ services:
- SEARCH_MEILI_INSTANCE=http://${STACK_NAME}_search:7700
search:
image: getmeili/meilisearch:v1.11 # TODO: upgrade to 1.14
image: getmeili/meilisearch:v1.11 # WIP: upgrade from v1.11 to 1.14
secrets:
- meili_master_key
volumes:

131
meili_backup.sh Normal file → Executable file
View File

@ -1,44 +1,107 @@
#!/bin/bash
#!/bin/sh
set -e
BACKUP_FILE='/var/lib/postgresql/data/backup.sql'
backup() {
SECRET=$(cat /run/secrets/meili_master_key)
# Create dump
echo "Creating new Meilisearch dump..."
RESPONSE=$(curl -s -X POST 'http://localhost:7700/dumps' -H "Authorization: Bearer $SECRET")
echo "Response: $RESPONSE"
function backup {
export SECRET=$(cat /run/secrets/meili_master_key)
// pre-hook command for compose.meilisearch.yml
TASK_UID=$(curl -s -X POST 'http://localhost:7700/dumps' -H 'Authorization: Bearer $SECRET' | grep -o '\"uid\":[0-9]*' | cut -d':' -f2) && \
echo "Waiting for dump creation (task $TASK_UID)..." && \
MAX_ATTEMPTS=600 && \
ATTEMPT=0 && \
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do \
TASK_STATUS=$(curl -s "http://localhost:7700/tasks/$TASK_UID" -H "Authorization: Bearer $SECRET" | grep -o '\"status\":\"[^\"]*\"' | cut -d':' -f2 | tr -d '\"'); \
if [ "$TASK_STATUS" = "succeeded" ]; then \
echo "Dump creation succeeded" && \
break; \
elif [ "$TASK_STATUS" = "enqueued" ] || [ "$TASK_STATUS" = "processing" ]; then \
echo "Dump creation in progress... ($TASK_STATUS)" && \
ATTEMPT=$((ATTEMPT+1)) && \
sleep 2; \
else \
echo "Dump creation in unexpected state: $TASK_STATUS" && \
exit 1; \
fi; \
done && \
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then \
echo "Timed out waiting for dump creation" && \
exit 1; \
fi && \
DUMP_UID=$(curl -s "http://localhost:7700/tasks/$TASK_UID" -H "Authorization: Bearer $SECRET" | grep -o '\"dumpUid\":\"[^\"]*\"' | cut -d':' -f2 | tr -d '\"') && \
echo "Using dump $DUMP_UID" && \
cp -f "/meili_dumps/$DUMP_UID.dump" "/meili_dumps/meilisearch_latest.dump" && \
echo "Dump created and copied successfully"
# More robust extraction of task UID
TASK_UID=$(echo "$RESPONSE" | sed -n 's/.*"taskUid":\([0-9]*\).*/\1/p')
if [ -z "$TASK_UID" ]; then
echo "Failed to extract task UID from response. Aborting."
exit 1
fi
echo "Waiting for dump creation (task $TASK_UID)..."
MAX_ATTEMPTS=600
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
RESPONSE=$(curl -s "http://localhost:7700/tasks/$TASK_UID" -H "Authorization: Bearer $SECRET")
echo "Task status response: $RESPONSE"
TASK_STATUS=$(echo "$RESPONSE" | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
if [ -z "$TASK_STATUS" ]; then
echo "Failed to extract task status. Retrying..."
ATTEMPT=$((ATTEMPT+1))
sleep 5
continue
fi
echo "Current status: $TASK_STATUS"
if [ "$TASK_STATUS" = "succeeded" ]; then
echo "Dump creation succeeded"
break
elif [ "$TASK_STATUS" = "enqueued" ] || [ "$TASK_STATUS" = "processing" ]; then
echo "Dump creation in progress... ($TASK_STATUS)"
ATTEMPT=$((ATTEMPT+1))
sleep 5
else
echo "Dump creation in unexpected state: $TASK_STATUS. Giving up."
exit 1
fi
done
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
echo "Timed out waiting for dump creation"
exit 1
fi
# Extract dump UID more reliably
DUMP_UID=$(echo "$RESPONSE" | sed -n 's/.*"dumpUid":"\([^"]*\)".*/\1/p')
if [ -z "$DUMP_UID" ]; then
echo "Failed to extract dump UID. Aborting."
exit 1
fi
echo "Using dump $DUMP_UID"
# Check if file exists before copying
if [ ! -f "/meili_dumps/$DUMP_UID.dump" ]; then
echo "Dump file /meili_dumps/$DUMP_UID.dump not found!"
ls -la /meili_dumps/
exit 1
fi
cp -f "/meili_dumps/$DUMP_UID.dump" "/meili_dumps/meilisearch_latest.dump"
echo "Dump created and copied successfully. You can find it at /meili_dumps/meilisearch_latest.dump"
}
function restore {
restore() {
echo 'Restarting Meilisearch with imported dump, may take a while to become available...'
pkill meilisearch
# Check if dump file exists
if [ ! -f "/meili_dumps/meilisearch_latest.dump" ]; then
echo "Error: Dump file not found at /meili_dumps/meilisearch_latest.dump"
exit 1
fi
pkill meilisearch || echo "No Meilisearch process found to kill"
echo "Starting Meilisearch with import dump option..."
MEILI_NO_ANALYTICS=true /bin/meilisearch --import-dump /meili_dumps/meilisearch_latest.dump &
echo "Meilisearch restore process initiated..."
}
$@
# Handle command line argument
case "$1" in
backup)
backup
;;
restore)
restore
;;
*)
echo "Usage: $0 {backup|restore}"
exit 1
;;
esac

57
pg_backup.sh Normal file → Executable file
View File

@ -2,36 +2,69 @@
set -e
BACKUP_PATH='/var/lib/postgresql/data'
LATEST_BACKUP_FILE='$BACKUP_PATH/backup.sql'
BACKUP_PATH="/var/lib/postgresql/data"
LATEST_BACKUP_FILE="${BACKUP_PATH}/backup.sql"
function backup {
export FILE_WITH_DATE='$BACKUP_PATH/backup_`date +%F`.sql'
export PGPASSWORD=$(cat $POSTGRES_PASSWORD_FILE)
pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > $FILE_WITH_DATE
cp -f $FILE_WITH_DATE $LATEST_BACKUP_FILE
FILE_WITH_DATE="${BACKUP_PATH}/backup_$(date +%F).sql"
if [ -f "$POSTGRES_PASSWORD_FILE" ]; then
export PGPASSWORD=$(cat "$POSTGRES_PASSWORD_FILE")
fi
echo "Creating backup at ${FILE_WITH_DATE}..."
pg_dump -U "${POSTGRES_USER:-postgres}" "${POSTGRES_DB:-postgres}" > "${FILE_WITH_DATE}"
echo "Copying to ${LATEST_BACKUP_FILE}..."
cp -f "${FILE_WITH_DATE}" "${LATEST_BACKUP_FILE}"
echo "Backup done. You will find it at ${LATEST_BACKUP_FILE}"
}
function restore {
echo "Restoring database from ${LATEST_BACKUP_FILE}..."
cd /var/lib/postgresql/data/
restore_config(){
# Restore allowed connections
function restore_config {
echo "Restoring original pg_hba.conf configuration..."
cat pg_hba.conf.bak > pg_hba.conf
su postgres -c 'pg_ctl reload'
}
# Don't allow any other connections than local
echo "Setting up temporary pg_hba.conf to only allow local connections..."
cp pg_hba.conf pg_hba.conf.bak
echo "local all all trust" > pg_hba.conf
su postgres -c 'pg_ctl reload'
trap restore_config EXIT INT TERM
# Recreate Database
psql -U ${POSTGRES_USER} -d postgres -c "DROP DATABASE ${POSTGRES_DB} WITH (FORCE);"
createdb -U ${POSTGRES_USER} ${POSTGRES_DB}
psql -U ${POSTGRES_USER} -d ${POSTGRES_DB} -1 -f $LATEST_BACKUP_FILE
echo "Dropping existing database ${POSTGRES_DB:-postgres}..."
psql -U "${POSTGRES_USER:-postgres}" -d postgres -c "DROP DATABASE \"${POSTGRES_DB:-postgres}\" WITH (FORCE);"
echo "Creating fresh database ${POSTGRES_DB:-postgres}..."
createdb -U "${POSTGRES_USER:-postgres}" "${POSTGRES_DB:-postgres}"
echo "Restoring data from ${LATEST_BACKUP_FILE}..."
psql -U "${POSTGRES_USER:-postgres}" -d "${POSTGRES_DB:-postgres}" -1 -f "${LATEST_BACKUP_FILE}"
trap - EXIT INT TERM
restore_config
echo "Database restore completed successfully."
}
$@
# Execute the function passed as argument
case "$1" in
backup)
backup
;;
restore)
restore
;;
*)
echo "Usage: $0 {backup|restore}"
exit 1
;;
esac