Unable to get Apache2 to run simple test perl script

But mod_perl never used to be needed to run perl CGI
You were asking for help here and complaining about it in another topic that no one knows how.
But no one here at least, seems to know why my Apache2 Perl CGI isn't working.
I will see if I can get it working without. I haven't worked with it in a long time, that's what I thought was needed.

I got it to work with mod_perl installed.
Code:
# httpd -M | grep perl
 perl_module (shared)

This is my virtualhost on CentOS10.
Code:
DocumentRoot /data/websites/test/html
<Directory /data/websites/test/html>
DirectoryIndex index.pl
AddHandler perl-script .pl
PerlResponseHandler ModPerl::Registry
Options +ExecCGI
PerlOptions +ParseHeaders
AllowOverride All
Require all granted
</Directory>
</VirtualHost>

This is my perl index file.
Code:
# cat /data/websites/test/html/index.pl
#!/usr/bin/perl

print "Content-type: text/plain\n\n";
print "Perl is working on this Apache!\n";
print "mod_perl now works!\n";

Here's the screenshot of it working.
Screenshot From 2025-09-07 00-57-46.png
 
Last edited:


I will see if I can get it working without. I haven't worked with it in a long time, that's what I thought was needed.
I also got it working without mod_perl now.

This is my perl file.
Code:
# cat /data/websites/test/html/index.pl
#!/usr/bin/perl

print "Content-type: text/plain\n\n";
print "Perl is working on this Apache!\n";
print "This is without mod_perl, it also now works!\n";

This is my virtualhost on CentOS10.
Code:
DocumentRoot /data/websites/test/html
<Directory /data/websites/test/html>
DirectoryIndex index.pl
Options +ExecCGI
AddHandler cgi-script .cgi .pl
Require all granted
</Directory>
</VirtualHost>

This is the page I see.
Screenshot From 2025-09-07 01-10-43.png
 
Last edited:
Thank you for your time experimenting with this f33dm3bits.

Is the AddHandler and Option +ExecCGI you defined there, within your specific localhost website? Mine is defined within
/etc/apache2/apach2.conf under the assumption it would be applied to all localhost sites.

This was how I saw many help articles do it.

Where configurations can be specified in different sections of Apache2 do you know which takes precedence? Also wondering the scope of AllowOverride All which also can be specified in different sections of Apache.

I'm about to to insert AddHandler and Options statements specifically into
/etc/apache2/sites-enabled/mywebsite.conf
and see if that cracks it.

If not, I'll install the mod_perl module and test again.
 
Last edited:
Where configurations can be specified in different sections of Apache2 do you know which takes precedence? Also wondering the scope of AllowOverride All which also can be specified in different sections of Apache.

I'm about to to insert AddHandler and Options statements specifically into
/etc/apache2/sites-enabled/mywebsite.conf
and see if that cracks it.
I have never looked up which takes precedence but I would think the main apache configuration file as those also lists option you don't put in your virtualhost. AllowOverride can be left out for this, I did so when I got it to work without mod_perl but I forgo to leave it out with the mod_perl example.I normally add anything I need for my virtualhost in the website specific virtualhost as you are mentioning there.
 
If not, I'll install the mod_perl module and test again.
I installed a Debian vm and try both ways which I shared in my other reply.

There are two ways also. without mod_perl, you need to install "libcgi-pm-perl" for this.

Perl index.
Code:
root@debian:/etc/apache2/sites-enabled# cat /data/websites/test/html/index.pl
#!/usr/bin/perl

print "Content-type: text/plain\n\n";
print "Perl is working on this Apache!\n";

Virtualhost without mod_perl
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /data/websites/test/html
<Directory /data/websites/test/html>
DirectoryIndex index.pl
Options +ExecCGI
AddHandler cgi-script .cgi .pl
Require all granted
</Directory>
</VirtualHost>

With mod_perl, you need to install "libapache2-mod-perl2".

Virtualhost with mod_per.
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /data/websites/test/html
<Directory /data/websites/test/html>
DirectoryIndex index.pl
AddHandler perl-script .pl
PerlResponseHandler ModPerl::Registry
Options +ExecCGI
PerlOptions +ParseHeaders
Require all granted
</Directory>
</VirtualHost>
 
Last edited:
I installed a Debian vm and try both ways which I shared in my other reply.

There are two ways also. without mod_perl, you need to install "libcgi-pm-perl" for this.

Perl index.
Code:
root@debian:/etc/apache2/sites-enabled# cat /data/websites/test/html/index.pl
#!/usr/bin/perl

print "Content-type: text/plain\n\n";
print "Perl is working on this Apache!\n";

Virtualhost without mod_perl
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /data/websites/test/html
<Directory /data/websites/test/html>
DirectoryIndex index.pl
Options +ExecCGI
AddHandler cgi-script .cgi .pl
Require all granted
</Directory>
</VirtualHost>

