Skip to content

Instantly share code, notes, and snippets.

@Mulugruntz
Created April 9, 2021 09:22
Show Gist options
  • Save Mulugruntz/a06cfd81d3953816c5a4b79fb32066ed to your computer and use it in GitHub Desktop.
Save Mulugruntz/a06cfd81d3953816c5a4b79fb32066ed to your computer and use it in GitHub Desktop.
EdgeDB backup/restore scripts (working with docker-compose)
###### .env ######
EDGEDB_USER="my_user"
EDGEDB_PASSWORD="my_password"
###### project/bin/.env.restore ######
EDGEDB_USER="edgedb"
EDGEDB_PASSWORD="edge_ubersecure_password"

Please note the subdirectories project/bin/. Some files are located there, others are at the root.

#!/usr/bin/env bash
###### project/bin/backup_db.sh ######
# exit on error
set -e
get_abs_filename() {
# $1 : relative filename
python -c "from pathlib import Path;print(f'''{Path('$1').resolve()}''')"
}
this_dir=$(get_abs_filename ${0%/*})
spinner="$this_dir/spinner.sh"
DOCKER_CNAME=edgedb
TS=$(date -u +%Y%m%d_%H%M%S%Z)
BACKUP_FILENAME="backup_${TS}.edgedb.dump.tar.gz"
BACKUP_FILEPATTERN="backup_*.edgedb.dump.tar.gz"
BACKUP_LOCAL_DIR=$(get_abs_filename "$this_dir/../backup")
mkdir -p "$BACKUP_LOCAL_DIR"
REMOTE_DATADIR=$(docker exec -it "$DOCKER_CNAME" /usr/bin/env bash -c 'echo $EDGEDB_DATADIR')
REMOTE_DATADIR="${REMOTE_DATADIR//[$'\t\r\n ']}"
BACKUP_SUBDIR=backup
function shutdown() {
echo "Cleanup..."
$spinner docker exec "$DOCKER_CNAME" rm -rf "$BACKUP_SUBDIR" "$BACKUP_FILENAME"
}
trap shutdown EXIT
echo "Creating the dump..."
$spinner docker exec "$DOCKER_CNAME" edgedb dump "$BACKUP_SUBDIR" --all --format=dir
echo "Compressing the dump..."
$spinner docker exec "$DOCKER_CNAME" tar -czvf "$BACKUP_FILENAME" "$BACKUP_SUBDIR"
echo "Copying the dump file to the host machine..."
$spinner docker cp "$DOCKER_CNAME:$BACKUP_FILENAME" "$BACKUP_LOCAL_DIR/"
echo "Done!"
BACKUP_FILELIST=$(get_abs_filename "$BACKUP_LOCAL_DIR/$BACKUP_FILEPATTERN")
echo "Created dump file $BACKUP_FILENAME"
ls -lah $BACKUP_FILELIST
###### docker-compose.yml ######
version: '3'
services:
myapp:
container_name: myapp
build: . # Meaning it needs a Dockerfile here
ports:
- "4242:8000" # The webserver
volumes:
- ./logs:/var/log
links:
- edgedb
depends_on:
- edgedb
edgedb:
container_name: edgedb
image: edgedb/edgedb:1-beta1
environment:
- EDGEDB_USER=${EDGEDB_USER}
- EDGEDB_PASSWORD=${EDGEDB_PASSWORD}
# - EDGEDB_DEBUG_PGSERVER=1
ports:
- "5656:5656" # EdgeQL over binary protocol
- "8889:8889" # EdgeQL over HTTP
- "8888:8888" # GraphQL over HTTP
volumes:
- edgedb-db:/var/lib/edgedb/data
volumes:
edgedb-db: {}
#!/usr/bin/env bash
###### project/bin/restore_db.sh ######
# exit on error
set -e
if [ -z "$1" ]; then
echo "No backup file provided."
exit 1
fi
get_abs_filename() {
# $1 : relative filename
python -c "from pathlib import Path;print(f'''{Path('$1').resolve()}''')"
}
DOCKER_CNAME=edgedb
EDGE_VOLUME=$(docker inspect -f '{{ (index .Mounts 0).Name }}' "$DOCKER_CNAME")
this_dir=$(get_abs_filename ${0%/*})
root_dir=$(get_abs_filename "$this_dir/../..")
spinner="$this_dir/spinner.sh"
BACKUP_FILEPATH=$(get_abs_filename "$1")
BACKUP_FILENAME=$(basename "$BACKUP_FILEPATH")
REMOTE_BACKUP_MOUNT="/backup"
function shutdown() {
echo "Cleanup..."
$spinner docker exec edgedb rm -rf "$REMOTE_BACKUP_MOUNT"
echo "Creating a new container with user role..."
docker-compose -f "$root_dir/docker-compose.yml" --env-file "$root_dir/.env" up -d --no-deps --force-recreate --build "$DOCKER_CNAME"
$spinner docker logs -f "$DOCKER_CNAME" 2>&1| tee /dev/tty | grep -m 1 'Serving admin on /run/edgedb/.s.EDGEDB.admin.5656' > /dev/null
}
trap shutdown EXIT
echo "Stopping the database..."
$spinner docker container stop "$DOCKER_CNAME"
echo "Removing the database..."
$spinner docker container rm "$DOCKER_CNAME"
echo "Removing the volume..."
docker volume rm "$EDGE_VOLUME"
echo "Creating a new container with edgedb role..."
$spinner docker-compose -f "$root_dir/docker-compose.yml" --env-file "$this_dir/.env.restore" up -d --no-deps --force-recreate --build "$DOCKER_CNAME"
$spinner docker logs -f "$DOCKER_CNAME" 2>&1| tee /dev/tty | grep -m 2 'Serving admin on /run/edgedb/.s.EDGEDB.admin.5656' > /dev/null
echo "Restoring the dump..."
$spinner docker exec edgedb mkdir -p "$REMOTE_BACKUP_MOUNT/backup"
echo " Copying the dump file to the container..."
$spinner docker cp "$BACKUP_FILEPATH" "edgedb:$REMOTE_BACKUP_MOUNT/$BACKUP_FILENAME"
echo " Extracting the dump..."
$spinner docker exec edgedb tar -C "$REMOTE_BACKUP_MOUNT/backup" -xzvf "$REMOTE_BACKUP_MOUNT/$BACKUP_FILENAME" --strip 1
echo " EdgeDB restoring..."
$spinner docker exec edgedb edgedb restore -v --allow-non-empty --all "$REMOTE_BACKUP_MOUNT/backup"
echo "Done!"
#!/usr/bin/env bash
###### project/bin/spinner.sh ######
# Shows a spinner while another command is running. Randomly picks one of 12 spinner styles.
# @args command to run (with any parameters) while showing a spinner.
# E.g. ‹spinner sleep 10›
function shutdown() {
tput cnorm # reset cursor
}
trap shutdown EXIT
function cursorBack() {
echo -en "\033[$1D"
}
function spinner() {
# make sure we use non-unicode character type locale
# (that way it works for any locale as long as the font supports the characters)
# local LC_CTYPE=C
local pid=$1 # Process Id of the previous running command
case $(($RANDOM % 12)) in
0)
local spin='⠁⠂⠄⡀⢀⠠⠐⠈'
local charwidth=3
;;
1)
local spin='-\|/'
local charwidth=1
;;
2)
local spin="▁▂▃▄▅▆▇█▇▆▅▄▃▂▁"
local charwidth=3
;;
3)
local spin="▉▊▋▌▍▎▏▎▍▌▋▊▉"
local charwidth=3
;;
4)
local spin='←↖↑↗→↘↓↙'
local charwidth=3
;;
5)
local spin='▖▘▝▗'
local charwidth=3
;;
6)
local spin='┤┘┴└├┌┬┐'
local charwidth=3
;;
7)
local spin='◢◣◤◥'
local charwidth=3
;;
8)
local spin='◰◳◲◱'
local charwidth=3
;;
9)
local spin='◴◷◶◵'
local charwidth=3
;;
10)
local spin='◐◓◑◒'
local charwidth=3
;;
11)
local spin='⣾⣽⣻⢿⡿⣟⣯⣷'
local charwidth=3
;;
esac
local i=0
tput civis # cursor invisible
while kill -0 $pid 2>/dev/null; do
local i=$(((i + $charwidth) % ${#spin}))
printf "%s" "${spin:$i:$charwidth}"
cursorBack 1
sleep .1
done
tput cnorm
wait $pid # capture exit code
return $?
}
("$@") &
spinner $!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment