I have a shell script, it is not executing the "crontab" command when it is run from docker CMD. But works when I execute the file inside the docker container. What am I missing?
File entry.sh:
#!/bin/sh
echo "Starting cron"
/usr/sbin/cron -f -L 15
crontab /etc/cron.d/cron-python
Docker file:
FROM python:3
RUN apt-get update && apt-get -y install cron
COPY ./cron/entry.sh /entry.sh
COPY ./cron/crontab.txt /etc/cron.d/cron-python
RUN chmod +x /entry.sh
RUN chmod 0644 /etc/cron.d/cron-python
CMD ["./entry.sh"]
cron-python:
# crontab -e
*/1 * * * * python /app/myscript.py >> /var/log/script.log 2>&1
Following should work :
#!/bin/sh
# start cron
echo "Starting cron"
crontab /etc/cron.d/cron-python
/usr/sbin/cron -f -L 15
In your version, /etc/cron.d/cron-python does not get installed as you asked /usr/sbin/cron to run on foreground.
Also you need to copy /app/myscript.py.
Related
I am trying to set up crontab to run two docker containers on system startup/reboot. The line I use to do this after entering the command crontab -e is:
#reboot sh folder_b/run_docker_containers.bash
The script run_docker_containers.bash has the following contents:
#!/bin/bash
# Run containers based on setup_image and main_image
sudo bash /home/user/folder_a/run_setup_docker_container.bash
sudo bash /home/user/folder_b/run_main_docker_container.bash
The scripts run_setup_docker_container.bash and run_main_docker_container.bash both have the following contents (where docker_image is setup_image and main_image, respectively):
#!/bin/bash
/snap/bin/docker run \
--rm \
--detach \
--privileged \
--net=host \
--device /dev/bus/usb \
docker_image:latest \
/bin/bash -c\
"
*SOME COMMANDS*
"
export containerId=$(/snap/bin/docker ps -l -q)
However, the containers are not run when the script is executed on reboot. I prove it finds the script folder_b/run_docker_containers.bash by adding the following code to it and seeing that the new file has been created after reboot.
touch proof_that_crontab_has_done_something.txt
It seems that crontab cannot find the scripts run_setup_docker_container.bash and run_main_docker_container.bash. Any ideas where I'm going wrong?
If you want to execute a shellscript with sudo rights I would recommend using the sudo crontab.
sudo crontab -e
Your personal cronjob should not be able to start a shell with sudo rights. Unless you do some weird modifications.
Use the absolute path
#reboot /...../folder_b/run_docker_containers.bash
I am attempting to start cron automatically in an Ubuntu 20.10 (Groovy Gorilla) Docker container, thus far without success.
From previous searches (example), I've found a method to start cron using Dockerfile as follows:
# Install and enable cron
RUN apt-get install systemd -y
RUN apt-get install cron -y
RUN systemctl enable cron
# Copy cron file to the cron.d directory
COPY cronfile /etc/cron.d/cronfile
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/cronfile
# Apply cron job
RUN crontab /etc/cron.d/cronfile
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
CMD cron && tail -f /var/log/cron.log
However, I can't make this work with my server setup. I have another, later, CMD in my Dockerfile (similar to this):
CMD ["/usr/sbin/run-lamp.sh"]
and of course only the second CMD will be run. I have tried combining multiple commands:
CMD cron && tail -f /var/log/cron.log && /usr/sbin/run-lamp.sh
but this does not run run-lamp.sh. I also tried putting the commands inside run-lamp.sh, but nothing has resulted in cron starting. Having said that, it is very easy to start cron manually, by opening up a shell in the container and entering the following:
# cron
# crontab /etc/cron.d/cronfile
I am open to suggestions.
All the files I'm working with are available here:
https://github.com/Downes/gRSShopper
In particular:
Dockerfile:
https://github.com/Downes/gRSShopper/blob/master/Dockerfile
run-lamp.sh:
https://github.com/Downes/gRSShopper/blob/master/run-lamp.sh
cronfile:
https://github.com/Downes/gRSShopper/blob/master/cronfile
Thanks in advance.
First off, you don't need that tail -f /var/log/cron.log, it's useless in a container.
Secondly, tail -f is designed to only stop on a signal, and you never signal it, so it will not stop, and therefore the next command, run-lamp.sh, will not run.
Here's a minimal reproducer:
entrypoint.sh:
#!/bin/bash
touch /tmp/x
sleep 120
cronfile:
* * * * * touch /tmp/y
# An empty line is required at the end of this file for a valid cron file.
Dockerfile:
FROM ubuntu:20.10
RUN apt-get update
RUN apt-get install systemd -y
RUN apt-get install cron -y
RUN systemctl enable cron
# Copy cron file to the cron.d directory
COPY cronfile /etc/cron.d/cronfile
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/cronfile
# Apply cron job
RUN crontab /etc/cron.d/cronfile
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
CMD cron && tail -f /var/log/cron.log
COPY entrypoint.sh /entrypoint.sh
CMD /entrypoint.sh
Test command:
docker build -t lamp . \
&& docker rm -f lamp \
&& docker run -d --name lamp lamp \
&& echo waiting for cron... \
&& sleep 61 \
&& docker exec lamp ls /tmp \
&& docker exec lamp sh -c "ps -e | grep cron || echo no cron"
Result:
Sending build context to Docker daemon 71.17kB
Step 1/12 : FROM ubuntu:20.10
...
Successfully tagged lamp:latest
lamp
0fbe19e0583b178543ccf1d1108f72b7f3f6dffb664122621bc67d5939b66672
waiting for cron...
x
no cron
However, with this Dockerfile:
FROM ubuntu:20.10
RUN apt-get update
RUN apt-get install systemd -y
RUN apt-get install cron -y
RUN systemctl enable cron
# Copy cron file to the cron.d directory
COPY cronfile /etc/cron.d/cronfile
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/cronfile
# Apply cron job
RUN crontab /etc/cron.d/cronfile
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
COPY entrypoint.sh /entrypoint.sh
# Run everything in parallel with '&', even the useless tail command
CMD /entrypoint.sh & cron & tail -f /var/log/cron.log
Result:
Sending build context to Docker daemon 87.55kB
Step 1/11 : FROM ubuntu:20.10
...
Successfully tagged lamp:latest
lamp
99dca45fe135326ca96ea90fe21ff7ae23689a56fab5cf0c2ccd8252bc4be84a
waiting for cron...
x
y
10 ? 00:00:00 cron
hey guys not sure what I am doing wrong here, but was hoping for some help.
I have a bash script with the following.
#!/bin/bash
docker exec -t wekan-db bash -c "scripts/wekandb_backup.sh"
docker exec -t wekan-db bash -c "rm -r /dump/*; cp -r /mongodb_backup/ /dump/mongodb_backup"
docker cp wekan-db:/dump /home/ikadmin/codes/backup/wekan/$(date +%Y-%m-%d)
Everything executes correctly when I run the bash script from the terminal.
However when I try to run it via crontab -e it does not work. Logs do show crontab trying to run it.
Just in case the bash script is currently set as 777 as well.
Any help would be appreciated
EDIT: crontab command
19 8 * * * /bin/bash /home/ikadmin/codes/scripts/backup-wekan-docker.sh
I would like to run a bash script periodically inside a Docker container (my work is based on this answer: https://stackoverflow.com/a/37458519/6240756)
Here is my script hello.sh:
#!/bin/sh
echo "Hello world" >> /var/log/cron.log 2>&1
Here is the cron file hello-cron:
# m h dom mon dow command
* * * * * /app/hello.sh
# Empty line
And here is my Dockerfile:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y cron
# Add backup script
COPY hello.sh /app/
RUN chmod +x /app/hello.sh
# Configure the cron
# Copy file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Start the cron
CMD cron && tail -f /var/log/cron.log
I build and run the container but nothing happens. I should see "Hello world" displayed every minutes.
If I replace the call to the script in the cron file by directly echo "Hello world" >> /var/log/cron.log 2>&1 it works, I see "Hello world" every minutes
What am I doing wrong?
EDIT
And the Docker commands:
docker build -t hello-cron .
docker run -t -i hello-cron
About your concrete question
The problem is that you're launching your docker with -t -i, and what you want is a background execution and check it interactively.
Try with:
docker run -d --name mycontainer hello-cron
docker logs -f mycontainer
Best practices
If you are going to execute something periodically, consider if it should be in healthcheck definition, where you can set period and other variables.
Second, note that your cron.log is not mounted, so, you'd lose this info if docker restart.
#!/bin/bash
docker exec -ti erpnext sh -c "cd /home/frappe/frappe-bench/ &&
/usr/local/bin/bench backup"
echo 'Hello, world.' >foo.txt
The above code is my bash file.
Here have two command
create txt file
execute docker container
If I run this command
cd /home/arifur/workspace_python/erpdatabasebackup && bash backup_database.sh
in terminal then it is working
But when I run in crontab
* * * * * cd /home/arifur/workspace_python/erpdatabasebackup && bash backup_database.sh
then only txt file creation is working but docker container is not working.
The -ti requests to use a pseudo-tty and run in interactive mode but cron does not attach to any TTY. Try removing -ti as in
docker exec erpnext sh -c "cd /home/frappe/frappe-bench/ && /usr/local/bin/bench backup"