Apache HTTP Server remains one of the most widely deployed web servers thanks to its flexibility, mature module ecosystem, and proven stability. It powers everything from hobby sites to enterprise workloads while handling static files, dynamic scripts, and SSL/TLS encryption with equal ease.
This guide covers installing Apache from Ubuntu’s default repository, configuring the UFW firewall, creating virtual hosts, and securing your server with Let’s Encrypt certificates for production-ready HTTPS.
Apache Installation Methods
Ubuntu’s default repository provides a stable, well-tested Apache build that receives security patches through Ubuntu’s standard update cycle. This is the recommended installation method for most users and the approach documented throughout this guide.
For users who specifically need the latest upstream Apache release with newer features or modules, Ondřej Surý maintains a PPA that tracks upstream more closely. See our Apache upgrade guide for detailed PPA installation and rollback instructions.
Default Apache Versions by Ubuntu Release
The default APT repository ships different Apache versions depending on your Ubuntu release. These versions receive security backports throughout the Ubuntu support lifecycle.
| Ubuntu Release | Default Apache | Support Status |
|---|---|---|
| Ubuntu 26.04 LTS | Apache 2.4.65 | Supported until 2031 |
| Ubuntu 24.04 LTS | Apache 2.4.58 | Supported until 2029 |
| Ubuntu 22.04 LTS | Apache 2.4.52 | Supported until 2027 |
Install Apache on Ubuntu
Update Ubuntu Before Apache Installation
Update Ubuntu first so every package pulls in the latest security fixes and dependency changes. Working from a current baseline prevents conflicts once Apache installs.
If you need a refresher on APT basics, review our guide to updating packages via the Ubuntu command line before proceeding.
Run the combined update and upgrade to sync your system:
sudo apt update && sudo apt upgrade
Install Apache Using APT
Install Apache from Ubuntu’s official repository:
sudo apt install apache2
After the installation completes, verify Apache is running and check the installed version:
sudo systemctl status apache2 --no-pager
Expected output:
● apache2.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-01-27 10:15:32 UTC; 1min ago
Main PID: 12345 (apache2)
Tasks: 6 (limit: 4915)
Memory: 12.5M
CPU: 125ms
CGroup: /system.slice/apache2.service
Check the Apache version:
apache2 -v
Expected output (version varies by Ubuntu release):
Server version: Apache/2.4.58 (Ubuntu) Server built: 2024-01-15T12:30:45
Configure UFW Firewall for Apache
After Apache installs, configure the UFW (Uncomplicated Firewall) rules so HTTP and HTTPS traffic can reach the service. Apache registers multiple UFW profiles during installation, making it easy to allow the correct ports in a single step.
Check UFW Installation
Before you add rules, verify that UFW is installed and note whether it is already active:
sudo ufw status
If the command reports that UFW is missing, install the package:
sudo apt install ufw
Do not enable UFW yet; build the allow rules first so you do not cut off SSH or web access mid-session.
Apply the
OpenSSHprofile (and any other required services) before runningsudo ufw enable. If you only have remote access, schedule firewall changes from a console or with out-of-band management so you can recover quickly if a rule is missing.
List Available Application Profiles
List the available profiles so you know which Apache presets UFW exposes:
sudo ufw app list
Example output:
Available applications: Apache Apache Full Apache Secure OpenSSH
The Apache profiles control web traffic ports:
- Apache — Opens port 80 (HTTP) only
- Apache Secure — Opens port 443 (HTTPS) only
- Apache Full — Opens both port 80 and 443
Most servers start with Apache during initial setup and switch to Apache Full or Apache Secure after configuring SSL certificates.
Configure UFW Firewall Rules for Apache
Start by allowing basic HTTP access with the Apache profile while you finish the rest of the setup:
sudo ufw allow 'Apache'
If you manage the server over SSH, also add the OpenSSH profile so port 22 stays reachable:
sudo ufw allow OpenSSH
Example output:
Rule added Rule added (v6)
The rules apply to both IPv4 and IPv6. Later you can swap profiles if you migrate directly to HTTPS.
Whitelist IP Addresses and Ranges
You can scope access to trusted hosts by allowing only specific IP addresses or ranges while keeping the rules tied to Apache’s HTTP (80) and HTTPS (443) ports. To allow a single remote IP, run (and repeat with port 443 if you want HTTPS too):
sudo ufw allow from <IP_ADDRESS> to any port 80 proto tcp
Replace <IP_ADDRESS> with the actual IP address you want to whitelist and adjust the port number as needed.
To authorize an entire subnet, adjust the CIDR notation in this rule (duplicate it for port 443 when needed):
sudo ufw allow from <IP_RANGE> to any port 80 proto tcp
Replace <IP_RANGE> with the subnet you want to trust, such as 192.168.1.0/24. Switching the port number lets you create HTTP-only, HTTPS-only, or dual-purpose rules.
For a typical home or lab network, you might run:
sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp
This example opens HTTP access for every device in the 192.168.1.0/24 subnet; add a matching port 443 rule if HTTPS should stay local-only.
Review the pending rules before enabling the firewall:
sudo ufw status
Expected output:
Status: inactive To Action From -- ------ ---- Apache ALLOW Anywhere OpenSSH ALLOW Anywhere Apache (v6) ALLOW Anywhere (v6) OpenSSH (v6) ALLOW Anywhere (v6)
Enable the firewall to activate these rules:
sudo ufw enable
Confirm the firewall is active:
sudo ufw status verbose
Expected output:
Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- Apache ALLOW IN Anywhere 22/tcp (OpenSSH) ALLOW IN Anywhere Apache (v6) ALLOW IN Anywhere (v6) 22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
Verify Apache Installation on Ubuntu
With Apache installed and the firewall configured, confirm the service answers web requests before moving on to custom content.
Find Your Server’s IP Address
To load Apache’s default landing page, you need the server’s IP address. Display the local addresses assigned to the host with:
hostname -I
The command prints one or more internal IP addresses, similar to this output:
192.168.50.15
Test each address until you reach the server, especially if the machine has multiple interfaces.
To view your public (external) IP address, query a simple HTTPS endpoint:
curl -4 icanhazip.com
If curl is missing, install it first:
sudo apt install curl -y
Once curl is installed, explore more practical use cases in our curl command guide for Linux to better understand how it can assist with troubleshooting and automation.
Access the Apache Landing Page
After you have the correct IP address, enter it in your browser:
http://your_server_ip
Replace your_server_ip with the address from the previous step.
Verify the Apache Default Page
Your browser should display the Apache test page:

