Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Django Crontab Job Not Executing Within Docker Container #130

Open
kazimovzaman2 opened this issue Aug 27, 2023 · 11 comments
Open

Django Crontab Job Not Executing Within Docker Container #130

kazimovzaman2 opened this issue Aug 27, 2023 · 11 comments

Comments

@kazimovzaman2
Copy link

I am facing an issue with running Django crontab jobs within a Docker container. The crontab jobs work perfectly in my local development environment, but when I dockerize my Django app and attempt to run it within a container, the crontab jobs do not seem to execute as expected.

Here's a breakdown of the setup and the problem I'm encountering:

Local Development (Working): In my local development setup, I have added the following configuration to my Django settings:

THIRD_PARTY_APPS = [
    "django_crontab",
]

CRONJOBS = [
    ("* * * * *", "apps.{path}.jobs.deactivate_expired_enrollments"),
]

This configuration sets up a crontab job that deactivates expired course enrollments. The crontab job works perfectly in this environment.

Docker Setup: To dockerize my Django app, I've created a Dockerfile and a start.sh script as part of my Docker Compose configuration:
Dockerfile:

# Install apt packages
RUN apt-get update && apt-get install --no-install-recommends -y \
    # Installing cron
    cron \

RUN touch /var/log/cron.log

RUN (crontab -l ; echo "* * * * * echo 'Hello world' >> /var/log/cron.log") | crontab

# Run the command on container startup
CMD cron && tail -f /var/log/cron.log

start.sh:

#!/bin/bash

set -o errexit
set -o pipefail
set -o nounset

python manage.py migrate
python manage.py crontab add
python manage.py runserver 0.0.0.0:8000

# crontab -l
* * * * * echo Hello world >> /var/log/cron.log
* * * * * /usr/local/bin/python /app/manage.py crontab run b428252730534a0b85d6be057a9debe1 # django-cronjobs for config

The Issue: After setting up the Docker environment and running my Django app within a container, I see that the crontab job is correctly registered when I run python manage.py crontab show. However, the job does not execute as expected. Even though the job is shown as active, it doesn't run at the specified interval. The command python manage.py crontab run {cron_id} executes the job only once, but it doesn't run automatically as it should.
I have checked various aspects such as the Docker setup, the way I'm configuring the crontab job, and the interaction between Docker and the crontab service. Everything seems correct, and I'm not receiving any error messages that could point me in the right direction for debugging.

I am reaching out for help in understanding why the crontab jobs are not running as expected within the Docker container. If anyone has experience with running Django crontab jobs within a Dockerized environment and can provide insights into potential pitfalls, configuration adjustments, or troubleshooting steps, I would greatly appreciate it.

Thank you for your time and assistance.

In an attempt to resolve the issue of crontab jobs not running within the Docker container, I added the service cron start command to the start.sh script. My intention was to manually start the cron service within the container, hoping that this might trigger the execution of the crontab jobs. But does not work.

@Telewa
Copy link

Telewa commented Aug 31, 2023

This may work for you

When you start your docker container, start the cron service as well.

service cron start

Ref: #62 (comment)

@kazimovzaman2
Copy link
Author

This may work for you

When you start your docker container, start the cron service as well.

service cron start

Ref: #62 (comment)

I tried, but does not work.

@Telewa
Copy link

Telewa commented Sep 1, 2023

As an alternative, do not use django-crontab

Instead try this:

In your Dockerfile:

RUN apt update && apt-get install -y cron

before starting your container (start.sh):


# this ensures that the cron can run your Django commands with the env data loaded
env > /etc/environment

# Add your cron job here
echo "SHELL=/bin/bash" > /etc/cron.d/my_custom_cron

echo "* * * * * cd /my_app && /usr/local/bin/python manage.py deactivate_expired_enrollments >> /proc/1/fd/1 2>&1" >> /etc/cron.d/my_custom_cron

service cron start

crontab /etc/cron.d/my_custom_cron

Then create a manage.py command called deactivate_expired_enrollments.
When you run python manage.py deactivate_expired_enrollments it should do what you want the cron to do.

So the cron will just call the manage command at specified intervals.

@tuanhopham
Copy link

@kazimovzaman2
Have you fixed that error yet?
I'm stuck with the same situation :(

@kazimovzaman2
Copy link
Author

@kazimovzaman2 Have you fixed that error yet? I'm stuck with the same situation :(

Nope, I can't ;(

@GorlikItsMe
Copy link

I found a solution!

Check this: https://stackoverflow.com/questions/27771781/how-can-i-access-docker-set-environment-variables-from-a-cron-job

update your docker files and add:

RUN apt-get update \
    && apt-get install -y cron

and add to entrypoint.sh

touch /var/log/cron.log
printenv | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID|LANG|PWD|GPG_KEY|_=' >> /etc/environment

python manage.py crontab remove
python manage.py crontab add
service cron start

This will install cron and copy all env variables to place where cron can see them.

@tuanhopham
Copy link

I found a solution!

Check this: https://stackoverflow.com/questions/27771781/how-can-i-access-docker-set-environment-variables-from-a-cron-job

update your docker files and add:

RUN apt-get update \
    && apt-get install -y cron

and add to entrypoint.sh

touch /var/log/cron.log
printenv | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID|LANG|PWD|GPG_KEY|_=' >> /etc/environment

python manage.py crontab remove
python manage.py crontab add
service cron start

This will install cron and copy all env variables to place where cron can see them.

thanks.It has worked well for me.
additionally if you are using apk package instead of apt-get then use dcron
replace

RUN apt-get update \
    && apt-get install -y cron

to

RUN apk add --update --no-cache dcron

@igorer88
Copy link

It doesn't work with alpine distro neither 😞

@rafaelalmeida2909
Copy link

@tuanhopham u saved me!!! THANKS, BRO!!

@apanagar
Copy link

apanagar commented Oct 24, 2024

The issue here is that cron gets its environment variables from /etc/environment.

For docker, in your entry point script just add the line
printenv > /etc/environment to get all your environment variables into your cron environment.

If you want to verify for yourself, you can add this code to the top of your script and run it from the command line and also from cron, and compare the environment variables in both cases.

import os
os.system("printenv")

@Christian-pprogrammer
Copy link

I found a solution!

Check this: https://stackoverflow.com/questions/27771781/how-can-i-access-docker-set-environment-variables-from-a-cron-job

update your docker files and add:

RUN apt-get update \
    && apt-get install -y cron

and add to entrypoint.sh

touch /var/log/cron.log
printenv | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID|LANG|PWD|GPG_KEY|_=' >> /etc/environment

python manage.py crontab remove
python manage.py crontab add
service cron start

This will install cron and copy all env variables to place where cron can see them.

You saved me, thanks a lot ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants