3

I have a Django application running in AWS Elastic beanstalk.I need to run a cron job which runs a Django management command every 10 minutes (python manage.py test). For that I created a .ebextensions/cron.config file.

.ebextensions/cron.config
container_commands:
  01_some_cron_job:
    command: "cat .ebextensions/cron_test.txt > /etc/cron.d/cron_test && chmod 644 /etc/cron.d/some_cron_job"

.ebextensions/cron_test.txt

*/10 * * * * /opt/python/run/venv/bin/python34 /opt/python/current/app/manage.py  test

Is this the right way to run a Django management command as cron job in AWS elastic beanstalk? Do we need to activate the virtual environment before running the command?

Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
Nijo
  • 772
  • 1
  • 8
  • 27
  • I know it is an old question but did you find a solution to your problem? – nbeuchat Apr 19 '18 at 14:00
  • @nbeuchat no, I had another alternative to use celery for the task. – Nijo Apr 25 '18 at 05:54
  • @Nijo: Thanks! I'm looking into both, hopefully I can figure out the cron job as it seems easier for our purpose – nbeuchat Apr 25 '18 at 06:43
  • 1
    @nbeuchat you can try this http://stackoverflow.com/questions/14077095/aws-elastic-beanstalk-running-a-cronjob – Nijo Apr 25 '18 at 07:02
  • Both of the links to related articles in these comments refer to php questions, so they are not relevant here because this question is about a python environment, which is considerably different due to the virtual environment that is set up. – kloddant Oct 02 '18 at 21:49

2 Answers2

1

Yes, you need to run your command in the context of the virtual environment that Elastic Beanstalk has set up, but no, you do not need to activate said environment before running your command. At least that is my understanding of it. Example file: .ebextensions/cron.config

files:
    "/etc/cron.d/mycron":
        mode: "000644"
        owner: root
        group: root
        content: |
            MAILTO=example@example.com

            */10 * * * * root source /opt/python/current/env && python3 /opt/python/current/app/manage.py test

No guarantee that this will work - I am testing it out myself right now so there might be something wrong, but one of my coworkers got this general method to work on their site.

The documentation about Elastic Beanstalk cronjobs, but not about the virtual environment, is located here: https://aws.amazon.com/premiumsupport/knowledge-center/cron-job-elastic-beanstalk/

kloddant
  • 1,026
  • 12
  • 19
0

Hello,

for my purpose i founded a way to archived this: first you need to connect throught SSH with eb ssh. Then set your crontab to the "webapp" user :

sudo crontab -u webapp -e

On your crontab you can put your cron i.e.

* 2 * * * /var/app/venv/staging-LQM1lest/bin/python3 /var/app/current/manage.py test >> /var/log/app-logs/log-crontab.log 2>&1

(option) Finally, if you have a different settings.py file for production for instance settings_prod.py you can modify your manage.py file with :

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
from django.conf import settings


def main():
    """Run administrative tasks."""
    if os.getenv("USER") == "webapp":
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<project_name>.settings_preprod')

        import subprocess
        import ast
        def get_environ_vars():
            completed_process = subprocess.run(
                ['/opt/elasticbeanstalk/bin/get-config', 'environment'],
                stdout=subprocess.PIPE,
                text=True,
                check=True
            )

            return ast.literal_eval(completed_process.stdout)
        for key, value in get_environ_vars().items():
            os.environ[key] = value

    else:
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<project_name>.settings')



    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

If you wish I have script that set up crontab from models ! Hope it will help !