Last updated on November 6th, 2024 at 07:57 pm
This tutorial aims to assist you in the configuration and activation of CGI within the Apache web server, enabling the execution of Python scripts. To provide dynamic content, it is essential to utilize the mod_cgi module. Throughout this tutorial, we will set up mod_cgi and facilitate the execution of Python scripts by configuring the Common Gateway Interface (CGI) in Apache. The primary benefit of this approach is the ability to run Python scripts with minimal 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!!