Skip to content

Add script+Dockerfile to test restoring from fresh backup every 24 hours #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@

Reference: https://www.postgresql.org/docs/current/continuous-archiving.html

1. Exec into a new container that is running the postgres image
2. Make sure that `$PGDATA` is empty
3. Run this script to download the backup and untar it into the $PGDATA directory
```
gsutil cp gs://<bucket>/<filename>.tar.zst - | tar -I zstd -xvf - -C $PGDATA
```
4. `pg_ctl -D $PGDATA reload`
1. Create a caprover app.
2. Check "Do not expose as web-app"
3. Specify the following environment variables in the App Configs tab
- `BUCKET_PATH` - The `gs://<bucket>/<filename>.tar.zst` path to the GCS bucket where the db backup should be stored
- `GOOGLE_APPLICATION_CREDENTIALS_JSON` - A JSON service account key, that has permission to create/replace objects in above bucket.
- `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD` - Should point to your db
4. Add this github repo in the deployment tab, set captain definition file path to `restore.captain-definition`, and press force deploy.

Ideally, keep a Caprover app configured with the above settings and instance count = 0. When you need to restore,
set the instance count to 1, and it will automatically restore from the latest backup. Scale down the instance
count to 0 when done.
24 changes: 24 additions & 0 deletions restore.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ARG POSTGRES_VERSION=15.2

FROM postgres:${POSTGRES_VERSION}

RUN apt-get update && apt-get install -y curl python3

WORKDIR /tmp

COPY ./restore.sh ./restore.sh
COPY ./run-restore.sh ./run-restore.sh

RUN mkdir -p $PGDATA
RUN chown -R postgres:postgres $PGDATA
RUN chmod 0700 $PGDATA

USER postgres

# install gcloud sdk
#
RUN curl -s https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz \
| tar xz && ./google-cloud-sdk/install.sh -q --usage-reporting=false
ENV PATH=$PATH:google-cloud-sdk/bin/

CMD ["./run-restore.sh"]
4 changes: 4 additions & 0 deletions restore.captain-definition
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"schemaVersion": 2,
"dockerfilePath": "./restore.Dockerfile"
}
16 changes: 16 additions & 0 deletions restore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pg_isready && pg_ctl -D $PGDATA stop && echo "Stopped running database..."

echo "Deleting existing DB and restoring from $BUCKET_PATH"
rm -rf $PGDATA/*
gsutil cp $BUCKET_PATH - | tar -I zstd -xf - -C $PGDATA

chmod 0700 $PGDATA

pg_ctl -D $PGDATA start

if pg_isready -h localhost -p 5432;
then
echo "Database is ready"
else
echo "Database is not ready"
fi
15 changes: 15 additions & 0 deletions run-restore.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# avoid logging secrets!
set -e

echo '+ echo "$GOOGLE_APPLICATION_CREDENTIALS_JSON" > serviceAccountKey.json'
echo "$GOOGLE_APPLICATION_CREDENTIALS_JSON" > serviceAccountKey.json

# safe to turn on logging now
set -ex

gcloud auth activate-service-account --key-file serviceAccountKey.json

while true; do
sh restore.sh
sleep "${SLEEP:-24h}"
done