graphql-engine/scripts/containers/postgres
Samir Talwar c0a0a5fe87 docker: Mount database data directories as named volumes.
I'm trying to shore up the Python integration tests to make them more reliable. In doing so, I noticed this.

---

This ensures that the data directories are always in a mutable file system, and not going through overlayfs.

In my testing, this sped up PostgreSQL database initialization a lot. In particular, `CREATE DATABASE` commands went from > 5s to < 0.1s.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5248
GitOrigin-RevId: 5104aea32c92559c323803020d727bebfdafb8e6
2022-08-04 10:11:10 +00:00

119 lines
3.4 KiB
Plaintext

### This file is not meant to be run directly, but to be sourced from
### the dev script. It defines all the functions required to run a
### postgres docker container.
######################
# Configuration #
######################
if [ "$MODE" = "test" ]; then
PG_PORT=35432
else
PG_PORT=25432
fi
PG_PASSWORD=postgres
PG_VOLUME_NAME='hasura-dev-postgres'
PG_CONTAINER_NAME="hasura-dev-postgres-$PG_PORT"
PG_DB_URL="postgresql://postgres:$PG_PASSWORD@127.0.0.1:$PG_PORT/postgres"
PG_DOCKER="docker exec -u postgres -it $PG_CONTAINER_NAME psql $PG_DB_URL"
if [[ `uname -m` == 'arm64' ]]; then
PG_CONTAINER_IMAGE=sayitsocial/postgis:raspi
else
PG_CONTAINER_IMAGE=cimg/postgres:14.4-postgis
fi
# NOTE FWIW:
# Brandon tried these options to speed up integration tests, but to little effect:
# fsync=off
# synchronous_commit=off
# full_page_writes=off
# ...as well as ramdisk for pg data:
# --mount type=tmpfs,destination=/var/lib/postgresql/data \
# Useful development defaults for postgres (no spaces here, please):
#
# setting 'port' in container is a workaround for the pg_dump endpoint (see tests)
# log_hostname=off to avoid timeout failures when running offline due to:
# https://forums.aws.amazon.com/thread.jspa?threadID=291285
#
# All lines up to log_error_verbosity are to support pgBadger:
# https://github.com/darold/pgbadger#LOG-STATEMENTS
#
# Also useful:
# log_autovacuum_min_duration=0
CONF=$(cat <<-EOF
log_min_duration_statement=0
log_checkpoints=on
log_connections=on
log_disconnections=on
log_lock_waits=on
log_temp_files=0
log_error_verbosity=default
log_hostname=off
log_duration=on
port=$PG_PORT
EOF
)
# log lines above as -c flag arguments we pass to postgres
CONF_FLAGS=$(echo "$CONF" | sed -e 's/^/-c /' | tr '\n' ' ')
######################
# Functions #
######################
function pg_launch_container {
echo_pretty "Launching postgres container: $PG_CONTAINER_NAME"
docker volume create "$PG_VOLUME_NAME"
docker run \
--name "$PG_CONTAINER_NAME" \
--publish "127.0.0.1:${PG_PORT}:${PG_PORT}" \
--expose="$PG_PORT" \
--volume="${PG_VOLUME_NAME}:/var/lib/postgresql/data" \
--env=POSTGRES_PASSWORD="$PG_PASSWORD" \
--detach \
"$PG_CONTAINER_IMAGE" \
$CONF_FLAGS
# graphql-engine calls the pg_dump executable. To avoid a version mismatch (and
# the dependency entirely) we create a shim that executes the pg_dump in the
# postgres container. Note output to file won't work.
DEV_SHIM_PATH="/tmp/hasura-dev-shims-$PG_PORT"
mkdir -p "$DEV_SHIM_PATH"
cat >"$DEV_SHIM_PATH/pg_dump" <<EOL
#!/bin/bash
# Generated from: $0
if [[ \$@ == *" -f"* ]]; then
echo "It looks like we're trying to pg_dump to a file, but that won't work with this shim. See $0" >&2
exit 1
fi
docker exec -u postgres $PG_CONTAINER_NAME pg_dump "\$@"
EOL
chmod a+x "$DEV_SHIM_PATH/pg_dump"
export PATH="$DEV_SHIM_PATH":$PATH
}
function pg_wait {
echo -n "Waiting for postgres to come up"
until ( $PG_DOCKER -c '\l' ) &>/dev/null; do
echo -n '.' && sleep 0.2
done
echo " Ok"
}
function pg_cleanup {
# Since scripts here are tailored to the env we've just launched:
rm -r "$DEV_SHIM_PATH"
echo_pretty "Removing $PG_CONTAINER_NAME and its volumes in 5 seconds!"
echo_pretty " PRESS CTRL-C TO ABORT removal of all containers, or ENTER to clean up right away"
read -t5 || true
docker stop "$PG_CONTAINER_NAME"
docker rm -v "$PG_CONTAINER_NAME"
docker volume rm "$PG_VOLUME_NAME"
}