Skip to content

Commit

Permalink
Merge pull request #4 from silinternational/develop
Browse files Browse the repository at this point in the history
fix DB restore error
  • Loading branch information
dalenewby authored Mar 16, 2022
2 parents 5d6aac7 + 29e083e commit b41486a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 48 deletions.
7 changes: 3 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
FROM alpine:3.11
FROM alpine:3.15

RUN apk update \
&& apk add --no-cache \
bash \
postgresql \
postgresql-client \
python py-pip \
postgresql12-client \
python3 py-pip \
&& pip install s3cmd python-magic

COPY application/ /data/
Expand Down
45 changes: 29 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@ Service to backup and/or restore a PostgreSQL database using S3
4. Run a backup and check your bucket for that backup

### Environment variables
`MODE=[backup|restore]`
`MODE` Valid values: `backup`, `restore`

`DB_HOST=` hostname of the database server
`DB_HOST` hostname of the database server

`DB_NAME=` name of the database
`DB_NAME` name of the database

`DB_OPTIONS=opt1 opt2 opt3 ...` optional arguments to supply to the backup or restore commands
`DB_OPTIONS` optional arguments to supply to the backup or restore commands

`DB_ROOTPASSWORD=` password for the `DB_ROOTUSER`
`DB_ROOTPASSWORD` password for the `DB_ROOTUSER`

`DB_ROOTUSER=` database administrative user, typically "postgres" for PostgreSQL databases
`DB_ROOTUSER` database administrative user, typically "postgres" for PostgreSQL databases

`DB_USERPASSWORD=` password for the `DB_USER`
`DB_USERPASSWORD` password for the `DB_USER`

`DB_USER=` user that accesses the database (PostgreSQL "role")
`DB_USER` user that accesses the database (PostgreSQL "role")

`AWS_ACCESS_KEY=` used for S3 interactions
`AWS_ACCESS_KEY` used for S3 interactions

`AWS_SECRET_KEY=` used for S3 interactions
`AWS_SECRET_KEY` used for S3 interactions

`S3_BUCKET=` _e.g., s3://database-backups_ **NOTE: no trailing slash**
`S3_BUCKET` e.g., _s3://database-backups_ **NOTE: no trailing slash**

>**It's recommended that your S3 bucket have versioning turned on.**
Expand All @@ -38,9 +38,22 @@ This image is built automatically on Docker Hub as [silintl/postgresql-backup-re
## Playing with it locally
You'll need [Docker](https://www.docker.com/get-docker), [Docker Compose](https://docs.docker.com/compose/install/), and [Make](https://www.gnu.org/software/make/).

1. `cp local.env.dist local.env` and supply variables
2. Ensure you have a `gz` dump in your S3 bucket to be used for testing. A test database is provided as part of this project in the `test` folder. You can copy it to S3 as follows:
1. Copy `local.env.dist` to `local.env`.
2. Edit `local.env` to supply values for the variables.
3. Ensure you have a `gz` dump in your S3 bucket to be used for testing. A test database is provided as part of this project in the `test` folder. You can copy it to S3 as follows:
* `aws s3 cp test/world.sql.gz ${S3_BUCKET}/world.sql.gz`
3. `make`

A UI into the local database will then be running at [http://localhost:8080](http://localhost:8080)
4. `make db` # creates the Postgres DB server
5. `make restore` # restores the DB dump file
6. `docker ps -a` # get the Container ID of the exited restore container
7. `docker logs <containerID>` # review the restoration log messages
8. `make backup` # create a new DB dump file
9. `docker ps -a` # get the Container ID of the exited backup container
10. `docker logs <containerID>` # review the backup log messages
11. `make restore` # restore the DB dump file from the new backup
12. `docker ps -a` # get the Container ID of the exited restore container
13. `docker logs <containerID>` # review the restoration log messages
14. `make clean` # remove containers and network
15. `docker volume ls` # find the volume ID of the Postgres data container
16. `docker volume rm <volumeID>` # remove the data volume
17. `docker images` # list existing images
18. `docker image rm <imageID ...>` # remove images no longer needed
19 changes: 1 addition & 18 deletions application/restore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ STATUS=0

echo "postgresql-backup-restore: restore: Started"

# Does the database exist?
echo "postgresql-backup-restore: checking for DB ${DB_NAME}"
result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME})
if [ -z "${result}" ]; then
message="Database "${DB_NAME}" on host "${DB_HOST}" does not exist."
echo "postgresql-backup-restore: FATAL: ${message}"
exit 1
fi

# Ensure the database user exists.
echo "postgresql-backup-restore: checking for DB user ${DB_USER}"
result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\du' | grep ${DB_USER})
Expand All @@ -25,14 +16,6 @@ if [ -z "${result}" ]; then
fi
fi

echo "postgresql-backup-restore: changing DB ownership to ${DB_USER}"
result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command="alter database ${DB_NAME} owner to ${DB_USER};")
if [ "${result}" != "ALTER DATABASE" ]; then
message="Alter database command failed: ${result}"
echo "postgresql-backup-restore: FATAL: ${message}"
exit 1
fi

echo "postgresql-backup-restore: restoring ${DB_NAME}"

start=$(date +%s)
Expand All @@ -58,7 +41,7 @@ else
fi

start=$(date +%s)
psql --host=${DB_HOST} --username=${DB_USER} --dbname=${DB_NAME} ${DB_OPTIONS} < /tmp/${DB_NAME}.sql || STATUS=$?
psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS} < /tmp/${DB_NAME}.sql || STATUS=$?
end=$(date +%s)

if [ $STATUS -ne 0 ]; then
Expand Down
15 changes: 5 additions & 10 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,14 @@ services:
# POSTGRES_USER - superuser (default is 'postgres')
# POSTGRES_DB - name of default database (default is value of POSTGRES_USER)
db:
image: postgres:9.6-alpine
image: postgres:11.15-alpine3.15
volumes_from:
- data
ports:
- "5432"
environment:
POSTGRES_PASSWORD: r00tp@ss!

# adminer:
# image: adminer:4.6.3
# ports:
# - "8080:8080"

# DB_HOST - hostname of the database server
# DB_ROOTUSER - administrative user for the database server
# DB_ROOTPASSWORD - password for the DB_ROOTUSER
Expand All @@ -39,8 +34,8 @@ services:
DB_HOST: db
DB_ROOTUSER: postgres
DB_ROOTPASSWORD: r00tp@ss!
DB_USER: postgres
DB_USERPASSWORD: r00tp@ss!
DB_USER: dbuser
DB_USERPASSWORD: dbuserpass
DB_NAME: world
MODE: restore
CRON_SCHEDULE: "25 * * * *"
Expand All @@ -55,8 +50,8 @@ services:
DB_HOST: db
DB_ROOTUSER: postgres
DB_ROOTPASSWORD: r00tp@ss!
DB_USER: postgres
DB_USERPASSWORD: r00tp@ss!
DB_USER: dbuser
DB_USERPASSWORD: dbuserpass
DB_NAME: world
MODE: backup
CRON_SCHEDULE: "20 * * * *"
Binary file modified test/world.sql.gz
Binary file not shown.

0 comments on commit b41486a

Please sign in to comment.