diff --git a/abra.sh b/abra.sh index 808f6b0..105dfc3 100644 --- a/abra.sh +++ b/abra.sh @@ -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 diff --git a/compose.meilisearch.yml b/compose.meilisearch.yml index 3b1ff40..0799a01 100644 --- a/compose.meilisearch.yml +++ b/compose.meilisearch.yml @@ -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: diff --git a/meili_backup.sh b/meili_backup.sh old mode 100644 new mode 100755 index 5f43da4..14607d0 --- a/meili_backup.sh +++ b/meili_backup.sh @@ -1,44 +1,107 @@ -#!/bin/bash +#!/bin/sh set -e -BACKUP_FILE='/var/lib/postgresql/data/backup.sql' - -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" +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" + + # 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 { - echo 'Restarting Meilisearch with imported dump, may take a while to become available...' - pkill meilisearch - MEILI_NO_ANALYTICS=true /bin/meilisearch --import-dump /meili_dumps/meilisearch_latest.dump & +restore() { + echo 'Restarting Meilisearch with imported dump, may take a while to become available...' + + # 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 \ No newline at end of file diff --git a/pg_backup.sh b/pg_backup.sh old mode 100644 new mode 100755 index 9aa6a1c..652b7c4 --- a/pg_backup.sh +++ b/pg_backup.sh @@ -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 \ No newline at end of file