TitanFighter
TitanFighter

Reputation: 5094

How to dump DB via cron inside container?

I use docker-compose which ups a stack.

Relative code:

db:
  build: ./dockerfiles/postgres
  container_name: postgres-container
  volumes:
    - ./dockerfiles/postgres/pgdata:/var/lib/postgresql/data
    - ./dockerfiles/postgres/backups:/pg_backups

Dockerfile for Postgres:

FROM postgres:latest

RUN mkdir /pg_backups && > /etc/cron.d/pg_backup-cron && echo "00 22 * * * /backup.sh" >> /etc/cron.d/pg_backup-cron
ADD ./backup.sh /
RUN chmod +x /backup.sh

backup.sh

#!/bin/sh
# Dump DBs

now=$(date +"%d-%m-%Y_%H-%M")
pg_dump -h db -U postgres -d postgres > "/pg_backups/db_dump_$now.sql"

# remove all files (type f) modified longer than 30 days ago under /pg_backups
find /pg_backups -name "*.sql" -type f -mtime +30 -delete

exit 0

Cron simply does not launch the script. How to fix that?


FINAL VERSION

Based on @Farhad Farahi answer, below is the final result:

On host I made a script:

#!/bin/bash
# Creates Cron Job which backups DB in Docker everyday at 22:00 host time
croncmd_backup="docker exec -it postgres-container bash -c '/pg_backups/backup.sh'"
cronjob_backup="00 22 * * * $croncmd_backup"

if [[ $# -eq 0 ]] ; then
    echo -e 'Please provide one of the arguments (example: ./run_after_install.sh add-cron-db-backup):
    1) add-cron-db-backup
    2) remove-cron-db-backup'

# In order to avoid task duplications in cron, the script checks, if there is already back-up job in cron
elif [[ $1 == add-cron-db-backup ]]; then
    ( crontab -l | grep -v -F "$croncmd_backup" ; echo "$cronjob_backup" ) | crontab -
    echo "==>>> Backup task added to Cron"

# Remove back-up job from cron
elif [[ $1 == remove-cron-db-backup ]]; then
    ( crontab -l | grep -v -F "$croncmd_backup" ) | crontab -
    echo "==>>> Backup task removed from Cron"

fi

This script adds cron task to host, which launches the script backup.sh (see above) in a container.

For this implementation there is no need to use Dockerfile for Postgres, so relevant part of docker-compose.yml should look like:

version: '2'
services:
  db:
    image: postgres:latest
    container_name: postgres-container
    volumes:
      - ./dockerfiles/postgres/pgdata:/var/lib/postgresql/data
      - ./dockerfiles/postgres/backups:/pg_backups

Upvotes: 5

Views: 6904

Answers (2)

TitanFighter
TitanFighter

Reputation: 5094

Based on the Farhad's answer I created a file postgres_backup.sh on the host with the next content:

#!/bin/bash
# Creates Cron Job which backups DB in Docker everyday at 22:00 host time
croncmd_backup="docker exec -it postgres-container bash -c '/db_backups/script/backup.sh'"
cronjob_backup="00 22 * * * $croncmd_backup"

if [[ $# -eq 0 ]] ; then
    echo -e 'Please provide one of the arguments (example: ./postgres_backup.sh add-cron-db-backup):
    1 > add-cron-db-backup
    2 > remove-cron-db-backup

elif [[ $1 == add-cron-db-backup ]]; then
    ( crontab -l | grep -v -F "$croncmd_backup" ; echo "$cronjob_backup" ) | crontab -
    echo "==>>> Backup task added to Local (not container) Cron"

elif [[ $1 == remove-cron-db-backup ]]; then
    ( crontab -l | grep -v -F "$croncmd_backup" ) | crontab -
    echo "==>>> Backup task removed from Cron"

fi

and I added a file /db_backups/script/backup.sh to Docker's Postgres Image with the content:

#!/bin/sh
# Dump DBs

now=$(date +"%d-%m-%Y_%H-%M")
pg_dump -h db -U postgres -d postgres > "/db_backups/backups/db_dump_$now.sql"

# remove all files (type f) modified longer than 30 days ago under /db_backups/backups
find /db_backups/backups -name "*.sql" -type f -mtime +30 -delete

exit 0

Upvotes: 4

Farhad Farahi
Farhad Farahi

Reputation: 39457

Things you should know:

  1. cron service is not started by default in postgres library image.

  2. when you change cron config, you need to reload cron service.

Recommendation:

Use docker host's cron and use docker exec to launch the periodic tasks.

Advantages of this approach:

  1. Unified Configuration for all containers.

  2. Avoids running multiple cron services in multiple containers (Better usage of system resources aswell as less management overhead.

  3. Honors Microservices Philosophy.

Upvotes: 11

Related Questions