Crontab Launches Python Script but SystemD Does Not? - python

I can log into my AWS EC2 server via ssh and type:
cd /opt/myWebApp
sudo python3 /opt/myWebApp/manage.py myCronJob
...and it runs.
I can also launch the same script via crontab:
0 */6 * * * sudo python3 /opt/myWebApp/manage.py myCronJob --settings=server.settings.production
But when I try to run it in SystemD, with .service file:
ExecStart='/usr/bin/python3.7' /opt/myWebApp/manage.py myCronJob --settings=server.settings.production
...I get:
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?
$PYTHONPATH and $VIRTUAL_ENV are empty. /opt/myWebApp/server_venv is empty as well. There's a python at /usr/bin/python3.7, but I'm referencing that in the SystemD .service file as noted above, and it's throwing that error.
What am I missing?

Solved it!
ExecStart='/etc/alternatives/python3' ./manage.py myCronJob --settings=server.settings.production
WorkingDirectory=/opt/myWebapp
User=myUser
The user ('myUser' in the above code) has access to Django.

Related

How do I run a cronjob with a python virtual environment?

Usually I SSH into my EC2 instance and run:
source MYVENV/bin/activate
How do I set my cronjob to activate the virtual environment? My Django script requires ENVIRONMENT variables that are stores in ~/.bash_profile
I tried following the steps here to no avail
Cron and virtualenv
SHELL=/bin/bash
*/1 * * * * root source /home/ec2-user/MYVENV/activate && python /home/script.py
This is my current setup above.
I get this following error in the log:
/bin/bash: root: command not found
create a shell script
eg scripts.sh
#!/bin/bash
source /home/user/MYVENV/bin/activate
python /path/to/file/script.py
Then in cron put
*/1 * * * * bash /path/to/shell/script/scripts.sh
The script will load all your environment variables and execute from the python in your environment
you can just run the python interpretor from your environment directly eg
MYENV/bin/python script.py
to find out what is the directory to your environment python interpretor, change into the virtual env then run
which python
in your case, this should become
*/1 * * * * /home/ec2-user/MYVENV/python /home/script.py
you can create a single wrapper bash script for executing your Django script. See the example below.
#!/bin/bash -l // this should pick up your ~/.bash_profile environment variables
cd /path to project dir/ // set it up if your project is not in python path
source /Users/<user>/.virtualenvs/dslab/bin/activate // this activates your environment
python /home/script.py // run your script

Can't run PyCharm interpreter as root

I am trying to use Kubernetes python SDK.
I tried to run the following code:
from kubernetes import client, config
# Configs can be set in Configuration class directly or using helper utility
config.load_kube_config()
v1 = client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
It failed with lots of errors.
When I run the same code with python from a shell, the same issue.
When I run the same code with sudo python from shell, it works.
I am trying to run PyCharm interperte as root.
Following the instruction from JetBrains, I created a script shell with the name pythonCustomInt.sh that contains:
sudo python
I went to PyCharm settings > Project Interpreter and changed the Base interpreter to /<path>/pythonCutomInt.sh but it writes an error:
Environment location directory is not empty
I am not sure where I need to put the script.
Any idea?
I ran sudo -s and then from the pycharm folder (pycharm-community-2018.1.4/bin) I ran sh ./pycharm.sh and it worked.

Start django app as service

I want to create service that will be start with ubuntu and will have ability to use django models etc..
This service will create thread util.WorkerThread and wait some data in main.py
if __name__ == '__main__':
bot.polling(none_stop=True)
How I can to do this. I just don't know what I need to looking for.
If you also can say how I can create ubuntu autostart service with script like that, please tell me )
P.S. all django project run via uwsgi in emperor mode.
The easiest way in my opinion is create a script and run on crontab.
First of all create a script to start your django app.
#!/bin/bash
cd /path/to your/virtual environment #path to your virtual environment
. bin/activate #Activate your virtual environment
cd /path/to your/project directory #After that go to your project directory
python manage.py runserver #run django server
Save the script and open crontab with the command:
crontab -e
Now edit the crontab file and write on the last line:
#reboot path/to/your/script.sh
This way is not the best but the easiest, if you are not comfortable with Linux startup service creation.
I hope this help you :)
Take a look at supervisord. It is much easier than daemonizing python script.
Config it something like this:
[program:watcher]
command = /usr/bin/python /path/to/main.py
stdout_logfile = /var/log/main-stdout.log
stdout_logfile_maxbytes = 10MB
stdout_logfile_backups = 5
stderr_logfile = /var/log/main-stderr.log
stderr_logfile_maxbytes = 10MB
stderr_logfile_backups = 5
Ok, that is answer - https://www.raspberrypi-spy.co.uk/2015/10/how-to-autorun-a-python-script-on-boot-using-systemd/
In new versions ubuntu services .conf in /etc/init fail with error Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused
But services works using systemd

