I'm trying to use Python as the server-scripting language instead of PHP.

I've configured localhost and php files run fine under it.

If I create a file .../localhost/temp/test.cgi (making it executable):


print( """Content-type:text/html\n\n
            <!DOCTYPE html>
            <html lang="en">
                    <meta charset="utf-8"/>
                    <title>My server-side template</title>
                <body>""" )
print( "</body></html>")

... it doesn't run as a Python script: the text of the file just gets displayed in the browser.

I've done quite a bit of searching on this. I have no such file, for example, as httpd.conf. My Apache2 setup is like this: executable in /usr/sbin/apache2, with most configuration files apparently under /etc/apache2, and in particular, seemingly, /sites-available, where one finds two files, 000-default.conf and default-ssl.conf.

I may be mistaken, but I believe httpd.conf is the "old" Apache way of doing things.

I found a totally baffling but (just) possibly promising line at the bottom of 000-default.conf:

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf

... so I uncommented that and restarted the apache2 service. No difference.

Details of 000-default.conf
(in /etc/apache2/sites-available). NB when I was struggling to change the localhost directory changes in this file seemed to do that.

<VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that...

    ServerAdmin webmaster@localhost

    DocumentRoot "/media/mike/W10 D drive/My Documents/localhost"
    <Directory />
                Options FollowSymLinks
                 AllowOverride All 
    <Directory /media/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Require all granted

I don't know where CGI scripts are meant to go or where they are configured (although I am about to examine the first answer below), but given that I want them to be used with the .html files under .../localhost/ as above, I want that location to be "CGI-enabled".

It turns out that a short answer to this question (specifically) was, in my case, simply to add "ExecCGI" as one of the "Options" in the <Directory> tag or block or whatever it's called.


2 Answers 2


There are a few extra steps you need to take.

  1. Enable the CGI subsystem with a2enmod cgid
  2. Uncomment the CGI handler in mods-enabled/mime.conf, or include this directive in your specific vHost section

    AddHandler cgi-script .cgi
  3. Include Options ExecCGI in the vHost or topmost directory where you want these programs to be available

For testing, what I did was to include the CGI handler and ExecCGI statements in my sites-enabled/000-default.conf file

<VirtualHost *:80>

        AddHandler cgi-script .cgi

        <Directory "/var/www/html">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

                Require all granted

I was then able to create and run executable scripts, such as time.cgi

  • Thanks very much. Does not seem to affect PHP functioning. Could you say what you mean by "for testing"? I tried restarting the Apache service (apache2) and browsing to the page after each step here: the last step seems necessary to get things to work. May 12, 2020 at 6:06
  • I'm sorry but i don't understand your comment. I gave three required steps; they are all necessary. Why should it affect PHP? When I tested the instructions I chose not to change the standard files but instead I put the configuration statements into the default vHost. This would not be best practice for a production system. May 12, 2020 at 8:00
  • I just meant, what did you mean by "for testing"? I wondered whether that was a significant expression, i.e. "testing" as contrasted with "the real thing" or "when running a real app" ... I think I've read too much into that expression! May 12, 2020 at 8:03
  • You could run with the configuration per my example, but in a professional best practice environment it's not what I'd do. (It would depend on the number of vHosts, what the server was being used for, etc.) I'd recommend you follow the three steps I gave. Does that help? May 12, 2020 at 8:04
  • Yes, it does. But now you've got me intrigued. It would probably take a long time for you to say in what way this is not "professional best practice", but could you point me somewhere or suggest something to search on (to learn more)? May 12, 2020 at 8:06

Your Apache setup looks like it's on Debian and on my system serve-cgi-bin.conf is already enabled, i.e. there is a symlink /etc/apache2/conf-enabled/serve-cgi-bin.conf to ../conf-available/serve-cgi-bin.conf.

If the symlink is missing on your system, run

sudo a2enconf serve-cgi-bin

You don't need to uncomment the line in 000-default.conf.

The file looks like this:

$ cat /etc/apache2/conf-available/serve-cgi-bin.conf
<IfModule mod_alias.c>
        <IfModule mod_cgi.c>
                Define ENABLE_USR_LIB_CGI_BIN

        <IfModule mod_cgid.c>
                Define ENABLE_USR_LIB_CGI_BIN

        <IfDefine ENABLE_USR_LIB_CGI_BIN>
                ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
                <Directory "/usr/lib/cgi-bin">
                        AllowOverride None
                        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                        Require all granted

The cgi directory is /usr/lib/cgi-bin, move your executable into this directory. You need to enable mod_cgi or mod_cgid, let's take the first one and restart the server.

sudo a2enmod cgi
sudo systemctl restart apache2

Go to http://localhost/cgi-bin/test.cgi and you should be greeted with "TEST".

If you want to use a different directory or different ScriptAlias path, you can disable serve-cgi-bin.conf (sudo a2disconf serve-cgi-bin) and copy the content of serve-cgi-bin.conf into your VirtualHost and change the locations as needed.

  • The OP isn't using the ancient /cgi-bin/ structure - they've got a file test.cgi inside what I assume is DocumentRoot May 11, 2020 at 16:21
  • You might be right. In that case OP needs to enable one of the cgi modules and add SetHandler cgi-script and Options +ExecCGI to the corresponding <Directory> as described in the ScriptAlias Directive.
    – Freddy
    May 11, 2020 at 16:40
  • Thanks both. Just going to follow these things up. I confirm that localhost is the document root. Updating my question to show settings, in 000-default.conf. May 11, 2020 at 16:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .