So I have a mariadb in a container in /home/admin/containers/mariadb
.
This directory also contains an .env
-file with MARIADB_ROOT_PASSWORD
specified.
I want to backup the database using the following command:
* * * * * root docker exec --env-file /home/admin/containers/mariadb/.env mariadb sh -c 'exec mysqldump --databases dbname -uroot -p"$MARIADB_ROOT_PASSWORD"' > /home/admin/containers/mariadb/backups/dbname.sql
The command works when running from the terminal but crontab only creates an empty sql file.
I assume there are some issues with cron ready the .env
file.
CodePudding user response:
Bash command line is nice.
Cron is "different".
Let me count the ways.
Here are things to pay attention to.
To simplify the description,
let's assume you put the above instructions
into backup.sh
, so the crontab line is simply
* * * * * root sh backup.sh
- Cron is running under UID zero here. Test interactively with:
$ sudo backup.sh
- Cron uses a restricted $PATH. Test with:
$ env PATH=/usr/bin:/bin backup.sh
- Cron's $CWD won't be your home directory.
- More generally,
env
will report different results from interactive. Your login dot files have not all been sourced. - Cron doesn't necessarily set
umask
to0022
. Likely not an issue here. - Output of
ulimit -a
might differ from what you see interactively. - Cron does not provide a pty, which can affect e.g. password prompts. Likely not an issue here.
Likely there are other details that differ.
If you find that some aspect of the
environment is crucial to a successful
run, then arrange for that near the
top of backup.sh
. You might want
to adjust PATH, source
a file,
or cd
somewhere.
Now let's examine what diagnostic clues
you're gathering from each cron run.
The most important detail is that
while you're logging stdout
,
you are regrettably discarding messages sent to
FD 2, stderr
.
You can accomplish your logging
on the crontab command line,
or within the backup.sh script.
Use 2>&1
to merge stderr with stdout.
Or capture each stream separately:
docker ... 2> errors.txt > dbname.sql
With no errors, you will see a zero-byte text file.
Also, remember the default behavior of crond.
If you just run a command, with no
redirect, cron assumes it should
complete silently with zero exit status,
such as /usr/bin/true
does.
If there's a non-zero status, cron will
report the error.
If there's any stdout text,
such as /usr/bin/date
produces,
cron wants to email you that text.
If there's any stderr text,
again it should be emailed to you.
Test your email setup.
Set the cron [email protected]
variable if the default of root
wasn't suitable.
Interactively verify that email sending on
that server actually works.
Repair your setup for postfix
or
whatever if you find that emails are
not reliably being delivered.