Skip to content

Commit 8024188

Browse files
authored
Update backup.sh
1 parent 9973f72 commit 8024188

1 file changed

Lines changed: 60 additions & 63 deletions

File tree

‎pg-node/backup.sh‎

Lines changed: 60 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,19 @@
11
#!/usr/bin/env bash
22
#
3-
# backup.sh
3+
# backup.sh - stops the pg-node stack, archives /opt/pg-node and
4+
# /var/lib/pg-node into backup.tar.gz, then restarts the stack.
45
#
5-
# Stops the pg-node Docker Compose stack, archives its application
6-
# and data directories into backup.tar.gz, then restarts the stack.
7-
#
8-
# Fixed application paths:
9-
# /opt/pg-node -> application / compose project
10-
# /var/lib/pg-node -> persistent data
11-
# /opt/pg-node/docker-compose.yml -> compose file
12-
#
13-
# Usage:
14-
# sudo ./backup.sh
6+
# Usage: sudo ./backup.sh
157
#
168
set -Eeuo pipefail
179

18-
# --------------------------------------------------------------------------
19-
# Constants
20-
# --------------------------------------------------------------------------
2110
readonly APP_DIR="/opt/pg-node"
2211
readonly DATA_DIR="/var/lib/pg-node"
2312
readonly COMPOSE_FILE="${APP_DIR}/docker-compose.yml"
2413
readonly BACKUP_FILE="backup.tar.gz"
2514
readonly BACKUP_PATH="$(pwd)/${BACKUP_FILE}"
15+
readonly LOG_FILE="/var/log/pg-node-backup.log"
2616

27-
# --------------------------------------------------------------------------
28-
# Colors
29-
# --------------------------------------------------------------------------
3017
readonly COLOR_RED="\033[0;31m"
3118
readonly COLOR_GREEN="\033[0;32m"
3219
readonly COLOR_YELLOW="\033[0;33m"
@@ -38,52 +25,80 @@ log_ok() { echo -e "${COLOR_GREEN}[ OK ]${COLOR_RESET} $*"; }
3825
log_warn() { echo -e "${COLOR_YELLOW}[WARN]${COLOR_RESET} $*"; }
3926
log_err() { echo -e "${COLOR_RED}[FAIL]${COLOR_RESET} $*" >&2; }
4027

41-
# --------------------------------------------------------------------------
42-
# Error handling / cleanup
43-
# --------------------------------------------------------------------------
28+
# Runs a command with output hidden (only a spinner is shown); full output
29+
# goes to LOG_FILE.
30+
run_quiet() {
31+
local desc="$1"
32+
shift
33+
34+
echo "----- $(date '+%Y-%m-%d %H:%M:%S') :: ${desc} -----" >> "${LOG_FILE}"
35+
36+
( "$@" ) >> "${LOG_FILE}" 2>&1 &
37+
local pid=$!
38+
39+
if [[ -t 1 ]]; then
40+
local frames='|/-\'
41+
local i=0
42+
while kill -0 "${pid}" 2>/dev/null; do
43+
i=$(( (i + 1) % 4 ))
44+
printf "\r${COLOR_BLUE}[....]${COLOR_RESET} %s %s" "${desc}" "${frames:$i:1}"
45+
sleep 0.2
46+
done
47+
else
48+
printf "${COLOR_BLUE}[....]${COLOR_RESET} %s\n" "${desc}"
49+
fi
50+
51+
wait "${pid}"
52+
local exit_code=$?
53+
54+
if [[ "${exit_code}" -eq 0 ]]; then
55+
printf "\r${COLOR_GREEN}[ OK ]${COLOR_RESET} %s\n" "${desc}"
56+
else
57+
printf "\r${COLOR_RED}[FAIL]${COLOR_RESET} %s (see: %s)\n" "${desc}" "${LOG_FILE}"
58+
fi
59+
60+
return "${exit_code}"
61+
}
62+
63+
init_log() {
64+
mkdir -p "$(dirname "${LOG_FILE}")"
65+
: > "${LOG_FILE}"
66+
log_info "Logging full output to: ${LOG_FILE}"
67+
}
68+
4469
STACK_STOPPED=0
4570

46-
# Always try to bring the stack back up if we stopped it and something
47-
# failed afterwards, so we don't leave the service down.
4871
on_error() {
4972
local exit_code=$?
50-
log_err "An error occurred (exit code ${exit_code}) on line ${BASH_LINENO[0]}."
73+
log_err "Error (exit code ${exit_code}) on line ${BASH_LINENO[0]}. See ${LOG_FILE}"
5174
if [[ "${STACK_STOPPED}" -eq 1 ]]; then
52-
log_warn "Attempting to restart the Docker Compose stack after failure..."
53-
docker compose -f "${COMPOSE_FILE}" up -d || \
54-
log_err "Failed to restart the stack automatically. Please check manually."
75+
log_warn "Attempting to restart the stack after failure..."
76+
docker compose -f "${COMPOSE_FILE}" up -d || log_err "Failed to restart the stack automatically."
5577
fi
5678
exit "${exit_code}"
5779
}
5880
trap on_error ERR
5981

