cron can't see systemctl --user services - cron

I have a user cronjob I setup with:
$ crontab -e
*/5 * * * * systemctl --user is-active test.service >> ~/test.txt
But for some reason the service is always displayed as offline when executed with cron, but not when I manually execute:
systemctl --user is-active test.service
Is this some kind of permission issue or how could I otherwise test that a service is still running periodically.

Related

Docker: cron within container no errors but still not working

I am new to docker. Managed to create a script which gets info from online source and populates an SQL DB. All works well within docker container.
However, I need to make this to run for example every minute.
So I amended my working Dockerfile and added the following:
Dockerfile:
RUN apt-get install -y cron
COPY cronms /etc/cron.d/cronms
RUN chmod 0644 /etc/cron.d/cronms
RUN crontab /etc/cron.d/cronms
RUN touch /var/log/cron.log
CMD cron && tail -f /var/log/cron.log
#CMD [ "python3", "./my_script.py" ] -- command before cron
my cronms file:
*/1 * * * * /usr/bin/python3 /my_script.py
Image builds without errors however when running it data is not being downloaded.
What I am missing please?
Thanks
Your crontab file has incorrect syntax. From the cron man page:
The system crontab (/etc/crontab) and the packages crontabs (/etc/cron.d/*) use the same format, except that the username for the command is specified after the time and date fields and before the command.
So your cronms file should look like:
*/1 * * * * root /usr/bin/python3 /my_script.py
I assume the Dockerfile in your question is truncated, but it's worth noting that for this to work you may need to explicitly install python3 as well as cron, depending on which base image you're using.
If I build an image using this Dockerfile:
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y cron python3
COPY cronms /etc/cron.d/cronms
RUN chmod 0644 /etc/cron.d/cronms
RUN crontab /etc/cron.d/cronms
RUN touch /var/log/cron.log
COPY my_script.py /my_script.py
CMD cron && tail -f /var/log/cron.log
And this cronms:
*/1 * * * * root /usr/bin/python3 /my_script.py
And this my_script.py:
#!/usr/bin/python3
import time
with open("/tmp/datafile", "a") as fd:
fd.write(time.ctime())
fd.write("\n")
Then I can confirm that everything works as expected: the script is
executed once a minute.
Note that nothing is written to /var/log/cron.log, however,
because cron logs to syslog, not to a file. To see output from
cron, you would need to arrange to run a syslog daemon, or use a
different cron daemon (for example, the busybox crond command can
log to a file or stderr).

Start a system service in the Postgres docker container

I want to extends the postgres:10.2 Dockerfile in order to add a cron job doing some SQL queries at specific dates:
FROM postgres:10.2
COPY task-purge.sh /usr/local/share/
RUN chown postgres:postgres /usr/local/share/task-purge.sh
RUN chmod 700 /usr/local/share/task-purge.sh
COPY query-task-purge.sql /usr/local/share/
RUN chown postgres:postgres /usr/local/share/query-task-purge.sql
RUN chmod 700 /usr/local/share/query-task-purge.sql
The problem is: the cron service is not started:
Inside the docker container:
root#5c17ce88c333:/# service cron status
[FAIL] cron is not running ... failed!
root#5c17ce88c333:/# pgrep cron
root#5c17ce88c333:/#
I have difficulties to start it ...
In the Dockerfile, I tried :
To add RUN service cron start: nothing change
To add CMD service cron start: when the container starts, it ends with Starting periodic command scheduler: cron without starting the DB.
To add CMD postgres && service cron start: when the container starts, it ends with "root" execution of the PostgreSQL server is not permitted. without starting the DB.
To add a wrappere CMD script like https://docs.docker.com/config/containers/multi-service_container/: same behaviour.
To add ENTRYPOINT "docker-entrypoint.sh" && service cron start: idem
To add service cron start in a new docker-entrypoint.sh (modified from the official postgres:10.2 Dockerfile https://hub.docker.com/layers/postgres/library/postgres/10.2/images/sha256-4b6b7bd361a3b7b69531b2c16766a38b0f3a89e9243f5a49ff16180dd2d42273?context=explore): Starting periodic command scheduler: croncron: can't open or create /var/run/crond.pid: Permission denied failed!
To add update-rc.d cron defaults && update-rc.d cron enable to the docker-entrypoint.sh: nothing change.
To add set -- su-exec root:root /bin/bash -c "service cron start": nothing change
To add set -- su-exec root:root /bin/bash -c "update-rc.d cron defaults && update-rc.d cron enable": nothing change
To add gosu root:root /bin/bash -c "service cron start": the container ends with error: failed switching to "root:root": operation not permitted.
To add exec gosu root:root /bin/bash -c "service cron start": the container ends with Starting periodic command scheduler: cron.
Do you have any idea how I can run a system service before postgres start ? And I want to extends postgres:10.2.
Thanks !
Ok, I have understand why ... I answer my own question to help everybody : the docker-entrypoint.sh script runs a exec gosu postgres "$BASH_SOURCE" "$#" command (even in the last postgres version: https://github.com/docker-library/postgres/blob/master/docker-entrypoint.sh) which call again this script but as postgres user.
So every system operations needs to be executed before this command.
For example: write a function called system_configure and call it before that line:
# ... (outside main)
system_configure() {
echo "[x] Crontab service start ..."
service cron start
echo "[x] Crontab service started"
}
# ... (inside main function path)
system_configure
exec gosu postgres "$BASH_SOURCE" "$#"
# ... (end main)
You could also use any other docker image like ubuntu with supervisord, but prefers distroless image for security reasons.
Just run it once in your Dockerfile using:
RUN service cron start

How to run commands on CentOS reboot

I want to run the following commands one after the other upon reboot of the server after I do shutdown -r now but not sure how to do it:
getenforce
setenforce 0
systemctl start httpd.service
I'm running CentOS 7.x
Technically you can crontab it
sudo crontab -e
and add the line
#reboot /somewhere/myscript.sh
and put the 3 commands in the myscript.sh with the proper rights.
But it is a bad idea since you can you just make these changes permanent:
systemctl enable httpd
and
vim /etc/selinux/config
to set the SELINUX variable to permissive
This will make the configuration permanent across reboot.

Why doesn't the cron service in Dockerfile run?

While searching for this issue I found that: cron -f should start the service.
So I have:
RUN apt-get install -qq -y git cron
Next I have:
CMD cron -f && crontab -l > pullCron && echo "* * * * * git -C ${HOMEDIR} pull" >> pullCron && crontab pullCron && rm pullCron
My dockerfile deploys without errors but the cron doesn't run. What can I do to start the cron service with an added line?
PS:
I know that the git function in my cron should actually be a hook, but for me (and probably for others) this is about learning how to set crons with Docker :-)
PPS:
Complete Dockerfile (UPDATED):
RUN apt-get update && apt-get upgrade -y
RUN mkdir -p /var/log/supervisor
RUN apt-get install -qq -y nginx git supervisor cron wget
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN wget -O ./supervisord.conf https://raw.githubusercontent.com/..../supervisord.conf
RUN mv ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN apt-get install software-properties-common -y && apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449 && add-apt-repository 'deb http://dl.hhvm.com/ubuntu utopic main' && apt-get update && apt-get install hhvm -y
RUN cd ${HOMEDIR} && git clone ${GITDIR} && mv ./tybalt/* ./ && rm -r ./tybalt && git init
RUN echo "* * * * * 'cd ${HOMEDIR} && /usr/bin/git pull origin master'" >> pullCron && crontab pullCron && rm pullCron
EXPOSE 80
CMD ["/usr/bin/supervisord"]
PPPS:
Supervisord.conf:
[supervisord]
autostart=true
autorestart=true
nodaemon=true
[program:nginx]
command=/usr/sbin/nginx -c /etc/nginx/nginx.conf
[program:cron]
command = cron -f -L 15
autostart=true
autorestart=true
Having started crond with supervisor, your cron jobs should be executed. Here are the troubleshooting steps you can take to make sure cron is running
Is the cron daemon running in the container? Login to the container and run ps a | grep cron to find out. Use docker exec -ti CONTAINERID /bin/bash to login to the container.
Is supervisord running?
In my setup for instance, the following supervisor configuration works without a problem. The image is ubuntu:14.04. I have CMD ["/usr/bin/supervisord"] in the Dockerfile.
[supervisord]
nodaemon=true
[program:crond]
command = /usr/sbin/cron
user = root
autostart = true
Try another simple cron job to findout whether the problem is your cron entry or the cron daemon. Add this when logged in to the container with crontab -e :
* * * * * echo "hi there" >> /tmp/test
Check the container logs for any further information on cron:
docker logs CONTAINERID | grep -i cron
These are just a few troubleshooting tips you can follow.
Cron is not running because only the last CMD overrides the first one (as #xuhdev said). It's documented here : https://docs.docker.com/reference/builder/#cmd.
There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect.
If you want to have nginx and cron running in the same container, you will need to use some kind of supervisor (like supervisord or others) that will be the pid 1 process of your container and manage the chield processes. I think this project should help : https://github.com/nbraquart/docker-nginx-php5-cron (it seems to do what you're trying to achieve).
Depending on what you're cron is here for, there would be other solution to that — like building a new image for each commit or each tags, etc...
I've used this with CentOS and it works:
CMD service crond start ; tail -f /var/log/cron
The rest of my Dockerfile just yum installs cronie and touches the /var/log/cron file so it will be there when the CMD runs.
On centos 7 this works for me
[program:cron]
command=/usr/sbin/crond -n -s
user = root
autostart = true
stderr_logfile=/var/log/cron.err.log
stdout_logfile=/var/log/cron.log
-n is for foreground
-s is to log to stdout and stderr
In my case, it turns out I needed to run cron start at run time. I can't put it in my Dockerfile nor docker-compose.yml, so I ended up placing in the Makefile I use for deploy.
Something like:
task-name:
# docker-compose down && docker-compose build && docker-compose up -d
docker exec CONTAINERNAME /bin/bash -c cron start

admin crontab won't run sudo command

sudo: no tty present and no askpass program specified
Hi I am getting the above error when ever I try to get the following crontab to run.
*/5 * * * * sudo bash /home/admin/scripts/monitor.sh /dev/null 2>&1
I am using nano as the editor to edit the admin user crontab - note this is not root user.
EDITOR=nano crontab -e -u admin
1) Disable requiretty in sudoers file
2) Permit script execution without password:
admin ALL=(ALL) NOPASSWD: /home/admin/scripts/monitor.sh
3) I'm not sure but you don't need specify bash after sudo. Just add #! /bin/bash at the begin of the script
*/5 * * * * sudo /home/admin/scripts/monitor.sh /dev/null 2>&1

Resources