0
votes

It took me quite a while to figure out how to make Apache2.4 run my "Hello, world!" python script. I have finally figured out what sequence of commands I have to run in the command line for the script to work. Unfortunately, I still don't understand what is happening when I run those commands. I would like to know why they make my script work. I know it's all in the documentation, but so far I find it a bit hard to comprehend what's written there.

Here goes the list of commands I used.

  1. sudo apt-get install apache2
  2. sudo a2dismod mpm_event
  3. sudo a2enmod mpm_prefork
  4. sudo service apache2 restart
  5. sudo a2enmod cgi
  6. sudo service apache2 restart

Any comments on steps 2, 3 and 5 would be highly appreciated.

After that I create script.py in /usr/lib/cgi-bin:

#! /usr/bin/python
print "Content-type: text/html\n\n"
print "Hello, world!"

For some reason the first two lines of the script.py are absolutely necessary. There is no way the code is going to run without them.

And finally I run:

sudo chmod +x /usr/lib/cgi-bin/script.py #why do I need this? how come it is not executable by default?
sudo service apache2 restart

When I call http://localhost/cgi-bin/script.py I get my Hello, world!

I didn't even have to modify apache2.conf, serve-cgi-bin.conf or 000-default.conf

If there is a more obvious/better/correct way to run a python script using Apache24, I would really love to learn it.

P.S. Some people recommend adding AddHandler cgi-script .py .cgi to /etc/apache2/conf-enabled/serve-cgi-bin.conf if you encounter a problem when running a script on Apache. But for some reason it doesn't make any difference in my case. Why?

P.P.S. I use Ubuntu 14.04.

2
You must have the shebang at the top of the script to specify which interpreter to use (in this case python). You must also set execute permission on the file using chmod() so the webserver may execute it. Just adding any file into the cgi-bin doesn't automatically gives it execute permission.Cyclonecode
The code runs without the second line, but apache will give 500 error anyhow.Antti Haapala
And the better way is to use mod_wsgi with any web framework (Pyramid, Flask, Django, etc...)Antti Haapala
Thank you. And what about mpm_event and mpm_prefork, what are they all about?Teiko Abe

2 Answers

0
votes

The mpm stands for Multi-Processing Module; basically you replaced the event based approach with the prefork; this is used internally by Apache and often does not affect anything beyond performance (each of these have different performance characteristics), but some things are not compatible with some MPM's and then you need to change them.

The cgi module is an additional module that provides the Common Gateway Interface; it is not included in Apache by default anymore.

The first line of the script is the shebang; it tells Unix/Linux kernel what program to use as the interpreter; that is; "use /usr/bin/python to run this file please". The file extensions do not mean anything in *nix w.r.t executability.

The second line are the headers. The CGI specification says that the output shall be headers followed by an empty line, followed by the content. 1 header is mandatory: the Content-Type. Here you are telling the webserver and browser, that what follows is a document of type text/html. '\n' stands for a newline. (Technically you should write

print "Content-type: text/html\n\n",

with a comma there, otherwise you get one newline too much).

Files in *nix don't have the +x execute bit on by default - this is a security feature; a conscious decision is required to make something executable.


As for the preferred method, since you control the server, use the Apache mod_wsgi with any web framework - Pyramid, Flask, Django, etc; WSGI applications are much more efficient than the CGI.

0
votes
  1. The event Multi-Processing Module (MPM) is designed to allow more requests to be served simultaneously by passing off some processing work to supporting threads, freeing up the main threads to work on new requests. http://httpd.apache.org/docs/2.2/mod/event.html

  2. This Multi-Processing Module (MPM) implements a non-threaded, pre-forking web server. Each server process may answer incoming requests, and a parent process manages the size of the server pool. It is appropriate for sites that need to avoid threading for compatibility with non-thread-safe libraries. It is also the best MPM for isolating each request, so that a problem with a single request will not affect any other. http://httpd.apache.org/docs/current/mod/prefork.html

5)

a2enmod is a script that enables the specified module within the apache2 configuration. http://manpages.ubuntu.com/manpages/lucid/man8/a2enmod.8.html

The name a2enmod stands for apache2 enable module.

For some reason the first two lines of the script.py are absolutely necessary.

The first one tells apache how to execute your cgi script. After all, there are other server side languages, like php, perl, ruby, etc. How is apache supposed to know which server side language you are using?

The second line outputs an HTTP header, which is the simplest header you can use. The headers are required to be output before the body of the request--that's the way the http protocol works.

sudo chmod +x /usr/lib/cgi-bin/script.py 

why do I need this? how come it is not executable by default?

A file cannot be executed unless an administrator has given permission to do so. That is for security reasons.

If there is a more obvious/better/correct way to run a python script using Apache24, I would really love to learn it.

Most of the commands you listed are to setup the apache configuration. You shouldn't have to run those commands every time you execute a cgi script. Once apache is configured, all you should have to do is start apache, then request a web page.

P.S. Some people recommend adding:

AddHandler cgi-script .py .cgi 

to /etc/apache2/conf-enabled/serve-cgi-bin.conf if you encounter a problem when running a script on Apache. But for some reason it doesn't make any difference in my case. Why?

See here:

AddHandler handler-name extension [extension]

Files having the name extension will be served by the specified handler-name. This mapping is added to any already in force, overriding any mappings that already exist for the same extension. For example, to activate CGI scripts with the file extension .cgi, you might use:

AddHandler cgi-script .cgi

Once that has been put into your httpd.conf file, any file containing the .cgi extension will be treated as a CGI program. http://httpd.apache.org/docs/2.2/mod/mod_mime.html#addhandler

So it appears that when you add the AddHandler line it is overriding a configuration setting somewhere that does the same thing.

Response to comment:

ScriptInterpreterSource Directive

This directive is used to control how Apache httpd finds the interpreter used to run CGI scripts. The default setting is Script. This causes Apache httpd to use the interpreter pointed to by the shebang line (first line, starting with #!) in the script http://httpd.apache.org/docs/current/mod/core.html

On the same page, there is this directive:

CGIMapExtension Directive

This directive is used to control how Apache httpd finds the interpreter used to run CGI scripts. For example, setting CGIMapExtension sys:\foo.nlm .foo will cause all CGI script files with a .foo extension to be passed to the FOO interpreter.