manage.py command in crontab not working

I have created a executeable script .sh which contains code to run a django managemenet command.
cron.sh
#!/bin/sh
. /path/to/env/activate
cd /path/to/project
/path/to/env/bin/python manage.py some_command
I can confirm this script and manage.py command is working by executing it directly on terminal
$ /path/to/cron.sh
When i do it same via crontab its not working as expected.
** What am i doing wrong ?? I can confirm there is nothing wrong with crontab, it executing the cron.sh file but path/to/env/bin/python manage.py some_command is not working as expected.
cron log also showing
CRON[14768]: (root) CMD /path/to/cron.sh > /dev/null 2>&1
I am using bitnami django ami (ubuntu 14.04.5 LTS)
Update
After removing /dev/null i am getting this error now
"Cannot locate wrapped file"
It seems that it is a PATH problem. I do not know if django uses specific paths that must be set but AFAIK the crontab PATH is really limited due to security reasons. Just to check if that is the problem you could do in a shell terminal the following:
echo $PATH
You will get a complete PATH for instance:
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
In your crontab, put it above your code:
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
Tell me if this works. If does, try to purge the provided PATH or even better provide absolute locations in your code.
I have to say that I don't know if you can perform a cd in the cron like this. I always used absolute paths or cd /some/dir && /path/to/script args.
P.S: I cannot make comments yet, for this reason I put it in an answer.
The problem is that your not using the script that Bitnami uses to load all the environment variables (/opt/bitnami/scritps/setenv.sh).
I would try using this script:
#!/bin/sh
. /opt/bitnami/scritps/setenv.sh
. /path/to/env/activate
cd /path/to/project
/path/to/env/bin/python manage.py some_command

Run manage.py from AWS EB Linux instance

How to run manage.py from AWS EB (Elastic Beanstalk) Linux instance?
If I run it from '/opt/python/current/app', it shows the below exception.
Traceback (most recent call last):
File "./manage.py", line 8, in <module>
from django.core.management import execute_from_command_line
ImportError: No module named django.core.management
I think it's related with virtualenv. Any hints?
How to run manage.py from AWS Elastic Beanstalk AMI.
SSH login to Linux (eb ssh)
(optional may need to run sudo su - to have proper permissions)
source /opt/python/run/venv/bin/activate
source /opt/python/current/env
cd /opt/python/current/app
python manage.py <commands>
Or, you can run command as like the below:
cd /opt/python/current/app
/opt/python/run/venv/bin/python manage.py <command>
With the new version of Python paths seem to have changed.
The app is in /var/app/current
The virtual environment is in /var/app/venv/[KEY]
So the instructions are:
SSH to the machine using eb shh
Check the path of your environment with ls /var/app/venv/. The only folder should be the [KEY] for the next step
Activate the environment with source /var/app/venv/[KEY]/bin/activate
Execute the command python3 /var/app/current/manage.py <command>
Of course Amazon can change it anytime.
TL;DR
This answer assumes you have installed EB CLI. Follow these steps:
Connect to your running instance using ssh.
eb ssh <environment-name>
Once you are inside your environment, load the environment variables (this is important for database configuration)
. /opt/python/current/env
If you wish you can see the environment variables using printenv.
Activate your virtual environment
source /opt/python/run/venv/bin/activate
Navigate to your project directory (this will depend on your latest deployment, so use the number of your latest deployment instead of XX)
cd /opt/python/bundle/XX/app/
Run the command you wish:
python manage.py <command_name>
Running example
Asumming that your environment name is my-env, your latest deployment number is 13, and you want to run the shell command:
eb ssh my-env # 1
. /opt/python/current/env # 2
source /opt/python/run/venv/bin/activate # 3
cd /opt/python/bundle/13/app/ # 4
python manage.py shell # 5
As of February 2022 the solution is as follows:
$ eb ssh
$ sudo su -
$ export $(cat /opt/elasticbeanstalk/deployment/env | xargs)
$ source /var/app/venv/*/bin/activate
$ python3 /var/app/current/manage.py <command name>
$ export $(cat /opt/elasticbeanstalk/deployment/env | xargs) is needed to import your environment variables if you have a database connection (most likely you will)

Categories