Last updated: August 2025

Apache and PHP

Apache and PHP

Note: This article series covers configuring Debian 12 for hosting multiple domains and web sites on a single dedicated server. As such, some strategies may be inappropriate for your environment. Sockets for example are appropriate for communication between services hosted on the same machine but not suited to a set up with distributed services (where you'd use ports). Please consult the overview for more information.


Operating System: Debian 12
Apache: version 2.4.62 (Debian)
PHP: version 8.2.29

Once you've got your DNS set up and Certbot installed it's time to set up your first web site. We're going to use Apache web server which serves up many of the world biggest web sites and we're going to install PHP for processing your server side scripts.

Once you've logged in to your server, start by updating your package manager:

sudo apt update

Then install Apache and PHP:

sudo apt install apache2
sudo apt install php libapache2-mod-php php-mysql


If you run a firewall, now would be a good time to poke a couple of holes in it, you want to open port 80 and 443. 80 is the standard web site port and 443 is the secure SSL version.

Apache needs to know where your web sites are stored so edit the configuration, mine will be on that SSD drive we set up earlier in the Drives article:

sudo nano /etc/apache2/apache2.conf

<Directory /mnt/d1/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

Enable the rewrite module

'Mod Rewrite' as it's known allows you to create a list of redirection rules for your web site. You can set these rules in your Apache site file or optionally in a file in your web site folder (.htaccess).

To enable the rewrite module:

sudo a2enmod rewrite

Restart Apache:

sudo systemctl restart apache2.service

It is most efficient to define your redirection rules in your Apache site file but I choose convenience over efficiency in this case because it means that you can transfer your redirection rules just by copying the web site files (it uses the .htaccess file).

If you want to enable the .htaccess file method, you have to edit the AllowOverride option in your Apache configuration file and set it to All:

sudo nano /etc/apache2/apache2.conf

<Directory /mnt/d1/www/>
	Options Indexes FollowSymLinks
	AllowOverride All
	Require all granted
</Directory>
Restart Apache:

sudo systemctl restart apache2.service

I also like to make sure the short_open_tag option is enabled in the PHP file because it allows me to write <? instead of <?php which is really useful when I want to insert the output of a function or variable into my HTML (you can just go <?=my_function()?> or <?=my_variable?>).

sudo nano /etc/php/8.2/apache2/php.ini

short_open_tag = On

Restart Apache to pick up the change:

sudo systemctl restart apache2.service

Install Common PHP Modules

I usually install a couple of common modules for PHP because some of my sites manipulate images and take payments.

Install PHP Curl (useful for payment gateways like Paypal):

sudo apt install php-curl

Install GD (for image manipulation)

sudo apt install php-gd

Restart Apache to pick up the changes:

sudo systemctl restart apache2.service

Set up a web site

You can set a web site up on Apache at any time but if you want to secure it with SSL using Certbot you'll need to make sure your DNS is working properly.

To check this, you can ping it (which just sends a message to your server, which it then returns) but first I'd recommend clearing down your DNS cache (just a list of host names and IP addresses) so you know you're getting a current result, on Ubuntu:

Older Ubuntu
sudo systemd-resolve --flush-caches

Newer Ubuntu
sudo resolvectl flush-caches

Then ping the primary domain name of the web site you intend to set up:

eg. ping benosborne.com

PING benosborne.com (74.201.177.83) 56(84) bytes of data.
64 bytes from blnkserver.com (74.201.177.83): icmp_seq=1 ttl=51 time=140 ms
64 bytes from blnkserver.com (74.201.177.83): icmp_seq=2 ttl=51 time=139 ms
64 bytes from blnkserver.com (74.201.177.83): icmp_seq=3 ttl=51 time=139 ms
64 bytes from blnkserver.com (74.201.177.83): icmp_seq=4 ttl=51 time=140 ms

--- benosborne.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 138.585/139.496/140.494/0.754 ms
If it's working then you'll see that the domain name has been resolved to one of your server DNS IP addresses, ping will send packets of data to your server and it will tell you if they're returned.

If your web site DNS is working then your results should look similar to the above and you're ready to set up your web site.

First of all, create a basic virtualhost configuration file for your web site when it runs on port 80 (insecure) in the Apache sites-available directory, you want this to be named the primary domain name followed by .conf. Obviously, use your settings for the parameters defined below:

sudo nano /etc/apache2/sites-available/benosborne.com.conf

<VirtualHost *:80>
    ServerAdmin admin@benosborne.com
    ServerName benosborne.com
    ServerAlias *.benosborne.com
    DocumentRoot /mnt/d1/www/benosborne.com
    DirectoryIndex index.php
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Now we're going to create a directory for it on our drive and create a simple home page (index.php) as per the parameters we defined:

sudo mkdir /mnt/d1/www/benosborne.com
sudo nano /mnt/d1/www/benosborne.com/index.php


<?php
phpinfo();
?>
phpinfo(); just outputs the PHP settings for you. Make sure you save the file.

Enable the site in Apache:

sudo a2ensite benosborne.com

Basically, this command creates a symlink in /etc/apache2/sites-enabled which points back to your virtualhost file.

Because we haven't added any new modules or changed any server configuration we can get away with using the Apache service reload option (instead of restart) which you'll want to use later because it won't interrupt your other web sites:

sudo systemctl reload apache2.service

Give your site a test by trying to visit it in a web browser, I say 'try' because these days a lot of browsers will fight you tooth and nail to prevent you visiting an insecure site.

"Are you sure you wish to visit that dangerous web site that doesn't have SSL?"

Not to worry, if it complains about it being insecure then you know it tried to load it, which means it's working!

Let's secure it with a Certbot SSL certificate. Obviously, change the following command to reflect your domain name:

sudo certbot --apache -d benosborne.com -d www.benosborne.com

You can see I've requested the primary domain (benosborne.com) and the sub-domain www.benosborne.com. You'll need both to host your web site properly.

Certbot will make sure you own the domain name before it issues your certificate (using Apache), because we've omitted the 'certonly' option it will also set up your secure certificate for you!

Now visit your web site again in a browser, this time it should load without complaint. phpinfo(); in your index page just shows you the PHP settings, search the page for the 'curl' section to make sure it thinks that's installed and have a quick look at the 'GD' section whilst you're at it to make sure that image manipulation module looks Ok!

If you want to see what Certbot did then check /etc/apache2/sites-available directory, you should see it created a new virtualhost file with 'le-ssl' on the end (Let's Encrypt SSL) which just defines your secure web site on port 443 and then enabled the site (see the symlink in sites-enabled). Here's my SSL file in case you're interested:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin admin@benosborne.com
    ServerName benosborne.com
    ServerAlias *.benosborne.com
    DocumentRoot /mnt/d1/www/benosborne.com
    DirectoryIndex index.php
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/benosborne.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/benosborne.com/privkey.pem
</VirtualHost>
</IfModule>
It's worth knowing that in case you need to do it manually one day!

Anyway. Congratulations, your web site is working!

Single Apache file for both port 80 and 443

Presently, you have 2 Apache files for your website, your_domain.conf and your_domain-le-ssl.conf which can be a little confusing and feel a bit cluttered.

You can tidy this up a bit by putting both virtualhost definitions in the same file, then disabling the le-ssl.conf version. This way, there's less confusion when you check your /etc/apache2/sites-enabled directory. First, open the ssl version and copy out the virtualhost definition:

sudo nano your_domain-le-ssl.conf

Copy the SSL virtualhost:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin admin@your_domain
    ServerName your_domain
    ServerAlias www.your_domain
    DocumentRoot /mnt/d1/www/your_domain
    DirectoryIndex index.php
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem
</VirtualHost>
</IfModule>
Then edit the port 80 version and paste the SSL virtualhost at the end of the file:

sudo nano your_domain.conf

<VirtualHost *:80>
    ServerAdmin admin@your_domain
    ServerName your_domain
    ServerAlias www.your_domain
    DocumentRoot /mnt/d1/www/your_domain
    DirectoryIndex index.php
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin admin@your_domain
    ServerName your_domain
    ServerAlias www.your_domain
    DocumentRoot /mnt/d1/www/your_domain
    DirectoryIndex index.php
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem
</VirtualHost>
</IfModule>
Now disable the le-ssl file:

sudo a2dissite your_domain-le-ssl.conf

...and restart Apache to pick up the changes:

sudo systemctl restart apache2

Obviously you'll want to load your website in a browser to make sure it's working and have a quick look in sites-enabled to make sure it looks ok.

ls /etc/apache2/sites-enabled

Neat and Tidy!




2025