The python documentation for modwsgi seems to fit what you are asking for. The following webpage has a really simple example and the necessary configuration for a python3-apache2 setup.
http://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html
You will need to install the mod_wsgi for the configuration to work. Take note of the different "_" underscore and "-" dash character used in apt and pip3.
$ sudo apt install apache2-dev libapache2-mod-wsgi-py3
$ sudo pip3 install mod_wsgi
libapache2-mod-wsgi-py3 and mod_wsgi seems to be the same thing. However, my test deployment only works after installing mod_wsgi. Could be configuration issue. The following are the details of the configuration I have tested on Ubuntu 16.04.2.
Application file /home/user/wsgi_sample/hello.wsgi:
def application(environ, start_response):
status = '200 OK'
output = b'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Apache2 configuration /etc/apache2/sites-available/000-test.conf
<VirtualHost *:80>
ServerName testmachine
<Directory /home/user/wsgi_sample>
Order allow,deny
Allow from all
Require all granted
</Directory>
WSGIScriptAlias /hello /home/user/wsgi_sample/hello.wsgi
</VirtualHost>
Enable the site in apache2.
sudo a2ensite 000-test.conf
Open your browser to testmachine/hello.
wsgi may also be deployed on Apache2 using passenger. It demands a slighter longer configuration. Ask a new question if passenger/python3 is desired.
Answer from Devakhim on Stack OverflowThe python documentation for modwsgi seems to fit what you are asking for. The following webpage has a really simple example and the necessary configuration for a python3-apache2 setup.
http://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html
You will need to install the mod_wsgi for the configuration to work. Take note of the different "_" underscore and "-" dash character used in apt and pip3.
$ sudo apt install apache2-dev libapache2-mod-wsgi-py3
$ sudo pip3 install mod_wsgi
libapache2-mod-wsgi-py3 and mod_wsgi seems to be the same thing. However, my test deployment only works after installing mod_wsgi. Could be configuration issue. The following are the details of the configuration I have tested on Ubuntu 16.04.2.
Application file /home/user/wsgi_sample/hello.wsgi:
def application(environ, start_response):
status = '200 OK'
output = b'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Apache2 configuration /etc/apache2/sites-available/000-test.conf
<VirtualHost *:80>
ServerName testmachine
<Directory /home/user/wsgi_sample>
Order allow,deny
Allow from all
Require all granted
</Directory>
WSGIScriptAlias /hello /home/user/wsgi_sample/hello.wsgi
</VirtualHost>
Enable the site in apache2.
sudo a2ensite 000-test.conf
Open your browser to testmachine/hello.
wsgi may also be deployed on Apache2 using passenger. It demands a slighter longer configuration. Ask a new question if passenger/python3 is desired.
Yes, your minimum code seem correct. The Apache config information is answered here https://stackoverflow.com/a/57531411/4084546
I think you have installed mod_wsgi for python2 with this command:
sudo apt-get install libapache2-mod-wsgi
But if you want to use mod_wsgi with python3, you should install correct mod_wsgi with this command:
sudo apt-get install libapache2-mod-wsgi-py3
To change a python version on per user basis you simply create an alias within user's home directory. Open ~/.bashrc file and add new alias to change your default python executable:
alias python='/usr/bin/python3.4'
Once you make the above change, re-login or source your .bashrc file:
$ . ~/.bashrc
Check your default python version:
$ python --version
Python 3.4.2
Change python version system-wide
To change python version system-wide we can use update-alternatives command. Logged in as a root user, first list all available python alternatives:
# update-alternatives --list python
update-alternatives: error: no alternatives for python
The above error message means that no python alternatives has been recognized by update-alternatives command. For this reason we need to update our alternatives table and include both python2.7 and python3.4:
# update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
update-alternatives: using /usr/bin/python2.7 to provide /usr/bin/python (python) in auto mode
# update-alternatives --install /usr/bin/python python /usr/bin/python3.4 2
update-alternatives: using /usr/bin/python3.4 to provide /usr/bin/python (python) in auto mode
The --install option take multiple arguments from which it will be able to create a symbolic link. The last argument specified it priority means, if no manual alternative selection is made the alternative with the highest priority number will be set. In our case we have set a priority 2 for /usr/bin/python3.4 and as a result the /usr/bin/python3.4 was set as default python version automatically by update-alternatives command.
# python --version
Python 3.4.2
Next, we can again list all python alternatives:
# update-alternatives --list python
/usr/bin/python2.7
/usr/bin/python3.4
From now on, we can anytime switch between the above listed python alternative versions using below command and entering a selection number:
# update-alternatives --config python
How to use Python 3 and Django with Apache? - Stack Overflow
apache - Executing a Python script in Apache2 - Stack Overflow
ubuntu - How to get apache to use python3.6 and its modules? - Stack Overflow
Quickest way to run python script via apache on Debian (11) - Unix & Linux Stack Exchange
Django 1.6+ and mod_wsgi 3.4+ are required to use Python 3 with Apache. For more detail refer to scot's answer.
These answers are no longer true of Django 1.6 - it supports python3. The mod_wsgi page says version 3.4 supports python 3. https://code.google.com/p/modwsgi/
Don't know if it all works at this point though (I will return and edit when I find out)!
The answer is YES it works!
I have an AWS EC3 Ubuntu instance running Python3, Django 1.5.6, Apache2.2 and mod_wsgi 3.4
Python 3.3.4:
sudo add-apt-repository ppa:fkrull/deadsnakes
sudo apt-get install python3.3
sudo apt-get install python3.3-dev python3.3-doc idle-python3.3
ppa:fkrull/deadsnakes is a apt repo has has multiple python versions available - see https://launchpad.net/~fkrull/+archive/deadsnakes
Then I added pip using the instructions at the pip page; http://pip.readthedocs.org/en/latest/installing.html. (remember your python is probably on your path as 'python3.3' at this point, plain 'python' will point at python 2.x!)
After that, virtualenv. Then I virtualenv'd the python installation. Upon activation and adding the environment's bin/ directory to the $PATH I've now got a clean python3.
Then, after I activated the virtual env, I did 'pip Django' and all my other necessary packages (which were quite a few). I have Django version 1.6.2 (I've been developing on this and running under python 3.3.3 on my Mac no problem).
The most trouble I had was installing lxml because it requires libxml2 and libxslt to be installed with apt-get (it is a wrapper around the C code) and it took me a couple of attempts to realise that they were not already installed (lxml compilation fails).
After tossing about getting my RDS database instance up and running and available (postgresql, beware mysql under python3, you'll get plenty of python db driver pain! but most of my issues were caused by me trying to understand the AWS security configuration), it was relatively plain sailing:
sudo apt-get install apache2 apache2-threaded-dev
That installs apache - and you need the dev packages for the next bit.
And that point, I tried using the apt package for mod_wsgi but I decided that the best thing to do was to compile and install it myself, following the instructions here - https://code.google.com/p/modwsgi/wiki/InstallationInstructions
I had no problems with configure, make, or make install. Make sure you compile it in your virtualenv activated environment.
You have to manually add the configuration to Apache's configuration:
# wsgi module
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so
# now configure it
<Directory /my/app/path>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
WSGIScriptAlias / /my/app/path/wsgi.py
WSGIPythonPath /my/app:/path/to/the/virtual/env/lib/python3.3/site-packages
And in the broadest possible way, this is all now working.
The first line of httpd.conf: AddHandler cgi-script .cgi .pl is irrelevant, since you're testing python scripts and not perl scripts. And you should define those directives within the location of your python script, and tell apache that it should execute cgi scripts in that location: Options +ExecCGI. This snippet would be a start:
<Directory /path/to/sample.py />
Options +ExecCGI
AddHandler cgi-script .py
</Directory>
Addendum 1:
As per my last comment, try this script. It should spit information about the cgi environment.
#!/usr/bin/python
import cgi
cgi.test()
Addendum 2:
I got your script to work with the above configuration. The problem is that script is written in python2. And the default interpreter apache is invoking to execute the script, is python3 (at least in my case, and chances are this would be the same for you too).
This is a python3 version of the hello world script:
#!/usr/bin/env python
# enable debugging
import cgitb
cgitb.enable()
print("Content-Type: text/plain;charset=utf-8")
print()
print("Hello World!")
Addendum 3:
For the first error, make sure the permission and the ownership of whatever directory and files you're attempting to deploy are properly set. And try adding those directives to httpd.conf:
Order allow,deny
Allow from all
Which will get you this:
<Directory /path/to/sample.py />
Options +ExecCGI
AddHandler cgi-script .py
Order allow,deny
Allow from all
</Directory>
For the second error, unless I am missing something, it looks like apache is invoking python 3 interpreter to execute your script. To rule out this possibility, you might try the following:
ls -al /usr/bin/python*
This will list the python interpreters available on your system. If you have more than one interpreter you'll get something similar to this output:
/usr/bin/python -> python3*
/usr/bin/python2.6*
/usr/bin/python3*
If not, it would be this output:
/usr/bin/python -> python2.6*
/usr/bin/python2.6*
To make sure, this is not the issue you're having, try with this modified sample script:
#!/usr/bin/python2.6
# enable debugging
import cgitb
cgitb.enable()
print "Content-Type: text/plain\r\n\r\n"
print
print "Hello World!"
You'll notice that I explicitly mentioned the version of the interpreter apache should invoke, which is ugly. But for the sake of testing, you can do it. Of course you should map #!/usr/bin/python2.6, to whatever binary you have on your server, and make sure you don't mix python 3 comtipable code with python 2 interpreter and vice versa.
Re: The Exec format error.
I've run in to this myself a couple of times before. I had the exact same (cryptic) error message.
I was developing Python (3) scripts to use via CGI in Notepad++ on my Windows machine, and then uploading them to my Linux server.
After much frustration, I discovered that this issue is related to line endings and you need to convert Windows line endings (\r\n) to UNIX line endings (\n).
In Notepad++ (6.1.5), you can achieve this by going to the Edit menu and selecting the EOL conversion option and then saving the file.