With mod_perl, you need to install "libapache2-mod-perl2".

Virtualhost with mod_per.
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /data/websites/test/html
<Directory /data/websites/test/html>
DirectoryIndex index.pl
AddHandler perl-script .pl
PerlResponseHandler ModPerl::Registry
Options +ExecCGI
PerlOptions +ParseHeaders
Require all granted
</Directory>
</VirtualHost>
Thank you again f33dmbits.

Since discovering that none of my Javascripts run inside Apache2 either (note they run fine when opening the HTMLs directly via browser, same as the simple Perl script runs fine inside the terminal window), I wonder if somehow, the directory paths are getting screwed up by apache. However the CSS and Graphics paths work fine. It's only Perl CGI and Javascript when run from inside Apache2.

For example inside one of the HTML <head> ... </head> blocks I have ...
<script type="text/javascript" src="Javascript/BMV100.js"></script>
<script type="text/javascript" src="Javascript/clock.js"></script>

Both of these scripts run perfectly well outside of Apache. But if the HTML page is called via localhost, neither will run.

Directory structure is thus. Are my permissions messed up? (Sorry for the lines, just trying to indent)

mywebsite (Root directory) (drwxr-xr-x 755 as reported on cstat)
_ (all html docs) _ (typically html docs set to -rw-r--r-- 644 as reported on cstat)
_ /cgi-bin ______ (drwxrwxrwx 777 as reported on cstat)
______ testPerl.pl ___ (-rwxrwxrwx 777 as reported on cstat)
_ /CSS ________ (rwxrwxr-x 775 as reported on cstat)
_ /Graphics ____ (drwxr-xr-x 755 as reported on cstat)
_ /Javascript ____ (drwxr-xr-x 755 as reported on cstat)
______ BMV100.js ___ (-rw-r--r-- 644 as reported on cstat)
______ clock.js ______ (-rw-r--r-- 644 as reported on cstat)
 
Last edited:
Since discovering that none of my Javascripts run inside Apache2 either (note they run fine when opening the HTMLs directly via browser, same as the simple Perl script runs fine inside the terminal window), I wonder if somehow, the directory paths are getting screwed up by apache. However the CSS and Graphics paths work fine. It's only Perl CGI and Javascript when run from inside Apache2.
Didn't know you had javascripts as well, I have only tested out perl scripts. If you share the current virtualhost you are using and what else you did to configure apache I will try and replicate it on my test vm or just use one of my virtualhosts examples and adjust the things you want changed and share that with the changes so I can use that to try and replicate your setup.

Both of these scripts run perfectly well outside of Apache. But if the HTML page is called via localhost, neither will run.

Directory structure is thus. Are my permissions messed up? (Sorry for the lines, just trying to indent)
The apache user should be able to at least read and execute the directories and scripts. From what I remember is that if the scripts don't have the correct permissions they won't execute and you may get a permission denied. Normally you will be able to see such things in your error.log of the virtualhost.
 
The Javascript problem was a recent discovery which I originally but mistakenly thought was caused by a browser update issue. It's very kind of you f33dmbits to try and replicate my problem for purposes of resolving it. I really do appreciate this.

What I think are the relevant default apache2 entries and settings :-
(all these files except 'mime.conf' untouched by me)

/etc/apache2/mods-enabled
cgi.load
mime.conf
perl.load
php8.1.conf
php8.1.load
python.load
(please note, I did enable cgi from the terminal)

/etc/apache2/mods-available
cgid.conf
cgid.load

/etc/apache2/conf-enabled
serve-cgi-bin.conf

/etc/apache2/sites-enabled
000-default.conf
mywebsite.conf

mywebsite.conf :-
ServerAdmin [email protected]
DocumentRoot /var/www/mywebsite
DirectoryIndex home.htm
ServerName localhost.mywebsite
ServerAlias localhost.bmv mywebsite bmv

/etc/apache2/mods-enabled/mime.conf :-
My mods here as per a Perl CGI video help I watched.
#
# AddHandler allows you to map certain file extensions to "handlers":
# actions unrelated to filetype. These can be either built into the server
# or added with the Action directive (see below)
#
# To use CGI scripts outside of ScriptAliased directories:
# (You will also need to add "ExecCGI" to the "Options" directive.)
#
# Following line uncommented out and appended with .pl .py .sh .rb .go .js .php by BAGHEERA - 1 Sep 2025
AddHandler cgi-script .cgi .pl .py .sh .rb .go .js .php

#
# For files that include their own HTTP headers:
#
# Following line uncommented out by BAGHEERA - 3 Sep 2025
AddHandler send-as-is asis