This page confirms that Apache is installed correctly and responding over the network.
Configure Virtual Hosts for Apache
Apache uses virtual hosts to map domains to directories, similar to how Nginx uses server blocks. The following example builds a site for example.com that you can later replace with your own domain.
Create and Configure Directories for Apache
Ubuntu ships a single enabled virtual host that serves /var/www/html. You can reuse it for a one-site server, but adding more domains is easier when each domain receives its own directory and matching virtual host file.
Leave /var/www/html untouched for the default site and create a dedicated directory for example.com, which becomes the DocumentRoot for that domain:
sudo mkdir /var/www/example.com
Assign ownership to your sudo user so you can edit site files without switching to root:
sudo chown -R $USER:$USER /var/www/example.com
Verify the permissions with ls -l to ensure Apache can read the files:
ls -l /var/www/
Example output:
drwxr-xr-x 2 joshua joshua 4096 Apr 18 15:25 example.com drwxr-xr-x 2 root root 4096 Apr 18 15:23 html
The drwxr-xr-x entry corresponds to chmod 755, which is ideal for a public web root. Fix the permissions if they differ:
sudo chmod -R 755 /var/www/example.com
Create a quick index.html file with your preferred editor (nano in this example):
sudo nano /var/www/example.com/index.html
In the file, copy and paste the following code:
<html>
<head>
<title>Welcome to Website!</title>
</head>
<body>
<h1>Success! The virtual host is working! You did not mess it up.</h1>
</body>
</html>
Save the file (CTRL+O), then exit (CTRL+X).
Create a Virtual Host for Apache
With the document root prepared, create the virtual host file under /etc/apache2/sites-available/, which is where Apache keeps site definitions.
Create a matching virtual host definition in /etc/apache2/sites-available/example.com.conf:
sudo nano /etc/apache2/sites-available/example.com.conf
Paste the template below and replace example.com with your actual domain, ensuring the DocumentRoot points to the directory you created earlier:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Use an appropriate email address for ServerAdmin and your domain names for the ServerName and ServerAlias entries.
Save the file (Ctrl+O) and exit (Ctrl+X) when the directives match your domain.
Enable Virtual Host for Apache
With the configuration saved, enable it using Apache’s helper utilities instead of creating symlinks manually like you would on Nginx:
Disable the default 000-default.conf site so Apache does not serve two sites on the same port:
sudo a2dissite 000-default.conf
Enable your new site so Apache creates the appropriate symlink under sites-enabled:
sudo a2ensite example.com.conf
Run the Apache syntax check before reloading to catch mistakes:
sudo apache2ctl configtest
You should see the following confirmation:
Syntax OK
Once apache2ctl configtest returns Syntax OK, restart Apache to load the new site:
sudo systemctl restart apache2
Apache now serves the example.com landing page. Visit http://example.com in your browser to confirm the custom index.html file loads:

