I'm unsure what's going on here:
I've got a backup script which runs fine under root. It produces a >300kb database dump in the proper directory.
When running it as a cron job with exactly the same command however, an empty gzip file appears with nothing in it.
The cron log shows no error, just that the command has been run.
This is the script:
#! /bin/bash
DIR="/opt/backup"
YMD=$(date "+%Y-%m-%d")
su -c "pg_dump -U postgres mydatabasename | gzip -6 > "$DIR/database_backup.$YMD.gz" " postgres
# delete backup files older than 60 days
OLD=$(find $DIR -type d -mtime +60)
if [ -n "$OLD" ] ; then
echo deleting old backup files: $OLD
echo $OLD | xargs rm -rfv
fi
When changed to:
pg_dump -U postgres mydatabasename | gzip -6 > "$DIR/database_backup.$YMD.gz"
The same thing happens.
And the cron job:
01 10 * * * root sh /opt/daily_backup_script.sh
It produces a database_backup file, just an empty one. Anyone know what's going on here?
edit:
Ok, simplified to this but it's still not working via cron
#! /bin/bash
DIR="/opt/backup"
YMD=$(date "+%Y-%m-%d")
pg_dumpall -U postgres > "$DIR/database_backup.$YMD"
And
01 10 * * * root /opt/daily_backup_script.sh
You need to specify the full path to
pg_dump
-- cron runs it's scripts with a very restrictivePATH
by default.Assumptions:
I assume that your credentials for postgress database are stored in
~/.pgpass
and file's permissions are set to0600
and that you are usingPG*
environment variables.Reason:
The reason that your backup command works (creates backup of database) when run from the terminal, and is not working (creates empty file) when run from crontab is the environment.
Cause:
When you run a command in crontab, (even when you enforce to execute it as a desired user (eg.
su - root -c 'my_aesome_command'
) the environment variables for requested user are different from environment variables as they are set when user is logged in terminal.Solution:
I fixed this problem by adding specific user's environment variables to
/etc/environment
file by executing this commandenv >> /etc/environment
when I load my backup script (actually when I load my container since I am working with docker)