Skip to content

Commit

Permalink
Add scripts and docs to configure docker backups (#2534)
Browse files Browse the repository at this point in the history
Add scripts and docs to configure docker backups (#2534)
  • Loading branch information
dumbstertruck3 authored Nov 25, 2024
1 parent 3ab5d90 commit f0f0c8b
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ POSTGRES_HOST=db
POSTGRES_DB=care
POSTGRES_PORT=5432
DATABASE_URL=postgres://postgres:postgres@localhost:5433/care
BACKUP_DIR="./care-backups"
DB_BACKUP_RETENTION_PERIOD=7
REDIS_URL=redis://localhost:6380
CELERY_BROKER_URL=redis://localhost:6380/0

Expand Down
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Any support is welcome. You could help by writing documentation, pull-requests,

### Getting Started

An issue wih the [good first](https://github.com/ohcnetwork/care/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22) or [help wanted](https://github.com/ohcnetwork/care/issues?q=is%3Aissue+sort%3Aupdated-desc+label%3A%22help+wanted%22+is%3Aopen) label might be a good place to start with.
An issue with the [good first](https://github.com/ohcnetwork/care/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22) or [help wanted](https://github.com/ohcnetwork/care/issues?q=is%3Aissue+sort%3Aupdated-desc+label%3A%22help+wanted%22+is%3Aopen) label might be a good place to start with.

### Setting up the development environment

Expand Down Expand Up @@ -34,11 +34,13 @@ Make sure you have docker and docker-compose installed. Then run:
make build
```



#### Using Virtualenv

Make sure you have Postgres and Redis installed on your system.

##### Setting up postgtres for the first time
##### Setting up postgres for the first time

```bash
sudo -u postgres psql
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ make load-dummy-data
Prebuilt docker images for server deployments are available
on [ghcr](https://github.com/ohcnetwork/care/pkgs/container/care)

For backup and restore use [this](/docs/databases/backup.rst) documentation.
## Contributing

We welcome contributions from everyone. Please read our [contributing guidelines](./CONTRIBUTING.md) to get started.
1 change: 1 addition & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ services:
- ./docker/.prebuilt.env
volumes:
- postgres-data:/var/lib/postgresql/data
- ${BACKUP_DIR:-./care-backups}:/backups
ports:
- "5433:5432"

Expand Down
121 changes: 121 additions & 0 deletions docs/databases/backup.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
Docker database backup
======================

This page explains how to automate the backup process of a Docker database on a daily basis and restore the backup snapshot created by the `backup script <../../scripts/backup.sh>`_.

Note: This documentation assumes that you are using a Linux-based system.
-------------------------------------------------------------------------------

Here's how the script works
---------------------------

The script automates the process of creating PostgreSQL database backups from a Docker container. It generates a backup file(``.dump``) using the pg_dump utility in PostgreSQL and stores these files in the path configured in ``$BACKUP_DIR`` environment variable which is binded to ``/backups`` in the docker container. Backup files older than ``$DB_BACKUP_RETENTION_PERIOD`` days are deleted when the script is executed by default it is set to 7 days. The backup file is saved with the name ``care_backup_%Y%m%d%H%M%S.sql``.

Set up a cronjob
----------------

Backup your database running on docker automatically everyday by initiating a cronjob.

Install the package
~~~~~~~~~~~~~~~~~~~

For a fedora based system:

.. code:: bash
sudo dnf install crond
For a debian based system:

.. code:: bash
sudo apt install cron
Automate the cronjob
~~~~~~~~~~~~~~~~~~~~
Note: Make sure you are inside the care directory at the time of executing the following.
-------------------------------------------------------------------------------

Open up a crontab:

.. code:: bash
crontab -e
Add the cronjob:

.. code:: bash
0 0 * * * "/scripts/backup.sh"
List the cron jobs
~~~~~~~~~~~~~~~~~~

.. code:: bash
crontab -l
Check the status of cron
~~~~~~~~~~~~~~~~~~~~~~~~

For a fedora based os:

.. code:: bash
sudo systemctl status crond
For a debian based os:

.. code:: bash
sudo systemctl status cron
Verify the cron job
~~~~~~~~~~~~~~~~~
To verify the cron job is working:

1. Check the system logs for cron activity, which is usually somewhere in

.. code:: bash
/var/log/
2. Monitor the backup directory for new files after the scheduled time

Restoration of the Database
===========================

We are basically deleting the container's existing database and creating a new database with the same name. Then we will use ``pg_restore`` to restore the database. Run the following commands in your terminal.

Make sure you have stopped all the containers except the db before proceeding. And be inside the care directory at the time of executing the following.
------------------------------------------------------------------------------

Delete the existing database:

.. code:: bash
docker exec -it $(docker ps --format '{{.Names}}' | grep 'care-db') psql -U postgres -c "DROP DATABASE IF EXISTS care;"
Create the new database:

.. code:: bash
docker exec -it $(docker ps --format '{{.Names}}' | grep 'care-db') psql -U postgres -c "CREATE DATABASE care;"
Execute and copy the name of the file you want to restore the database with:

.. code:: bash
sudo ls ./care-backups
Restore the database:

Replace <file name> with your file name which looks like this ``care_backup_%Y%m%d%H%M%S.sql``

.. code:: bash
docker exec -it $(docker ps --format '{{.Names}}' | grep 'care-db') pg_restore -U postgres -d care /backups/<file name>.dump
------------------------------------------------------------------------------------------------------------------

There are way easier ways to do this. If anyone has any particular idea, feel free to make a PR :)
34 changes: 34 additions & 0 deletions scripts/backup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
set -ueo pipefail
# Ensure we can find the .env file
ENV_FILE="$(dirname "$(readlink -f "$0")")/../.env"
if [[ ! -f "${ENV_FILE}" ]]; then
echo "Error: .env file not found at ${ENV_FILE}" >&2
exit 1
fi
source "${ENV_FILE}"

container_name="$(docker ps --format '{{.Names}}' | grep 'care-db')"
if [[ -z "${container_name}" ]]; then
echo "Error: PostgreSQL container 'care-db' is not running" >&2
exit 1
elif [[ $(echo "${container_name}" | wc -l) -gt 1 ]]; then
echo "Error: Multiple containers matched 'care-db'" >&2
exit 1
fi

date=$(date +%Y%m%d%H%M%S)
#name the file
backup_file="${POSTGRES_DB}_backup_${date}.dump"

# Remove old backup/backups
docker exec -t ${container_name} find "/backups" -name "${POSTGRES_DB}_backup_*.dump" -type f -mtime +${DB_BACKUP_RETENTION_PERIOD} -exec rm {} \;

#backup the database
docker exec -t ${container_name} pg_dump -U ${POSTGRES_USER} -Fc -f /backups/${backup_file} ${POSTGRES_DB}

if ! docker exec -t ${container_name} pg_dump -U ${POSTGRES_USER} -Fc -f /backups/${backup_file} ${POSTGRES_DB}; then
echo "Error: Database backup failed" >&2
exit 1
fi
echo "Backup of database '${POSTGRES_DB}' completed and saved as /backups/${backup_file}"

0 comments on commit f0f0c8b

Please sign in to comment.