The problem
Python script invoked from PHP via shell_exec and runs fine when PHP invoked from command line but fails when PHP triggered by browser access.
Reason
PHP, when triggered by a browser access is invoked by web server with the user www-data, while from the command line it is run as user ubuntu.
Attempting to see what happens when running PHP from the command line as user www-data would help to understand why running the script fails
One method to run php as www-data from the command line is to enable a shell for www-data user. This is done by modifying /etc/passwd so that user www-data has a shell (change the existing /usr/sbin/nologin or whatever to /bin/bash or something similar) and then sudo su www-data
and try to run the python script again (see this reply for details).
Doing the above, quickly showed that the one of the imports in the python script fails when running it under www-data.
Comparing python3 -m site
when running under user www-data vs. when running under ubuntu showed there is a difference in the module search paths.
Adding the missing path found for user ubuntu to user www-data via sys.path.insert
was not scalable, nor possible (since the ubuntu user path is inaccessible to the www-data user), so the best way was to install the python modules (in my case, imagehash) in a way that will be accessible to the www-data user
The solution, found here illustrated how this is done
sudo mkdir /var/www/.local sudo mkdir /var/www/.cache sudo chown www-data.www-data /var/www/.local sudo chown www-data.www-data /var/www/.cache sudo -H -u www-data pip install imagehash
Method #2 ∞
Of course, a simpler alternative to this is to run apache as ubuntu, which will make all the above unnecessary assuming the situation/security requirements enable it, in which case you might want to also change the htdocs directory:
sudo vim /etc/apache2/envvars # change APACHE_RUN_USER and APACHE_RUN_GROUP to ubuntu cd /etc/apache2/sites-available/ sudo cp 000-default.conf 000-ubuntu.conf sudo vim 000-ubuntu.conf # change the path for DocumentRoot sudo a2dissite 000-default.conf sudo a2ensite 000-ubuntu.conf
Also,
sudo vim /etc/apache2/apache2.conf
and add the following:
<Directory /home/ubuntu/> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>
Don’t forget to
sudo systemctl restart apache2
or
service apache2 reload
Method2 is not working.
I tested the method 2 in my local, but the same error occures.
I uses python selenium and wanna to run the script inside the php web app.
but when I run the script inside php, it says it can not find the selenium module.
I changed the www-data to my user name of ubuntu.
Let me know what is the solution.
Thank you.
That was so extremely helpful for me. I spend hours to figure out a solution for my issue. Thanks a lot
How do i do this but with python3 for www-data to access? im runing a python 3 script from php and its not returning the output like it does in command line!
Method #1 works fine! Thanks for this!
Please, could you add the eror message “ModuleNotFoundError: ” in your “it fails” description?
It safes a lot of time for searching.
Thank you!