Complete Guide to Installing and Configuring Apache2 on Ubuntu 22.04

Development tutorial - IT technology blog
Development tutorial - IT technology blog

My First Web Deployment Struggle

When I first started working with Linux servers, I deployed a PHP project to an Ubuntu VPS and spent hours wondering why hitting the IP address showed Apache’s default page instead of my project. It took nearly half a day to figure out: installing Apache isn’t enough — you still need to configure virtual hosts, set directory permissions, and open the right ports on the firewall.

After about 6 months running Apache2 in production — including a web app for a 5-developer team — I’ve been through every kind of “stupid” error that the official docs don’t mention. This article is the workflow I actually use, not a copy-paste from the manual.

Why Does Apache2 Cause Headaches Right from the Start?

The issue isn’t that Apache is complex. Ubuntu 22.04 has a few changes compared to older versions that many tutorials haven’t caught up with:

  • UFW blocks port 80/443 by default — you can install Apache and the firewall will still block all traffic.
  • The /etc/apache2/ directory structure uses a sites-available / sites-enabled system — completely different from what many older guides describe.
  • PHP-FPM vs mod_php — since PHP 7.4, Ubuntu recommends PHP-FPM but it requires additional configuration and isn’t as plug-and-play as before.

Understanding these 3 points explains 80% of why Apache “works but doesn’t work” on your machine.

Installing Apache2

Update the package list and install:

sudo apt update
sudo apt install apache2 -y

Check if Apache is running:

sudo systemctl status apache2

If you see active (running), you’re good. If it shows failed, run sudo journalctl -xe to see the specific reason. Enable auto-start on reboot:

sudo systemctl enable apache2

Properly Configuring UFW Firewall

This is the most commonly skipped step. Apache comes with pre-built profiles for UFW:

# List available profiles
sudo ufw app list

# Allow HTTP and HTTPS
sudo ufw allow 'Apache Full'

# If you only need HTTP for now
sudo ufw allow 'Apache'

# Enable UFW if not already enabled
sudo ufw enable
sudo ufw status

After this step, typing your server’s IP address into a browser should show the “Apache2 Ubuntu Default Page” — confirming everything is running correctly.

Configuring Virtual Hosts — The Ubuntu Way

I’ve seen many people edit /etc/apache2/apache2.conf directly — this is the wrong approach. On Ubuntu, each website should have its own configuration file in /etc/apache2/sites-available/.

Create the website directory

sudo mkdir -p /var/www/mywebsite.com/public
sudo chown -R $USER:$USER /var/www/mywebsite.com
sudo chmod -R 755 /var/www/mywebsite.com

Create the virtual host configuration file

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

File contents:

<VirtualHost *:80>
    ServerName mywebsite.com
    ServerAlias www.mywebsite.com
    ServerAdmin [email protected]
    DocumentRoot /var/www/mywebsite.com/public

    <Directory /var/www/mywebsite.com/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/mywebsite.com-error.log
    CustomLog ${APACHE_LOG_DIR}/mywebsite.com-access.log combined
</VirtualHost>

Enable the site and reload Apache

# Enable the new site
sudo a2ensite mywebsite.com.conf

# Disable the default site if not needed
sudo a2dissite 000-default.conf

# Check configuration syntax
sudo apache2ctl configtest

# Reload Apache
sudo systemctl reload apache2

The apache2ctl configtest command is something I always run before reloading — it prevents Apache from crashing due to a syntax error in the config.

Enabling Required Modules

Apache2 on Ubuntu uses the a2enmod command to enable modules. Some commonly used ones:

# Required if using .htaccess with WordPress/Laravel
sudo a2enmod rewrite

# SSL
sudo a2enmod ssl

# Gzip compression for static files
sudo a2enmod deflate

# Security headers
sudo a2enmod headers

sudo systemctl restart apache2

For the 5-developer team project, I rolled these 4 commands into a server bootstrap script. Run it once and you’re done — no more debugging sessions caused by module mismatches between dev and production.

Setting Up SSL with Let’s Encrypt

Once your domain is pointed at the server, Certbot is the fastest option:

sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d mywebsite.com -d www.mywebsite.com

Certbot automatically modifies your .conf file, adds SSL configuration for port 443, and sets up HTTP-to-HTTPS redirect. Certificates expire after 90 days, but auto-renewal is already configured via a systemd timer:

# Check the auto-renewal timer
sudo systemctl status certbot.timer

# Test renewal
sudo certbot renew --dry-run

Managing Multiple Websites on a Single VPS

After running multiple projects on the same VPS, I’ve settled on this structure:

/var/www/
├── site1.com/
│   └── public/         # DocumentRoot
├── site2.com/
│   └── public/
└── site3.com/
    └── public/

/etc/apache2/
├── sites-available/
│   ├── site1.com.conf
│   ├── site2.com.conf
│   └── site3.com.conf
└── sites-enabled/      # Only contains symlinks, never create files here

The rule: one conf file per domain, use a2ensite/a2dissite to toggle — never edit sites-enabled directly.

Reading Logs When Something Goes Wrong

9 times out of 10, the answer to any Apache error is right there in the error log:

# Watch errors in real-time
sudo tail -f /var/log/apache2/error.log

# View logs by domain (if custom log is configured)
sudo tail -f /var/log/apache2/mywebsite.com-error.log

# View access log
sudo tail -f /var/log/apache2/mywebsite.com-access.log

Getting a 403 Forbidden? It’s usually incorrect directory permissions or a missing AllowOverride All in the config. Getting a 500? The error log will point to the exact problem line — no guesswork needed.

Standard Setup Checklist

  1. Install Apache2 → enable the service
  2. Open the firewall with UFW (Apache Full)
  3. Create the website directory with correct permissions
  4. Create a .conf file in sites-available
  5. Enable the site with a2ensite, test the config, reload
  6. Enable required modules (rewrite, ssl, …)
  7. Install SSL with Certbot

Apache2 is honestly not as intimidating as people think. Most cases of a server being “unreachable” come down to UFW not opening the port or the virtual host not being enabled. Check those two things first — then start looking for more complex causes.

Share: