run Python script as CGI in Apache

Last updated on March 9th, 2022 at 04:13 am

This tutorial will guide you on configuring and enabling CGI in Apache web server and run python scripts. We need to make use of mod_cgi module to deliver dynamic content. In this tutorial we will configure mod_cgi and run python scripts by configuring CGI (Common Gateway Interface) in Apache. Advantage is that you can run python scripts without much complexity.

If you are wondering how to run python application using uwsgi/flask, you might be interested in this tutorial configuring uwsgi to run flask application. This method can be used for running Python application behind Nginx or Apache.

My Apache Server information

Server version: Apache/2.4.41 (Ubuntu)
 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic

Step 1: Configure Apache with CGI

$ sudo a2enmod
Your choices are: access_compat actions alias allowmethods asis auth_basic auth_digest auth_form authn_anon authn_core authn_dbd authn_dbm authn_file authn_socache authnz_fcgi authnz_ldap authz_core authz_dbd authz_dbm authz_groupfile authz_host authz_owner authz_user autoindex buffer cache cache_disk cache_socache cern_meta cgi cgid charset_lite data dav dav_fs dav_lock dbd deflate dialup dir dump_io echo env expires ext_filter file_cache filter headers heartbeat heartmonitor http2 ident imagemap include info lbmethod_bybusyness lbmethod_byrequests lbmethod_bytraffic lbmethod_heartbeat ldap log_debug log_forensic lua macro mime mime_magic mpm_event mpm_prefork mpm_worker negotiation proxy proxy_ajp proxy_balancer proxy_connect proxy_express proxy_fcgi proxy_fdpass proxy_ftp proxy_hcheck proxy_html proxy_http proxy_http2 proxy_scgi proxy_wstunnel ratelimit reflector remoteip reqtimeout request rewrite sed session session_cookie session_crypto session_dbd setenvif slotmem_plain slotmem_shm socache_dbm socache_memcache socache_shmcb speling ssl status substitute suexec unique_id userdir usertrack vhost_alias xml2enc
Which module(s) do you want to enable (wildcards ok)?
cgid
Enabling module cgid.

To activate the new configuration please restart apache ( You don’t really have to restart apache now since we are doing it again in the final step but good to do a refresh of Apache configuration since it will make sure that modules got installed successfully)

 $ sudo systemctl restart apache2

We also have a separate step by step tutorial on how to configure perl cgi script in Ubuntu

Step 2: Modify configuration file

There is a configuration file named serve-cgi-bin.conf in this location /etc/apache2/conf-enabled . Content of this file should be similar to the one below.

Note: This file normally gets created automatically. If that is not the case please create and enable it.

<IfModule mod_alias.c>
    <IfModule mod_cgi.c>
        Define ENABLE_USR_LIB_CGI_BIN
    </IfModule>
 
    <IfModule mod_cgid.c>
        Define ENABLE_USR_LIB_CGI_BIN
    </IfModule>
 
    <IfDefine ENABLE_USR_LIB_CGI_BIN>
        ScriptAlias /cgi-bin/ /var/www/pythonscript
        <Directory "/var/www/pythonscript">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            AddHandler cgi-script .cgi .py
            Require all granted
        </Directory>
    </IfDefine>
</IfModule>

Make sure to update path /var/www/pythonscript to the one you have configured (Under ScriptAlias and Directory directives)

Note: By default you can deploy your CGI script in /usr/lib/cgi-bin

As you can see above we have added .py in the AddHandler directive

AddHandler cgi-script .cgi .py

Step 3: Verify Apache syntax

Check the apache syntax and restart the service.

$sudo apachectl -t
Syntax OK
$sudo systemctl restart apache2
$

Step 4: Deploy Python script and Test

Let us create a simple python script named load.py to deploy in location /var/www/pythonscript

#!/usr/bin/python3
print ("Content-type: text/html \r\n")
print ('''<html>
<head><title>My first Python CGI app</title></head>
<body>
<p>Hello, 'world'!</p>
</body>
</html>''')

Make sure the interpreter shebang ( #!/usr/bin/python3 ) location matches the python binary installed on your server, if not change it accordingly.

Next is to test the webserver

$ curl http://localhost/cgi-bin/load.py
<html>
<head><title>My first Python CGI app</title></head>
<body>
<p>Hello, 'world'!</p>
</body>
</html>
$ curl http://localhost/cgi-bin/load.py -I
HTTP/1.1 200 OK
Date: Wed, 23 Feb 2022 15:17:13 GMT
Server: Apache/2.4.41 (Ubuntu)
Vary: Accept-Encoding
Content-Type: text/html

It works!!

2 thoughts on “Configure Apache web server to run python as cgi”
  1. Followed all this tutorial and at the end I’m getting Error 404 Not found.
    Suppose we should add all those new “pythonscript” directories into Apache2 somehow.

    1. Sorry about the super late response. If this issue still persist, Can you share the snippet of your Apache configuration ? Yes you should add those directives within the config file. Do you have /etc/apache2/conf-enabled directory?
      The file should look like this
      >lrwxrwxrwx 1 root root 36 Feb 15 2022 serve-cgi-bin.conf -> ../conf-available/serve-cgi-bin.conf

Leave a Reply

Your email address will not be published. Required fields are marked *