60-
# --------------------------------------------------------------------------
61-
# Checks
62-
# --------------------------------------------------------------------------
63-
64-
# 1. Verify root privileges
6582
check_root() {
6683
if [[ "${EUID}" -ne 0 ]]; then
6784
log_err "This script must be run as root (use sudo)."
6885
exit 1
6986
fi
70-
log_ok "Running with root privileges."
87+
log_ok "Running as root."
7188
}
7289

73-
# 2. Verify Docker is installed
7490
check_docker() {
7591
if ! command -v docker &>/dev/null; then
76-
log_err "Docker is not installed. Please install Docker before running this script."
92+
log_err "Docker is not installed."
7793
exit 1
7894
fi
7995
if ! docker compose version &>/dev/null; then
8096
log_err "Docker Compose plugin is not installed."
8197
exit 1
8298
fi
83-
log_ok "Docker and Docker Compose plugin are present."
99+
log_ok "Docker and Compose plugin present."
84100
}
85101

86-
# Verify required paths exist
87102
check_paths() {
88103
if [[ ! -f "${COMPOSE_FILE}" ]]; then
89104
log_err "Compose file not found at ${COMPOSE_FILE}."
@@ -94,29 +109,17 @@ check_paths() {
94109
exit 1
95110
fi
96111
if [[ ! -d "${DATA_DIR}" ]]; then
97-
log_warn "Data directory ${DATA_DIR} does not exist. It will be skipped in the archive."
112+
log_warn "Data directory ${DATA_DIR} does not exist; it will be skipped."
98113
fi
99114
log_ok "Required paths verified."
100115
}
101116

102-
# --------------------------------------------------------------------------
103-
# Steps
104-
# --------------------------------------------------------------------------
105-
106-
# 3. Stop the Docker Compose project
107117
stop_stack() {
108-
log_info "Stopping Docker Compose stack..."
109-
docker compose -f "${COMPOSE_FILE}" down
118+
run_quiet "Stopping Docker Compose stack" docker compose -f "${COMPOSE_FILE}" down
110119
STACK_STOPPED=1
111-
log_ok "Stack stopped."
112120
}
113121

114-
# 4. Create compressed archive
115122
create_backup() {
116-
log_info "Creating backup archive: ${BACKUP_FILE}"
117-
118-
# Build list of existing directories only, to avoid tar failing
119-
# if one of them is missing.
120123
local targets=()
121124
[[ -d "${APP_DIR}" ]] && targets+=("${APP_DIR}")
122125
[[ -d "${DATA_DIR}" ]] && targets+=("${DATA_DIR}")
@@ -126,36 +129,30 @@ create_backup() {
126129
exit 1
127130
fi
128131

129-
# Archive with paths relative to / so restore can extract to / directly.
130-
tar -czpf "${BACKUP_PATH}" -C / \
132+
# Paths relative to / so restore.sh can extract straight to /.
133+
run_quiet "Creating backup archive" tar -czpf "${BACKUP_PATH}" -C / \
131134
$(printf '%s\n' "${targets[@]}" | sed 's|^/||')
132135

133-
log_ok "Archive created at ${BACKUP_PATH}"
136+
log_ok "Archive created: ${BACKUP_PATH}"
134137
}
135138

136-
# 5. Start the project again
137139
start_stack() {
138-
log_info "Starting Docker Compose stack..."
139-
docker compose -f "${COMPOSE_FILE}" up -d
140+
run_quiet "Starting Docker Compose stack" docker compose -f "${COMPOSE_FILE}" up -d
140141
STACK_STOPPED=0
141-
log_ok "Stack started."
142142
}
143143

144-
# 6. Print backup size and success message
145144
print_summary() {
146145
local size
147146
size=$(du -h "${BACKUP_PATH}" | cut -f1)
148147
echo
149148
log_ok "Backup completed successfully."
150-
log_info "Backup file: ${BACKUP_PATH}"
151-
log_info "Backup size: ${size}"
149+
log_info "File: ${BACKUP_PATH}"
150+
log_info "Size: ${size}"
152151
}
153152

154-
# --------------------------------------------------------------------------
155-
# Main
156-
# --------------------------------------------------------------------------
157153
main() {
158154
check_root
155+
init_log
159156
check_docker
160157
check_paths
161158
stop_stack

0 commit comments

Comments
 (0)