I'm running into a long series of issues trying to use docker exec and the postgresql psql utility to restore a postgresql installation running within docker 1.3. I have a backup running OK via docker exec mycontainer pg_dumpall --clean --user=postgres --no-password > /tmp/backup.sql.
I have hit issues attempting a restore including:
docker execonly works when the container is running butpsqlcan't restore things properly with actively connected clientspg_ctl stopwill exit the postgres server process, which stops both the main container and thedocker execprocess you are running alongside it.docker execruns as root butpg_ctlmust run as postgres (I was trying to use pg_ctl to stop postgres so the restore would work)
So given the scenario that a postgresql container is running and serving active connections to an application, how can I restore it? Looking for details around cleanly stopping, running the restore, starting, etc.
Env is docker 1.3, postgresql 9.4, data lives in a data volume mounted at /var/lib/postgresql/data in the container. I have a valid .sql backup file on the docker host filesystem.
Update: FYI I'm open to any solution that works, whether it involves docker exec or not. If I should run a separate container and link to the main postgresql container and talk to it over TCP, for example, that's fine as long as I get some workable flow.
Here's what I have so far. Suggestions welcome. It's a bash script (with some mustache variables that get interpolated during the build process) designed to be run on the docker host.
#!/bin/bash
docker_sql() {
docker exec \
--interactive \
--tty \
"${container}" \
psql --user="${user}" --no-password --file="$1"
}
export DOCKER_HOST=tcp://localhost:2375
container="{{appName}}_db"
user=postgres
backup_path="$1"
if [[ -z "${backup_path}" ]]; then
echo "Provide a path to a backup file" 1>&2
exit 1
fi
backup_file=$(basename "${backup_path}")
restore_file=$(echo "${backup_file}" | sed -e s/.\bz2//)
restore_path="/var/lib/postgresql/data/${restore_file}"
bunzip2 --stdout "${backup_path}" > "/var/local/"${container}/"${restore_file}"
terminate_path="/var/lib/postgresql/data/terminate.sql"
cat <<EOF > "/var/local/${container}/terminate.sql"
revoke connect on database {{appName}} from public;
alter database {{appName}} connection limit 0;
select pg_terminate_backend(pid)
from pg_stat_activity
where pid <> pg_backend_pid()
and datname='{{appName}}';
EOF
docker_sql "${terminate_path}"
docker_sql "${restore_path}"