/etc/apache2.conf :-
(Just the sections where I've made modification)
NOTE: I feel somewhat suspicious of this first Directory block (default settings) in that maybe it denies some configs elsewhere?
# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>

<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>

<Directory /var/www/>
# Following line appended with ExecCGI by BAGHEERA 1 Sep 2025
Options Indexes FollowSymLinks ExecCGI

# Following line added by BAGHEERA 1 Sep 2025
AddHandler cgi-script .cgi .pl .py .sh .rb .go .js .php
AllowOverride None
Require all granted
</Directory>

#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>

If you'd like my full apache2.conf please let me know and I'll post it here in entirety.
Obviously please let me know if you'd like to see anything else. I think I've covered what you asked for.

Regarding the Javascript, interesting access-log entries for the javascripts on one of the webforms :-
127.0.0.1 - - [10/Sep/2025:00:03:44 +0100] "GET /Javascript/BMV100.js HTTP/1.1" 500 831 "http://localhost.mywebsite/candForm.htm?rolId=pdn01&clsgDat=31%20Jan%2025&catId=URG&rtnPag=reqUrg.htm&dept=Production&rolTtl=Director" "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0"
127.0.0.1 - - [10/Sep/2025:00:03:44 +0100] "GET /Javascript/clock.js HTTP/1.1" 500 831 "http://localhost.mywebsite/candForm.htm?rolId=pdn01&clsgDat=31%20Jan%2026&catId=URG&rtnPag=reqUrg.htm&dept=Production&rolTtl=Director" "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0"

The BMV100.js populates some of the webform.
clock.js turns the hands of an analog clock.
Off the top of your head, are those 500 and 831 codes signifying access errors ?
 
Last edited:
The Javascript problem was a recent discovery which I originally but mistakenly thought was caused by a browser update issue.
Just going to do the perl question now. It took me a while to get working again but I got it working again on Debian.
What I think are the relevant default apache2 entries and settings :-
(all these files except 'mime.conf' untouched by me)
I would keep your mime.conf default and add anything specific for a website within the vhost, that way you don't lose track of what made a website work. You're vhost was kind of basic, wasn't much different from mine but I created one with the same paths in it and you left out VirtualHost definitions. Also it's more readable to use fqdn name for ServerName and ServerAlias since all of the web uses that.
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /var/www/mywebsite
<Directory /var/www/mywebsite>
Options +ExecCGI
AddHandler cgi-script .cgi .pl
Require all granted
</Directory>
</VirtualHost>
You can leave out the log entries but it can be useful to debug stuff and verify things and if you don't define a log file configuration for the vhost everything will end up in the general apache log files, I have the ServerName set in my /etc/hosts file for resolving for localhost. After that the only thing I had to run was "a2enmod cgid" to enable the cgi module for Apache and then reload or restart Apache.

Here's my web files.
Code:
root@debian:# ls -l /var/www/mywebsite/home.htm /var/www/mywebsite/perl.pl
-rw-rw-r-- 1 root root 122 Sep 10 18:54 /var/www/mywebsite/home.htm
-rwxrwxr-x 1 root root  98 Sep 10 18:46 /var/www/mywebsite/perl.pl
[/QUOTE]

Requesting the html website.
[CODE]
root@debian:~# curl perl.example.com/home.htm
<!doctype html>
<html>
  <head>
    <title>This is the title of the webpage!</title>
  </head>
  <body>
  </body>
</html>

Requesting the perl script.
Code:
root@debian:~# curl perl.example.com/perl.pl
Perl is working on this Apache!

Off the top of your head, are those 500 and 831 codes signifying access errors ?
500 are errors, the number after 500 isn't anything important.

Also I tried this as you have in mime.conf
# Following line uncommented out and appended with .pl .py .sh .rb .go .js .php by BAGHEERA - 1 Sep 2025
AddHandler cgi-script .cgi .pl .py .sh .rb .go .js .php

#
# For files that include their own HTTP headers:
#
# Following line uncommented out by BAGHEERA - 3 Sep 2025
AddHandler send-as-is asis
This didn't work because you only have the the DocumentRoot defined in your vhost but you also still need to give the directory permission to execute the script with this part by defining the directory.

Code:
DocumentRoot /var/www/mywebsite
<Directory /var/www/mywebsite>
Options +ExecCGI
Require all granted
</Directory>
In instead of the above you can also do just use the root directory since you have DocumentRoot defined and that is the root directory, which then would look like this.
Code:
DocumentRoot /var/www/mywebsite
<Directory />
Options +ExecCGI
Require all granted
</Directory>

I would still recommend doing it like this because of what I mentioned previously which is because it's easier to keep track of the configurations you used to make the website work than to remember what you changed in some general used file.
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /var/www/mywebsite
<Directory /var/www/mywebsite>
#DirectoryIndex index.pl
Options +ExecCGI
AddHandler cgi-script .cgi .pl .py .sh .rb .go .js .php
AddHandler send-as-is asis
Require all granted
</Directory>
</VirtualHost>

Can you try this, I'm thinking this may also solve your javescript issue when you have those things defined in your vhost. As mentioned before putting all the necessary configurations in your vhost gives you a better overview of what configurations worked for that specific website as you tend to lose track of general configuration files that you edited.

So try out both and see where it gets you.
 
Just going to do the perl question now. It took me a while to get working again but I got it working again on Debian.

I would keep your mime.conf default and add anything specific for a website within the vhost, that way you don't lose track of what made a website work. You're vhost was kind of basic, wasn't much different from mine but I created one with the same paths in it and you left out VirtualHost definitions. Also it's more readable to use fqdn name for ServerName and ServerAlias since all of the web uses that.
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /var/www/mywebsite
<Directory /var/www/mywebsite>
Options +ExecCGI
AddHandler cgi-script .cgi .pl
Require all granted
</Directory>
</VirtualHost>
You can leave out the log entries but it can be useful to debug stuff and verify things and if you don't define a log file configuration for the vhost everything will end up in the general apache log files, I have the ServerName set in my /etc/hosts file for resolving for localhost. After that the only thing I had to run was "a2enmod cgid" to enable the cgi module for Apache and then reload or restart Apache.

Here's my web files.
Code:
root@debian:# ls -l /var/www/mywebsite/home.htm /var/www/mywebsite/perl.pl
-rw-rw-r-- 1 root root 122 Sep 10 18:54 /var/www/mywebsite/home.htm
-rwxrwxr-x 1 root root  98 Sep 10 18:46 /var/www/mywebsite/perl.pl
[/QUOTE]

Requesting the html website.
[CODE]
root@debian:~# curl perl.example.com/home.htm
<!doctype html>
<html>
  <head>
    <title>This is the title of the webpage!</title>
  </head>
  <body>
  </body>
</html>

Requesting the perl script.
Code:
root@debian:~# curl perl.example.com/perl.pl
Perl is working on this Apache!


500 are errors, the number after 500 isn't anything important.

Also I tried this as you have in mime.conf

This didn't work because you only have the the DocumentRoot defined in your vhost but you also still need to give the directory permission to execute the script with this part by defining the directory.

Code:
DocumentRoot /var/www/mywebsite
<Directory /var/www/mywebsite>
Options +ExecCGI
Require all granted
</Directory>
In instead of the above you can also do just use the root directory since you have DocumentRoot defined and that is the root directory, which then would look like this.
Code:
DocumentRoot /var/www/mywebsite
<Directory />
Options +ExecCGI
Require all granted
</Directory>

I would still recommend doing it like this because of what I mentioned previously which is because it's easier to keep track of the configurations you used to make the website work than to remember what you changed in some general used file.
Code:
<VirtualHost *:80>
ServerName perl.example.com
ErrorLog /var/log/apache2/test-error.log
CustomLog /var/log/apache2/test-access.log combined
Loglevel warn

DocumentRoot /var/www/mywebsite
<Directory /var/www/mywebsite>
#DirectoryIndex index.pl
Options +ExecCGI
AddHandler cgi-script .cgi .pl .py .sh .rb .go .js .php
AddHandler send-as-is asis
Require all granted
</Directory>
</VirtualHost>

Can you try this, I'm thinking this may also solve your javescript issue when you have those things defined in your vhost. As mentioned before putting all the necessary configurations in your vhost gives you a better overview of what configurations worked for that specific website as you tend to lose track of general configuration files that you edited.

So try out both and see where it gets you.
Thank you everso much for all that. I agree with you entirely about putting as much of the configuration in the vhost as possible, thereby leaving the rest of apache as it was installed. This is why I comment and record my mods within apache2 so it's easy to reset. them, which is what I shall now do.

I'll need to digest much of the rest of what you describe to understand better what I'd be actually doing.For example I'm quite confused calling the server perl.example.com rather than what the virtual host relates localhost.mywebsite which is what is keyed into the browser URL bar. (I initially had a lot of problems getting the home page to display through localhost) However the server name I appreciate should relate to the server that more than one virtual host is located within. (is my thinking correct there at least?)

Once I've mirrored your recommendations f33dm3bits, I'll reply back here. It'll probably be tomorrow.
Thank you again.
 
For example I'm quite confused calling the server perl.example.com rather than what the virtual host relates localhost.mywebsite which is what is keyed into the browser URL bar.
I named it that because it was about your specific question perl and I don't like using localhost as a name which I don't do either when I have a public website. So in your case I would have named it website.example.com, I just personally find using localhost confusing but yes technically you can name it whatever you want. Do what you find is best for you, I just thought I'd mention it.
 


Follow Linux.org

Members online


Top