
Apache HTTP Server remains the most widely deployed open-source web server in the world, and learning how to install Apache on Ubuntu 26.04 puts a production-ready foundation under every site you will ever host. Ubuntu 26.04 LTS “Resolute Raccoon” shipped in April 2026 with Linux kernel 7.0 and five years of official security support, making it a solid long-term base for any web server. This guide walks you through every stage of an Apache on Ubuntu 26.04 setup: from a fresh server to a domain-serving, firewall-protected, SSL-secured instance. Whether you are a developer spinning up a local test environment or a sysadmin provisioning a production node, every command here is tested, explained, and production-grade.
By the end of this Linux server tutorial you will have:
- Apache2 installed and running as a systemd service
- UFW firewall configured to allow web traffic on ports 80 and 443
- A custom virtual host serving your domain
- A free, auto-renewing SSL certificate from Let’s Encrypt
- Basic security hardening applied before you go live
Prerequisites
Before you run a single command, confirm you have the following in place:
- Operating system: Ubuntu 26.04 LTS “Resolute Raccoon” (server or desktop)
- User privileges: A non-root user with
sudoaccess. Running everything directly as root is a security anti-pattern on any production box. - Network access: Your server must reach Ubuntu’s APT repositories. A live internet connection is required.
- Terminal access: SSH into a remote VPS or open the Ptyxis terminal on a local Ubuntu 26.04 desktop install (it is the default terminal starting from this release).
- Domain name (optional but recommended): You need a domain pointing to your server’s public IP address for the virtual host and SSL sections. The basic install steps work without one.
Step 1: Update Your System Package Index
Every solid Apache on Ubuntu 26.04 setup begins with a fresh package index. Skipping this step is one of the most common reasons people end up installing an outdated apache2 build with known vulnerabilities that Ubuntu has already patched in its repositories.
sudo apt update && sudo apt upgrade -y
What this does:
apt updaterefreshes the local list of available packages from Ubuntu’s servers. APT maintains this list as a local cache. Without refreshing it, APT works from potentially outdated data.apt upgrade -yapplies all available upgrades to installed packages. The-yflag auto-confirms the prompt so the process runs without stopping to ask questions.
Expected output:
Hit:1 http://archive.ubuntu.com/ubuntu resolute InRelease
...
Reading package lists... Done
Building dependency tree... Done
XX upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
On Ubuntu 26.04, you may notice the sudo command now uses sudo-rs, a memory-safe Rust rewrite of the classic sudo binary. The behavior is identical from a user perspective.
If you hit a lock error like Could not get lock /var/lib/dpkg/lock-frontend, another APT process is running in the background, often the automatic unattended-upgrades service. Wait 60 seconds and try again.
Step 2: Install Apache on Ubuntu 26.04
With a fully updated system, you can now install the apache2 package directly from Ubuntu’s official repositories.
sudo apt install apache2 -y
What this does:
APT pulls the apache2 package along with all its dependencies: the apache2-bin binary, apache2-data (default config files and the default web page), and apache2-utils (tools like ab for benchmarking and htpasswd for basic auth).
Why APT instead of compiling from source:
Compiling Apache from source gives you fine-grained control, but it also removes you from Ubuntu’s security patch pipeline. When a CVE hits Apache, Ubuntu’s security team backports the fix and ships it via APT within hours. If you compiled manually, you get nothing automatically. For any production server, stick with the APT package.
Verify the installation:
apachectl -v
Expected output:
Server version: Apache/2.4.62 (Ubuntu)
Server built: 2026-xx-xx
The exact patch version will reflect what Ubuntu 26.04 ships at the time of your install. What matters is that the command returns a version string without errors.
Step 3: Start and Enable the Apache Service
APT’s post-install script starts Apache automatically on most Ubuntu setups, but never assume it happened. Always verify the service state explicitly and enable it for boot persistence yourself.
sudo systemctl enable apache2
sudo systemctl start apache2
sudo systemctl status apache2
Why systemctl enable matters
enable writes a symlink into systemd’s target directory, wiring Apache into the boot sequence. Without this step, Apache runs fine right now but goes offline silently the next time your server reboots. In a production environment, a server restart after a kernel update is routine. You want Apache to come back up on its own every time.
Reading the status output
● apache2.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-06-15 11:30:00 WIB; 2min ago
Process: ... ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
Main PID: 1234 (apache2)
The key line is Active: active (running). The word enabled next to Loaded confirms the boot symlink is in place. If you see inactive (dead) or failed, check the logs immediately:
sudo journalctl -u apache2 --no-pager -n 50
Confirm with a browser
Get your server’s IP address:
hostname -I | awk '{print $1}'
Visit http://YOUR_SERVER_IP in a browser. You should see the Apache2 Ubuntu Default Page. This page is served from /var/www/html/index.html and confirms that port 80 is open, Apache is running, and the default document root is accessible.
If the page does not load, your firewall is almost certainly blocking port 80. The next step covers exactly that.
Step 4: Configure the UFW Firewall for Apache Traffic
A running Apache process means nothing if the kernel’s firewall drops every inbound HTTP request before it reaches the service. Ubuntu 26.04 ships with UFW (Uncomplicated Firewall) as the default firewall management tool.
UFW ships with pre-built application profiles for Apache. Check what is available:
sudo ufw app list
Expected output:
Available applications:
Apache
Apache Full
Apache Secure
OpenSSH
The three Apache profiles map to specific ports:
| Profile | Ports Opened | Use Case |
|---|---|---|
Apache |
80 (HTTP only) | HTTP-only sites |
Apache Secure |
443 (HTTPS only) | HTTPS-only |
Apache Full |
80 and 443 | HTTP + HTTPS (recommended) |
Allow Apache Full from the start since you will be adding SSL later in this guide:
sudo ufw allow OpenSSH
sudo ufw allow 'Apache Full'
sudo ufw enable
sudo ufw status
Critical step: allow OpenSSH before enabling UFW.
If you are on a remote server and enable UFW without allowing SSH first, you lock yourself out completely. There is no graceful recovery without access to a VPS console or physical keyboard. Always allow SSH before you enable the firewall.
Expected output from sudo ufw status:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Apache Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Apache Full (v6) ALLOW Anywhere (v6)
Now reload the page you opened earlier. It should load cleanly.
Step 5: Configure Apache on Ubuntu 26.04 with a Virtual Host
The default Apache configuration serves a placeholder page from /var/www/html. For any real site, you need a virtual host: a config block that tells Apache which domain to answer for and where its files live. This is how you configure Apache on Ubuntu 26.04 for actual production use.
Understanding Apache’s directory layout on Ubuntu
Ubuntu uses a split-configuration structure that differs from RHEL-based systems. Knowing this layout saves a lot of confusion:
| Path | Purpose |
|---|---|
/etc/apache2/apache2.conf |
Master config, loaded first |
/etc/apache2/sites-available/ |
All vhost config files (active or inactive) |
/etc/apache2/sites-enabled/ |
Symlinks to active configs only |
/var/www/html/ |
Default document root |
/var/log/apache2/ |
Access and error logs |
Apache only reads configs from sites-enabled. The a2ensite and a2dissite commands manage the symlinks between the two directories. This means you can write a new virtual host, test it, and activate it without touching any currently running configs.
Create the web root and a test page
Replace yourdomain.com with your actual domain throughout:
sudo mkdir -p /var/www/yourdomain.com/public_html
sudo chown -R $USER:$USER /var/www/yourdomain.com/public_html
sudo chmod -R 755 /var/www/yourdomain.com
echo "<h1>Apache on Ubuntu 26.04 is working.</h1>" | sudo tee /var/www/yourdomain.com/public_html/index.html
The chmod 755 on the web root lets Apache’s www-data user read and traverse the directory. Without this, you get a 403 Forbidden response even though the files exist.
Create the virtual host configuration file
sudo nano /etc/apache2/sites-available/yourdomain.com.conf
Paste the following block:
<VirtualHost *:80>
ServerAdmin admin@yourdomain.com
ServerName yourdomain.com
ServerAlias www.yourdomain.com
DocumentRoot /var/www/yourdomain.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Save and close the file (Ctrl+X, then Y, then Enter in nano).
Enable the site and test the configuration
sudo a2ensite yourdomain.com.conf
sudo a2dissite 000-default.conf
sudo apache2ctl configtest
The configtest command is something every experienced sysadmin runs before every reload. It parses the entire Apache configuration for syntax errors without touching the running service. A clean output looks like this:
Syntax OK
If you see any error here, Apache will refuse to reload cleanly. Fix the error first. Then apply the new configuration:
sudo systemctl reload apache2
Use reload instead of restart here. reload sends a SIGHUP signal to Apache, which tells it to re-read configuration files gracefully without dropping existing connections. restart kills the process and brings it back, which drops every active connection. In production, reload is almost always the right call for config changes.
Step 6: Secure Apache with a Free SSL Certificate
Running a site over plain HTTP in 2026 is not just a security problem; it is also an SEO problem. Google treats HTTPS as a ranking signal, and every modern browser shows a “Not Secure” warning on HTTP pages. Let’s Encrypt provides free, browser-trusted SSL certificates that renew automatically.
Install Certbot with the Apache plugin
sudo apt install certbot python3-certbot-apache -y
The python3-certbot-apache plugin handles the entire Apache integration automatically. It modifies your virtual host file, enables mod_ssl, and sets up HTTP-to-HTTPS redirection without any manual config editing.
Obtain and install the certificate
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
Certbot walks you through a short interactive prompt:
- Enter your email address for renewal notifications.
- Agree to the Let’s Encrypt terms of service.
- Choose whether to redirect HTTP to HTTPS (choose option 2, “Redirect”, for all production sites).
When the process finishes, Certbot has:
- Placed your certificate files under
/etc/letsencrypt/live/yourdomain.com/ - Written a new
yourdomain.com-le-ssl.confvhost for port 443 - Added redirect rules to your port 80 vhost
Test automatic certificate renewal
Let’s Encrypt certificates expire every 90 days. Certbot installs a systemd timer that checks for renewal twice daily. Test that the timer works correctly:
sudo certbot renew --dry-run
The --dry-run flag simulates the renewal process without actually contacting Let’s Encrypt’s servers or touching your live certificates. If it returns no errors, automatic renewal is wired up correctly.
Verify the timer is active:
sudo systemctl status certbot.timer
You should see Active: active (waiting).
Step 7: Basic Apache Security Hardening
Installing Apache and getting it running is the beginning, not the end. A default Apache install on any Linux distribution broadcasts its exact version number and operating system in HTTP response headers. Attackers use this information to look up CVEs and target your server with known exploits.
Spend five minutes on these hardening steps before your server goes live.
Hide server version information
Open the Apache security config file:
sudo nano /etc/apache2/conf-available/security.conf
Find and set these two directives:
ServerTokens Prod
ServerSignature Off
ServerTokens Prod reduces the Server header to just Apache, removing the version number. ServerSignature Off removes the Apache version footer from error pages. Together, they make your server much less informative to anyone scanning for vulnerabilities.
Disable directory listing
When Apache serves a directory that has no index.html file, it generates a file browser by default. This exposes your directory structure to the open internet.
Add Options -Indexes to your virtual host’s <Directory> block:
<Directory /var/www/yourdomain.com/public_html>
Options -Indexes -FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Add security response headers
Enable the headers module first:
sudo a2enmod headers
Then add these lines inside your SSL virtual host block:
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"stops browsers from guessing content types, blocking a class of MIME confusion attacks.X-Frame-Options "SAMEORIGIN"prevents your pages from being embedded in iframes on foreign domains, which stops clickjacking.Strict-Transport-Securityforces browsers to use HTTPS for every future visit for one full year, even if someone typeshttp://manually.
Apply all changes:
sudo apache2ctl configtest && sudo systemctl reload apache2
Managing Apache as a systemd Service
Here is a quick reference for the commands you will use most often during day-to-day operations:
sudo systemctl start apache2 # Start Apache
sudo systemctl stop apache2 # Stop Apache
sudo systemctl restart apache2 # Full restart (drops active connections)
sudo systemctl reload apache2 # Graceful config reload (no dropped connections)
sudo systemctl status apache2 # Check service state
sudo systemctl enable apache2 # Auto-start at boot
sudo systemctl disable apache2 # Remove from boot sequence
Use restart only when you are changing something that requires a full process cycle, like switching Apache’s Multi-Processing Module (MPM). For all other config changes, reload is the right tool.
Troubleshooting Common Apache Errors on Ubuntu 26.04
Even a careful install hits snags. These are the five errors that appear most frequently and exactly how to fix them.
1. Site does not load in the browser
The firewall is almost always the cause. Verify that UFW is allowing the right ports:
sudo ufw status
If Apache Full is not listed, run sudo ufw allow 'Apache Full' and try again.
2. Warning: AH00558: apache2: Could not reliably determine the server's fully qualified domain name
This appears on startup when Apache cannot resolve a hostname. Fix it by adding a global ServerName directive:
echo "ServerName 127.0.0.1" | sudo tee -a /etc/apache2/apache2.conf
sudo systemctl reload apache2
3. Port 80 is already in use
You get this if another process, often nginx or a second Apache instance, is already bound to port 80. Find out what it is:
sudo ss -tulpn | grep :80
Stop the conflicting service before starting Apache, or reconfigure one of them to use a different port.
4. 403 Forbidden on your virtual host
The web root directory either has wrong permissions or the www-data user cannot traverse it. Check and fix:
sudo chmod -R 755 /var/www/yourdomain.com
sudo chown -R www-data:www-data /var/www/yourdomain.com/public_html
5. SSL certificate does not renew automatically
Let’s Encrypt’s ACME challenge requires port 80 to be reachable, even on HTTPS-only sites. If you closed port 80 in UFW after enabling SSL, renewal fails silently. Keep port 80 open; Certbot’s redirect rule handles the HTTP-to-HTTPS forwarding at the application layer while the firewall keeps the port accessible for renewal challenges.
[su_box title=”VPS Manage Service Offer” style=”bubbles” box_color=”#000000″ radius=”10″]If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal![/su_box]