Use CGI Scripts with Apache on Ubuntu 26.04
CGI scripts are programs that Apache runs to build a web page when someone asks for it. To set one up on Ubuntu 26.04, install Apache2, turn on the cgid module, add an executable script to /usr/lib/cgi-bin, and restart Apache. This guide covers Linux commands. Use it in an Ubuntu 26.04 virtual machine, on a server you reach over SSH, or in a WSL (Windows Subsystem for Linux) Ubuntu window on your Windows PC.
To run a CGI script on Apache in Ubuntu 26.04, install Apache2 with sudo apt install -y apache2, enable the cgid module with sudo a2enmod cgid, and restart Apache with sudo systemctl restart apache2. Then save an executable script in /usr/lib/cgi-bin and open http://localhost/cgi-bin/test.cgi in a browser.
Before you start
Commands that start with sudo need an account with administrator (sudo) rights, and Ubuntu asks for your password the first time.
If you use WSL, systemd (the service manager that starts Apache) must be running in your Ubuntu instance for the systemctl commands to work. If they fail, use a virtual machine instead.
Install Apache2
Skip this section if Apache2 is already installed and serving its default page.
Install the package
- Open your Ubuntu terminal.
- Update the package list. This requires administrator rights.Bash / Shell
sudo apt update
- Install Apache2. This requires administrator rights.Bash / Shell
sudo apt install -y apache2
- Check that the service is running.Code
systemctl status apache2
You should see active (running) in green. Pressqto leave the status screen.
Enable the CGI module
Ubuntu’s Apache uses the event MPM (the part of Apache that handles connections in threads). With that setup, CGI needs cgid, a version of the CGI module built for threaded Apache. Turn it on as shown below.
Turn on cgid and restart Apache
- Enable the module. This requires administrator rights.Ubuntu prints a message saying the module is enabled, or already enabled.Bash / Shell
sudo a2enmod cgid
- Restart Apache so it loads the module. This requires administrator rights.Bash / Shell
sudo systemctl restart apache2
Ubuntu’s default setup already maps the /cgi-bin/ URL to the folder /usr/lib/cgi-bin. Once cgid is on, that folder works with no extra configuration. You can write your first script there.
Create and test a CGI script
A CGI script must print an HTTP header first, then a blank line, then the page content. If the header is missing, Apache returns a 500 error.
Write a test script
- Create a new file in the CGI folder. This requires administrator rights.Bash / Shell
sudo nano /usr/lib/cgi-bin/test.cgi
- Type or paste this script:Code
#!/bin/bash
echo "Content-Type: text/html"
echo ""
echo "<html><body>"
echo "<h1>CGI is working</h1>"
echo "<p>Server time: $(date)</p>"
echo "</body></html>" - Press Ctrl+O, then Enter to save.
- Press Ctrl+X to close nano.
Make the script executable
Apache can only run a file that has the execute permission. Give the script that permission so Apache can run it.
- Set the permissions. This requires administrator rights.Bash / Shell
sudo chmod 755 /usr/lib/cgi-bin/test.cgi
- Open a browser on the same machine, or on your Windows PC if you use WSL, and go to:For a remote server, replaceCode
http://localhost/cgi-bin/test.cgi
localhostwith the server’s address, for example192.0.2.10. - Look for the heading CGI is working and the current server time.
Run CGI scripts from a different folder
Use this method if you want scripts next to your website files instead of in /usr/lib/cgi-bin. You tell Apache that one folder may run programs and which file extensions count as scripts.
Create the folder and the configuration
- Create the folder. This requires administrator rights.Bash / Shell
sudo mkdir /var/www/html/cgi
- Create a configuration file. This requires administrator rights.Bash / Shell
sudo nano /etc/apache2/conf-available/my-cgi.conf
- Add these lines:Code
<Directory /var/www/html/cgi>
Options +ExecCGI
AddHandler cgi-script .cgi .py
</Directory>Options +ExecCGIallows programs to run in the folder.AddHandlertells Apache that files ending in.cgior.pyare scripts. - Save the file with Ctrl+O, Enter, then close nano with Ctrl+X.
- Enable the configuration. This requires administrator rights.Bash / Shell
sudo a2enconf my-cgi
- Check the syntax before you restart.The output should end with Syntax OK. If it shows an error, reopen the file and fix the line it names.Bash / Shell
sudo apache2ctl configtest
- Restart Apache. This requires administrator rights.Bash / Shell
sudo systemctl restart apache2
Add and test a Python script
- Create the script. This requires administrator rights.Bash / Shell
sudo nano /var/www/html/cgi/hello.py
- Add this code:Code
#!/usr/bin/python3
print("Content-Type: text/html")
print()
print("<h1>Hello from Python CGI</h1>") - Save and close the file.
- Make it executable. This requires administrator rights.Bash / Shell
sudo chmod 755 /var/www/html/cgi/hello.py
- Browse to
http://localhost/cgi/hello.py. You should see Hello from Python CGI.
Fix a 500 Internal Server Error
A 500 error means Apache found the script but could not run it. The error log usually names the cause.
- Open the Apache error log to see why the script failed. Read the last lines, which hold the newest entries. This requires administrator rights.Bash / Shell
sudo tail -n 20 /var/log/apache2/error.log
- Look for Permission denied. If you see it, run
chmod 755on the script again. - Look for malformed header or End of script output before headers. If you see either, make sure the script prints
Content-Typefirst, followed by a blank line. - Look for bad interpreter. If you see it, check the first line of the script (the line that starts with
#!and names the program that runs it) for a wrong program path or Windows line endings.
Windows line endings are a common trap if you write the script in Notepad and copy it over. Linux treats the hidden carriage return (a character Windows adds at the end of each line) as part of the command, so the script fails. Remove it with this command. It requires administrator rights if the file sits in a protected folder.
sudo sed -i 's/\r$//' /usr/lib/cgi-bin/test.cgi
Undo the changes
- Disable the custom folder configuration, if you created it. This requires administrator rights.Bash / Shell
sudo a2disconf my-cgi
- Disable the CGI module. This requires administrator rights.Bash / Shell
sudo a2dismod cgid
- Restart Apache. This requires administrator rights.Bash / Shell
sudo systemctl restart apache2
What to do next
If a script still fails after the checks above, run the command sudo apache2ctl configtest again and read the error log while you reload the page. When CGI works, the next task is usually running PHP, which Apache handles through its own module rather than CGI.
Have a question about this guide?
Answered by AI from this guide. Good questions may be added to this page — please don't include personal details.
Did this guide fix your problem?
About the Author
Richard
Tech Writer, IT Professional
Richard is a writer at Geek Rewind who turns complex IT tasks into clear, step-by-step guides. He draws on years of hands-on experience in system administration and enterprise IT operations, focusing on Windows, Linux and WordPress: the problems people actually run into, and the fixes that work. His server and WordPress guides come from systems he runs himself. Richard builds and maintains the platform behind Geek Rewind, from its Ubuntu servers and Nginx configuration to its custom WordPress plugins. Many new tutorials start with readers' questions, and he's always glad to answer them in the comments.
No comments yet — be the first to share your thoughts!