Secure Apache with Let’s Encrypt Free SSL Certificate
Protect traffic by serving Apache over HTTPS with a trusted SSL/TLS certificate. Let’s Encrypt, a free certificate authority backed by the Internet Security Research Group (ISRG), automates the process so you are never stuck paying for renewals.
Install Certbot for Apache
Install the Certbot Apache plugin, which handles certificate requests and VirtualHost updates automatically:
sudo apt install python3-certbot-apache -y
Create and Configure SSL Certificate for Apache
Request and install a certificate for your domain, replacing the email address and domain names with your own:
sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d www.example.com
This command enables several production-friendly options:
- Force permanent HTTPS redirects (–redirect) so browsers stop using HTTP.
- Add the Strict-Transport-Security header (–hsts) to tell browsers to prefer HTTPS for future visits.
- Enable OCSP stapling (–staple-ocsp) so Apache sends fresh certificate status to clients.
Provide a monitored email address for renewal reminders and replace the domain arguments with the hostnames assigned to your site.
Verify SSL Configuration with Apache
Your site now answers on https://www.example.com and automatically redirects from http://www.example.com, keeping visitors on encrypted connections.
Visit the site in a browser to confirm the padlock icon appears and that the redirect fires correctly.
Update your firewall now that HTTPS is available. Use the Apache Full profile to keep HTTP and HTTPS open, or switch to Apache Secure if you only want HTTPS:
Keep both ports open:
sudo ufw allow 'Apache Full'
Allow HTTPS only:
sudo ufw allow 'Apache Secure'
If you switch from the earlier HTTP-only rule to Apache Secure, remove the original entry with sudo ufw delete allow 'Apache' so port 80 closes.
Automate Certificate Renewal
Let’s Encrypt certificates remain valid for 90 days. Certbot installs a cron job or systemd timer automatically, but run a quick dry run to confirm renewals work:
sudo certbot renew --dry-run
The dry run simulates a renewal without making changes. A successful result means the automated job can refresh the certificate before it expires.
Combine HTTPS with an application firewall by following our ModSecurity with Apache on Ubuntu guide if you want to block malicious traffic before it reaches your apps.
Apache Management on Ubuntu
Keep Apache healthy by monitoring its logs and knowing the service commands you’ll need during routine operations.
Analyze Apache Server Logs
Use these commands to review Apache logs when you troubleshoot errors or monitor traffic patterns.
Display the last few lines of a log file:
The tail command allows you to view the last few lines of a log file. This can be useful for monitoring recent activity or errors.
tail /var/log/apache2/access.log
tail /var/log/apache2/error.log
Monitor log file in real-time:
Use the tail -f command to monitor log files in real-time, which is helpful for observing live user activity or troubleshooting issues as they occur.
tail -f /var/log/apache2/access.log
tail -f /var/log/apache2/error.log
Search for specific keywords in log files:
The grep command allows you to search for specific keywords or patterns in log files. For example, you can search for occurrences of the “404” error code in the error log:
grep "404" /var/log/apache2/error.log
Count the occurrences of a specific keyword or pattern:
You can use grep in combination with the -c flag to count the occurrences of a specific keyword or pattern in log files. For example, to count the number of “500” error codes in the error log:
grep -c "500" /var/log/apache2/error.log
Display unique IP addresses that have accessed the server:
Use the awk command to display unique IP addresses that have accessed your server by analyzing the access log:
awk '{print $1}' /var/log/apache2/access.log | sort | uniq
These snippets give you a starting point for tailing logs, searching for errors, and spotting abusive hosts.
Essential Apache Service Management Commands
Memorize these service commands for common maintenance tasks:
Stop Apache web server:
sudo systemctl stop apache2
Start Apache web server:
sudo systemctl start apache2
Restart Apache web server:
sudo systemctl restart apache2
Reload Apache web server: (For minor changes that don’t require a complete restart)
sudo systemctl reload apache2
Disable Apache on server boot:
sudo systemctl disable apache2
Enable Apache on server boot: (Automatically enabled upon installation)
sudo systemctl enable apache2
Additional Apache Maintenance Tasks
Update Apache
Keep Apache patched by running the regular APT update and upgrade cycle:
sudo apt update
sudo apt upgrade
Note that it’s always a good idea to create backups or server images if your Apache service is running critical applications. While most updates are safe, occasional issues can arise during upgrades.
For major version changes or when migrating to a new LTS release, follow our step-by-step Apache upgrade guide for Ubuntu so you can plan downtime, confirm module compatibility, and roll back safely if needed.
Remove Apache
Remove Apache if you are decommissioning the service or migrating to another web server. Choose between a standard removal that keeps configuration files or a full purge that removes everything.
Standard removal (keeps config files for reinstallation):
sudo apt remove apache2
Full purge (removes packages and configuration files):
sudo apt purge apache2 apache2-utils apache2-bin
Clean up orphaned packages afterward:
sudo apt autoremove
This removal does not delete website content in
/var/www/or custom virtual host configurations in/etc/apache2/sites-available/. Back up these directories before deleting them manually if you want a completely clean slate.
Verify Apache is completely removed:
apache2 -v
Expected output after removal:
-bash: apache2: command not found
Troubleshooting Apache on Ubuntu
This section covers common Apache issues and their solutions.
Apache Fails to Start
When Apache refuses to start, first check the service status for error details:
sudo systemctl status apache2 --no-pager -l
Common causes and fixes:
Port 80 already in use:
(98)Address already in use: AH00072: make_sock: could not bind to address
Another process is using port 80. Find it with:
sudo ss -tlnp | grep :80
Stop the conflicting service (often nginx) or change Apache’s port in /etc/apache2/ports.conf.
Configuration syntax error:
Job for apache2.service failed because the control process exited with error code.
Test the configuration syntax:
sudo apache2ctl configtest
Fix the reported issue, then restart Apache.
Permission Denied Errors
If Apache returns 403 Forbidden errors for a directory, verify the permissions allow Apache to read the files:
sudo chmod -R 755 /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
Also confirm the Directory block in your virtual host allows access:
<Directory /var/www/example.com>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Virtual Host Not Loading
If Apache serves the default page instead of your virtual host, verify the site is enabled:
ls -l /etc/apache2/sites-enabled/
Confirm your .conf file appears in the list. If not, enable it:
sudo a2ensite example.com.conf
sudo systemctl reload apache2
Also confirm your DNS or /etc/hosts file points the domain to the server’s IP address.
Certbot Certificate Request Fails
Let’s Encrypt validation requires that the domain resolves to your server and port 80 is open. If certificate requests fail:
- Verify DNS A/AAAA records point to the correct public IP
- Confirm UFW allows the Apache profile:
sudo ufw status - Check that no firewall upstream (cloud provider, router) blocks port 80
- Test HTTP access from outside your network before requesting the certificate
Conclusion
Apache is now installed from your preferred repository, locked down with UFW, serving custom virtual hosts, and secured with Let’s Encrypt certificates that renew automatically. This gives your Ubuntu server a dependable HTTP and HTTPS stack ready for production workloads or continued development.
I’d like to know how to delete a file created on Apache.
To delete a file from your Apache web server, use the
rmcommand with the full path to the file. For example, if you createdtest.htmlin your document root at/var/www/example_domain/, remove it withsudo rm /var/www/example_domain/test.html. You needsudobecause Apache’s web directories are typically owned by root or the www-data user.To remove an entire directory and its contents, add the
-rflag:sudo rm -r /var/www/example_domain/. Always double-check the path before runningrmcommands since deletions are permanent. You can verify what’s in a directory first withls -la /var/www/example_domain/to confirm you’re targeting the right files.