Report this

What is the reason for this report?

How To Install the Apache Web Server on Ubuntu

Updated on December 9, 2025
English

Not using Ubuntu 20.04?
Choose a different version or distribution.
Ubuntu 20.04
How To Install the Apache Web Server on Ubuntu

Introduction

The Apache HTTP Server, or Apache, is one of the most widely used web servers in the world. Since its release in 1995, it has remained popular because it is open source, reliable, and easy to customize. Even in 2025, Apache continues to be a dependable choice for hosting websites and applications on Linux servers such as Ubuntu.

Apache uses a modular design that allows you to enable only the features you need, such as SSL encryption, caching, or URL rewriting. On Ubuntu 24.04, Apache is included with the event MPM as the default processing module, offering improved performance for busy servers.

In this tutorial, you will install Apache on an Ubuntu server, configure the firewall, set up virtual hosts, enable HTTPS with Let’s Encrypt, and learn how to manage and troubleshoot the service. This guide follows an HTTPS-first approach, helping you configure SSL early so your Apache server is secure and ready for production use.

Key Takeaways:

  • Default Architecture: Ubuntu 24.04 installs Apache with the event MPM (Multi-Processing Module) by default, offering better performance for high-concurrency environments compared to the older prefork model.
  • Firewall Integration: You must explicitly permit traffic through the firewall; using the ‘Apache Full’ profile in UFW automatically opens both port 80 (HTTP) and 443 (HTTPS) simultaneously.
  • Virtual Host Strategy: To host multiple domains, avoid using the default /var/www/html root; instead, create dedicated directories for each domain and assign permissions to the non-root user.
  • Configuration Management: Apache separates configuration files (sites-available) from active sites (sites-enabled); use a2ensite to enable a site (creating a symbolic link) and a2dissite to disable it without deleting the file.
  • HTTPS Automation: Security is mandatory, not optional. The python3-certbot-apache plugin automates the acquisition of Let’s Encrypt SSL certificates and handles the configuration of HTTPS redirects.
  • Systemd Timers: You do not need to manually renew SSL certificates; Certbot installs a systemd timer that checks for expiration twice daily and renews certificates automatically.
  • Security Hardening: A production-ready server requires disabling directory indexing (to hide file lists) and implementing security headers like X-Content-Type-Options and X-Frame-Options to prevent browser-based attacks.
  • Troubleshooting Protocol: Always verify configuration syntax with sudo apache2ctl configtest before restarting the service to prevent downtime, and check journalctl -u apache2 if the service fails to start.

Simplify deploying applications to servers with DigitalOcean App Platform. Deploy directly from GitHub in minutes.

Prerequisites

Before you begin this guide, you should have a regular, non-root user with sudo privileges configured on your server. Additionally, you will need to enable a basic firewall to block non-essential ports. You can learn how to configure a regular user account and set up a firewall for your server by following our Initial server setup guide for Ubuntu.

Once you have created a non-root user with sudo privileges, log in as that user to begin.

Note: This guide has been tested on Ubuntu 24.04 LTS, the latest stable release at the time of writing. The commands and steps will also work on other recent Ubuntu versions, such as 22.04 LTS. However, it is recommended to use the latest stable version to ensure compatibility, security, and access to updated software packages.

Installing Apache

Apache is included in Ubuntu’s default package repositories, so you can install it using standard package management tools. Let’s start by updating your server’s local package index to make sure you’re installing the latest available version.

  1. sudo apt update

Once the update is complete, install the apache2 package:

  1. sudo apt install apache2

When prompted, confirm the installation. The package manager will install Apache along with all required dependencies.

After installation, you can verify that Apache was installed correctly and check the version currently running on your system:

  1. apache2 -v

You’ll see output similar to this:

Server version: Apache/2.4.58 (Ubuntu)
Server built:   2025-08-11T11:10:09

Ubuntu may ship the prefork MPM by default if libapache2-mod-php is installed, because mod_php is not thread safe. To confirm which MPM (Multi-Processing Module) your system is using, run:

  1. apache2ctl -M | grep mpm

Expected output:

mpm_event_module (shared)

That confirms that Apache is installed and configured with the default event-based processing model.

If you want to switch to the event MPM (recommended when using PHP-FPM instead of mod_php), run:

  1. sudo a2dismod mpm_prefork
  2. sudo a2enmod mpm_event
  3. sudo systemctl restart apache2

Note: mpm_event works best with PHP-FPM (php-fpm package). It does not work with mod_php because mod_php requires the prefork MPM.

Tip: You can extend Apache’s functionality by installing additional modules. For example, use sudo apt install apache2-utils for common administrative tools or sudo apt install libapache2-mod-security2 to enable a web application firewall for added security.

Configuring the Firewall for Apache (HTTP and HTTPS)

Before testing Apache, you’ll need to adjust your firewall to allow web traffic. If you followed the Initial Server Setup for Ubuntu guide, you should already have UFW (Uncomplicated Firewall) configured to restrict access to only essential services like SSH.

When Apache is installed, it automatically registers a few application profiles with UFW that define which ports to open for different traffic types. To view these profiles, run:

  1. sudo ufw app list

You should see output similar to this:

Available applications:
  Apache
  Apache Full
  Apache Secure
  OpenSSH

Each profile allows different levels of access:

Profile Ports Opened Description
Apache 80/tcp Allows unencrypted HTTP traffic
Apache Secure 443/tcp Allows encrypted HTTPS traffic
Apache Full 80, 443/tcp Allows both HTTP and HTTPS traffic

Since most websites today use HTTPS by default, it’s best to enable the Apache Full profile to allow both HTTP and HTTPS connections:

  1. sudo ufw allow 'Apache Full'

Next, verify that the rule was added successfully:

  1. sudo ufw status

You should see output similar to this:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Apache Full                ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Apache Full (v6)           ALLOW       Anywhere (v6)

This confirms that Apache is now allowed through the firewall for both IPv4 and IPv6 traffic.

Note: If your servers are running on DigitalOcean, you can optionally use DigitalOcean Cloud Firewalls instead of the UFW firewall. We recommend using only one firewall at a time to avoid conflicting rules that may be difficult to debug.

Checking Apache Status

After installation, Apache starts automatically. Let’s verify that it’s running and serving web pages correctly.

Check Apache Service Status

Apache on Ubuntu is managed by systemd, which controls how services start, stop, and restart. To check whether Apache is active, run:

  1. sudo systemctl status apache2

You should see output similar to this:

● apache2.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled)
     Active: active (running) since Wed 2025-12-03 06:22:48 UTC; 2min 6s ago
       Docs: https://httpd.apache.org/docs/2.4/
   Main PID: 2085 (apache2)
      Tasks: 55 (limit: 4656)
     Memory: 5.3M (peak: 5.5M)
        CPU: 57ms
     CGroup: /system.slice/apache2.service
             ├─2085 /usr/sbin/apache2 -k start
             ├─2087 /usr/sbin/apache2 -k start
             └─2088 /usr/sbin/apache2 -k start

If you see Active: active (running), Apache is up and running.

If Apache isn’t active, you can start it manually with:

  1. sudo systemctl start apache2

Test Apache Using Your Server’s Public IP

You can confirm Apache is serving web content by visiting your server’s public IP address.

First, find your server’s IP address:

  1. hostname -I

This command will return one or more IP addresses. You can also get your public IPv4 address using:

  1. curl -4 icanhazip.com

Copy the IPv4 address and enter it in your browser’s address bar:

http://your_server_ip

For example:

http://203.0.113.10

If Apache is working correctly, you’ll see the default Apache welcome page, which confirms your web server is running and serving requests from /var/www/html.

Access Apache via Hostname (Optional)

If you’ve already configured a domain name for your server, you can also test access using your domain:

http://your_domain

Make sure your DNS records are correctly pointed to your server’s public IP. DNS changes can take a few minutes to propagate depending on your registrar.

IPv6 Access

Most modern Ubuntu servers, including those on DigitalOcean, come with IPv6 enabled by default. To check whether Apache is listening on both IPv4 and IPv6 addresses, run:

  1. sudo ss -tuln | grep :80

You should see both of these lines if IPv6 is enabled:

LISTEN 0      511    0.0.0.0:80       0.0.0.0:*  
LISTEN 0      511    [::]:80          [::]:*

To test locally over IPv6, open this address in your browser:

http://[::1]

Or, if your server has a public IPv6 address, use that address in brackets:

http://[your_ipv6_address]

Tip: If you’re testing on a remote cloud instance, make sure your provider’s networking setup supports both IPv4 and IPv6. On DigitalOcean, you can verify this under Networking -> IP Addresses in your control panel.

Managing the Apache Process

Now that Apache is installed and running, it’s helpful to know how to control the service. Ubuntu uses systemd to manage background services, including Apache. This means you can use the systemctl command to start, stop, restart, and check the status of the web server.

Starting, Stopping, and Restarting Apache

To stop the web server, run:

  1. sudo systemctl stop apache2

To start Apache again, run:

  1. sudo systemctl start apache2

If you’ve made configuration changes and need to apply them, you can restart the service:

  1. sudo systemctl restart apache2

Restarting stops and then restarts Apache, which briefly interrupts any active connections. For configuration updates that don’t require a full restart, you can instead reload the service to apply changes gracefully:

  1. sudo systemctl reload apache2

Reloading tells Apache to re-read its configuration files without closing existing connections. This is useful when you’re updating virtual hosts, enabling modules, or changing log settings.

Enable or Disable Apache at Boot

By default, Apache is set to start automatically when your system boots. You can confirm this behavior by checking its enablement status:

  1. sudo systemctl is-enabled apache2

To disable Apache from starting automatically on boot:

  1. sudo systemctl disable apache2

To enable it again:

  1. sudo systemctl enable apache2

This control is useful for testing environments or servers where you only want Apache running on demand.

Checking Apache’s Status

At any time, you can view the current status of the Apache service:

  1. sudo systemctl status apache2

This command displays whether the service is running, its uptime, and recent log entries. You’ll also see the Main PID, which identifies the process Apache is using to serve requests.

For a simple confirmation without full log output, you can use:

  1. sudo systemctl is-active apache2

If it returns active, Apache is running as expected.

Viewing Apache Logs

Apache keeps detailed logs that can help you monitor performance and diagnose issues. These logs are stored in /var/log/apache2/ by default:

  • Access logs (/var/log/apache2/access.log): records every request to your server.
  • Error logs (/var/log/apache2/error.log): records warnings, errors, and startup messages.

To view the most recent entries in the error log, use:

  1. sudo tail -f /var/log/apache2/error.log

For a broader look at Apache’s activity through systemd’s journal, use the modern log viewer:

  1. sudo journalctl -u apache2 --no-pager

You can also view only the latest events:

  1. sudo journalctl -u apache2 -n 20

And to follow logs in real time:

  1. sudo journalctl -u apache2 -f

Using journalctl is often the best way to view live logs and service messages in modern Ubuntu systems, since it combines traditional logging with system-level information.

Tip: For production servers, consider setting up log rotation and retention policies using logrotate, which is installed by default on Ubuntu. This prevents log files from growing too large and ensures older logs are archived automatically.

Setting Up Virtual Hosts

When using the Apache web server, you can configure virtual hosts (similar to server blocks in Nginx) to define separate configurations for each website hosted on the same server. Virtual hosts make it easy to serve different domains or subdomains from a single machine, each with its own document root, log files, and configuration options.

In this example, we’ll set up a domain called example.com, but you should replace this with your actual domain name. If you’re setting up a new domain with DigitalOcean, refer to our Networking Documentation for steps on creating DNS records that point to your server.

Creating the Web Root Directory

Apache on Ubuntu includes one default site that serves content from /var/www/html. While this works for a single website, it’s better to create a separate directory for each domain you host. This structure keeps files organized and prevents conflicts when managing multiple sites.

Create a new directory for your domain under /var/www:

  1. sudo mkdir /var/www/example.com

Assign ownership of the directory to your current user to make it easier to edit web files:

  1. sudo chown -R $USER:$USER /var/www/example.com

By default, Ubuntu sets a umask value that assigns secure permissions, but you can verify the correct settings using:

  1. sudo chmod -R 755 /var/www/example.com

This gives the owner full read/write/execute access, while allowing others to read and execute files, the standard for web content.

Now, let’s create a simple test page that will confirm your virtual host works correctly:

  1. sudo nano /var/www/example.com/index.html

Add the following HTML content:

<html>
    <head>
        <title>Welcome to example.com!</title>
    </head>
    <body>
        <h1>Success! The example.com virtual host is working!</h1>
        <p>This page is being served from /var/www/example.com on Ubuntu 24.04.</p>
    </body>
</html>

Save and close the file when finished.

Creating the HTTP Virtual Host

Apache’s virtual host configuration files are stored in the /etc/apache2/sites-available/ directory. These files define how Apache should respond to incoming HTTP requests for a given domain.

Let’s create a new configuration file for your domain:

  1. sudo nano /etc/apache2/sites-available/example.com.conf

Insert the following configuration block:

<VirtualHost *:80>
    ServerAdmin webmaster@example.com
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com

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

Here’s what each directive does:

  • ServerAdmin: The email address Apache should display on error pages.
  • ServerName: The main domain name for this virtual host.
  • ServerAlias: Additional domain names that should point to the same site (for example, www.example.com).
  • DocumentRoot: The directory where your site’s files are stored.
  • ErrorLog and CustomLog: Define separate log files for tracking errors and access requests.

Save and close the file. This configuration will handle all requests to http://example.com.

Enabling and Testing Your Sites

Now that your configuration files are ready, you can enable your site using the a2ensite command:

  1. sudo a2ensite example.com.conf

To prevent the default site from serving unintended traffic, disable it:

  1. sudo a2dissite 000-default.conf

Before applying any changes, always test your Apache configuration for syntax errors:

  1. sudo apache2ctl configtest

You should see this output:

Syntax OK

If there are no syntax errors, reload Apache to apply the configuration changes:

  1. sudo systemctl reload apache2

This command gracefully reloads the service, applying new settings without disconnecting existing users.

You can confirm that both virtual hosts are active by listing the enabled sites:

  1. sudo apache2ctl -S

You’ll see an output that includes your domain and the associated configuration file paths.

Now, open your browser and visit your site:

http://example.com

If everything is set up correctly, you should see the sample page you created earlier.

Installing TLS/SSL with Let’s Encrypt

Using HTTPS has become the standard for all modern websites, not only to secure user data but also to improve search rankings and user trust. The easiest way to obtain and manage free SSL/TLS certificates is through Let’s Encrypt, a certificate authority that provides automated, no-cost certificates.

Let’s Encrypt works together with Certbot, a lightweight command-line tool that handles certificate creation, installation, and renewal automatically.

In this section, you’ll install Certbot, generate a certificate for your domain, and verify that automatic renewal is configured correctly.

Installing Certbot and the Apache Plugin

Certbot is included in Ubuntu’s default repositories, along with a plugin that integrates directly with Apache.

Update your package index and install both packages:

  1. sudo apt update
  2. sudo apt install certbot python3-certbot-apache
  • The certbot package handles certificate requests and renewals.
  • The python3-certbot-apache plugin automates the Apache configuration process for HTTPS.

Once installed, you can verify Certbot’s version with:

  1. certbot --version

Generating a Let’s Encrypt Certificate

With Certbot installed, you can request and install a certificate for your domain in a single step. Replace example.com and www.example.com with your actual domain names:

  1. sudo certbot --apache -d example.com -d www.example.com

Certbot will:

  1. Communicate with Let’s Encrypt’s servers to verify domain ownership.
  2. Generate a valid SSL/TLS certificate.
  3. Automatically update your Apache virtual host to use HTTPS.
  4. Reload Apache to apply the changes.

You’ll be asked to provide an email address for renewal notices and agree to the Let’s Encrypt Terms of Service. When prompted, you can also choose whether to redirect HTTP traffic to HTTPS. Selecting “Redirect” is recommended, as it enforces secure connections for all visitors.

After the setup completes, Certbot will display a message confirming that the certificate was successfully installed.

You can verify your certificate’s expiration date with:

  1. sudo certbot certificates

The output should list your domain name and indicate that your certificate is valid for 90 days.

Automatic Certificate Renewal

Let’s Encrypt certificates are valid for 90 days, but Certbot includes a built-in systemd timer that automatically renews them before they expire.

You can confirm that the renewal timer is active with:

  1. sudo systemctl status certbot.timer

You should see output similar to this:

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled)
     Active: active (waiting) since Tue 2025-12-02 15:00:00 UTC; 1h ago
      Trigger: Wed 2025-12-03 00:00:00 UTC; 8h left

This means that Certbot will automatically check for expiring certificates twice per day and renew them if necessary.

Note: If you installed Certbot via snap/distro packaging, the mechanism may be a systemd timer or a cron job. You can check this with systemctl list-timers.

To manually test the renewal process without making changes, use:

  1. sudo certbot renew --dry-run

If you see “Congratulations! Your certificate and chain have been saved successfully.”, automatic renewal is working as expected.

Testing Your HTTPS Configuration

After your certificate is installed, open your site in a web browser and verify that it loads securely:

https://example.com

You should see the padlock icon in the browser’s address bar, indicating that HTTPS is active and the connection is encrypted.

You can also verify the configuration using the command line with:

  1. curl -I https://example.com

A valid response should include:

HTTP/2 200
content-type: text/html
strict-transport-security: max-age=31536000; includeSubDomains

If you see this response, your site is correctly serving HTTPS traffic.

Getting Familiar with Important Apache Files and Directories

Now that Apache is installed, configured, and serving your site, it’s helpful to understand where key files and directories are located. Knowing how Apache’s configuration is organized will make it easier to manage multiple sites, enable modules, and troubleshoot issues later.

/var/www/ — Web Root Directories

This is where your website content lives. By default, Apache serves files from /var/www/html, which contains the default Apache landing page you saw after installation.

When hosting multiple sites, it’s common to create a dedicated directory for each one, such as:

/var/www/example.com
/var/www/myblog.com
/var/www/api.example.com

Each virtual host you configure can point to its own directory inside /var/www. This structure keeps your projects organized and allows you to apply permissions or ownership separately per site.

/etc/apache2/ — Apache Configuration Directory

This directory contains all of Apache’s configuration files. Most of your administrative work, including enabling sites, changing ports, or managing modules, happens here.

The key files and subdirectories include:

Location Description
/etc/apache2/apache2.conf The main configuration file. It loads the other configuration files and sets global options that affect the entire server.
/etc/apache2/ports.conf Defines which ports Apache listens on. By default, Apache listens on port 80 (HTTP) and port 443 (HTTPS) when SSL is enabled.
/etc/apache2/envvars Contains environment variable settings used by Apache, such as the user and group under which it runs (www-data by default).
/etc/apache2/conf-enabled/ Contains symbolic links to active configuration fragments found in /etc/apache2/conf-available/. Used for settings that apply to all sites (for example, security headers or timeout directives).

sites-available/ and sites-enabled/ — Virtual Host Configurations

Apache separates virtual host configurations into two directories:

  • /etc/apache2/sites-available/ contains all virtual host configuration files. These files define how Apache serves each site, including the document root, domain names, and logging directives.
  • /etc/apache2/sites-enabled/ contains symbolic links to the active site configurations found in sites-available/.

To activate a site, use:

  1. sudo a2ensite example.com.conf

To deactivate it:

  1. sudo a2dissite example.com.conf

This approach makes it easy to manage multiple websites without editing global configuration files. You can quickly enable or disable sites as needed, and Apache will only load configurations that are linked in sites-enabled/.

mods-available/ and mods-enabled/ — Apache Modules

Apache’s functionality is modular, meaning most features, such as SSL, rewrite rules, or compression, are implemented as modules that can be loaded dynamically.

  • /etc/apache2/mods-available/ contains configuration (.conf) and load (.load) files for all available modules.
  • /etc/apache2/mods-enabled/ contains symbolic links to the modules that are currently enabled.

You can enable or disable modules using these commands:

  1. sudo a2enmod module_name
  2. sudo a2dismod module_name

For example, to enable the rewrite and ssl modules (common for HTTPS sites):

  1. sudo a2enmod rewrite ssl

After enabling or disabling modules, reload Apache to apply the changes:

  1. sudo systemctl reload apache2

conf-available/ and conf-enabled/ — Configuration Fragments

These directories are similar to the site directories but are used for global configuration snippets that don’t belong to a specific virtual host.

For example, a configuration file that sets default security headers or MIME types might live in /etc/apache2/conf-available/, and when enabled, a symbolic link is created in /etc/apache2/conf-enabled/.

You can enable or disable these configuration fragments with:

  1. sudo a2enconf config_name
  2. sudo a2disconf config_name

Like site configurations, these fragments are only active when linked in conf-enabled/.

/var/log/apache2/ — Log Files

Apache logs nearly every event, from client requests to errors, in the /var/log/apache2/ directory. Monitoring these logs is one of the best ways to understand how your server is performing and to troubleshoot problems.

The two most common log files are:

File Description
/var/log/apache2/access.log Records every request to the web server, including the client IP, requested URL, status code, and user agent.
/var/log/apache2/error.log Captures startup messages, warnings, and errors. Useful for diagnosing configuration issues or site-level problems.

You can view the most recent log entries with:

  1. sudo tail -f /var/log/apache2/access.log

or

  1. sudo tail -f /var/log/apache2/error.log

For a broader view across all Apache logs, you can use:

  1. sudo journalctl -u apache2 --no-pager

This command shows recent service messages collected by systemd, combining traditional logs with service-level events.

Tip: On high-traffic sites, log files can grow quickly. Ubuntu includes logrotate, which automatically compresses and rotates Apache logs to prevent them from filling up disk space. You can view its configuration at /etc/logrotate.d/apache2.

Security Best Practices

Once Apache is installed and serving your websites, the next step is securing your web server. Even a correctly configured Apache installation can expose unnecessary information or become vulnerable if not hardened properly. The following best practices will help protect your system against common attacks, reduce information exposure, and keep your web environment stable and up to date.

Disable Directory Listing

By default, Apache may display the contents of a directory if it does not contain an index file. This can unintentionally expose sensitive information, such as backup files, configuration scripts, or version numbers.

To disable directory listing, open your site’s configuration file:

  1. sudo nano /etc/apache2/sites-available/example.com.conf

Inside the <Directory> block or the virtual host configuration, ensure the Options directive does not include Indexes. For example:

<Directory /var/www/example.com>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Save the file and reload Apache to apply your changes:

  1. sudo systemctl reload apache2

Now, if a directory does not contain an index.html file, Apache will return a 403 Forbidden error instead of listing its contents.

Restrict File Permissions and Ownership

File and directory permissions should always follow the principle of least privilege.

  • The owner of each web root should be the user who manages the files.
  • The group should typically remain www-data, which is the default user that Apache runs as.

You can set these permissions with the following commands:

  1. sudo chown -R $USER:www-data /var/www/example.com
  2. sudo find /var/www/example.com -type d -exec chmod 755 {} \;
  3. sudo find /var/www/example.com -type f -exec chmod 644 {} \;

These commands ensure that directories are readable and executable by everyone but writable only by the owner, while files are readable by everyone and writable only by the owner.

Avoid granting 777 permissions, as they allow any user on the system to modify web files.

Enable Security Headers

Security headers help protect browsers from common web vulnerabilities like cross-site scripting (XSS), clickjacking, and content-type sniffing.

If you have not already done so, enable the headers module:

  1. sudo a2enmod headers

Then, open your site’s virtual host configuration file:

  1. sudo nano /etc/apache2/sites-available/example.com.conf

Inside the <VirtualHost> block, add the following headers:

Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"

You can also apply a basic Content Security Policy (CSP) to control which resources the browser can load:

Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self';"

This policy allows only local scripts and styles to load from the same domain.

Save your changes and reload Apache:

  1. sudo systemctl reload apache2

To confirm that the headers are active, you can test your site with curl:

  1. curl -I https://example.com

Look for the headers in the response. You can also use securityheaders.com to analyze your configuration.

Harden SSL and TLS Configuration

Apache 2.4.58 on Ubuntu 24.04 supports TLS 1.3 by default, provided your OpenSSL version is 1.1.1 or later (check with openssl version). To ensure strong encryption and compatibility, open the SSL configuration file:

  1. sudo nano /etc/apache2/mods-available/ssl.conf

Verify or update the following settings:

SSLProtocol TLSv1.2 TLSv1.3
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
SSLHonorCipherOrder on

These settings disable older, insecure protocols and ciphers.

After saving the file, reload Apache:

  1. sudo systemctl reload apache2

For stricter or more compatible configurations (Modern or Old profiles), you can generate templates at: SSL Configuration Generator. You can also test your site’s SSL configuration using Qualys SSL Labs to verify that it scores at least an “A” rating.

Disable Unused Apache Modules

Every enabled module increases Apache’s attack surface. To reduce potential vulnerabilities, disable any modules that are not required for your site.

List enabled modules with:

  1. apache2ctl -M

If you see a module you are not using, disable it with:

  1. sudo a2dismod module_name

For example, if your site does not use CGI scripts:

  1. sudo a2dismod cgi

After disabling modules, reload Apache:

  1. sudo systemctl reload apache2

Keep essential modules such as ssl, rewrite, headers, and mpm_event active, as they are commonly used for secure, high-performance websites.

Keep the System Updated Automatically

Keeping your server updated is one of the most effective ways to prevent vulnerabilities. Security patches are released regularly for both Ubuntu and Apache. To ensure your server always receives updates, enable unattended-upgrades, which installs security updates automatically.

Install the package:

  1. sudo apt install unattended-upgrades

Then enable automatic updates:

  1. sudo dpkg-reconfigure --priority=low unattended-upgrades

By default, the service runs daily and applies available security updates silently. You can check the status of the timer with:

  1. systemctl status apt-daily-upgrade.timer

Logs are stored in /var/log/unattended-upgrades/.

To apply updates manually at any time, run:

  1. sudo apt update && sudo apt upgrade

Additional Recommendations

To further improve security and server reliability:

  • Use strong passwords or SSH keys for administrative access.
  • Restrict SSH access to known IP addresses using UFW or cloud firewalls.
  • Set up fail2ban to automatically block repeated failed login attempts.
  • Regularly back up your /etc/apache2/ and /var/www/ directories.
  • Monitor logs for unusual activity using tools like goaccess or journalctl.

Basic Troubleshooting

Even a correctly configured Apache server can occasionally fail to start, reload, or serve web pages. Common issues usually involve syntax errors, missing permissions, or blocked ports.

1. Check Apache Service Logs

When Apache does not start or reload properly, the first place to look is the service log. Apache integrates with systemd, so logs are managed by the journalctl command.

To view recent log entries:

  1. sudo journalctl -u apache2 --no-pager

This displays Apache-related messages, including startup logs, configuration warnings, and module errors.

If you want to see live log updates while restarting or reloading Apache, use:

  1. sudo journalctl -u apache2 -f

The log output can reveal valuable details such as:

AH00526: Syntax error on line 14 of /etc/apache2/sites-enabled/example.com.conf:
Invalid command 'Redirectt'

or

(13)Permission denied: AH00072: make_sock: could not bind to address [::]:80

In these cases:

  • The first indicates a typo or syntax issue in a configuration file.
  • The second means Apache cannot bind to port 80, usually because another process is using it or UFW or a cloud firewall is blocking it.

Checking logs is often the quickest way to pinpoint why Apache isn’t starting or responding.

2. Test Apache Configuration Syntax

A common mistake is reloading Apache after editing a configuration file without testing it first. Apache includes a built-in syntax checker that scans all configuration files for errors.

Run the following:

  1. sudo apache2ctl configtest

If your configuration is valid, you’ll see:

Syntax OK

If not, the command will show the file and line number containing the issue. For example:

AH00526: Syntax error on line 25 of /etc/apache2/sites-enabled/example.com.conf:
Invalid command 'ServerNme', perhaps misspelled or defined by a module not included in the server configuration

This tells you exactly where the problem is located. Once you fix the issue, test again until the syntax passes.

Finally, reload Apache to apply the working configuration:

  1. sudo systemctl reload apache2

Tip: Always run configtest before reloading Apache, especially on production servers. It prevents accidental downtime caused by broken configurations.

3. Check Listening Ports and Conflicting Services

If your Apache service starts but your site doesn’t load, it may not be listening on the expected ports (80 for HTTP, 443 for HTTPS), or another application could be using those ports.

Check which ports Apache is currently listening on:

  1. sudo ss -tuln | grep apache

You should see output similar to:

LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("apache2",pid=1534,fd=4))
LISTEN 0 511 [::]:443   [::]:*    users:(("apache2",pid=1535,fd=6))

This confirms Apache is listening on both HTTP and HTTPS.

If no entries appear, check that your virtual hosts and SSL module are enabled:

  1. sudo a2enmod ssl
  2. sudo a2ensite example.com.conf
  3. sudo a2ensite example.com-le-ssl.conf
  4. sudo systemctl reload apache2

If another process is using port 80 or 443, identify it:

  1. sudo ss -tulpn | grep ':80\|:443'

This will show which process ID (PID) and program name are bound to the ports. For example:

nginx   1920  root  6u  IPv4  37221  0t0  TCP *:80 (LISTEN)

If another web server like Nginx or a development process (for example, Node.js) is using the same port, you can either stop that service or reconfigure one of them to use a different port.

4. Fix Common Permission and Ownership Errors

If Apache starts correctly but returns a “403 Forbidden” error or fails to load your site, it often means that file permissions or ownership are incorrect. Apache must be able to read the files under your site’s web root, and they must be owned by the right user and group.

To fix ownership and permissions, run:

  1. sudo chown -R $USER:www-data /var/www/example.com
  2. sudo find /var/www/example.com -type d -exec chmod 755 {} \;
  3. sudo find /var/www/example.com -type f -exec chmod 644 {} \;

These commands set:

  • The current user as the owner (so you can edit files easily).
  • The www-data group for Apache.
  • Secure permissions for files and directories.

You can confirm the permissions using:

  1. ls -ld /var/www/example.com

The output should look like this:

drwxr-xr-x 3 user www-data 4096 Jan 10 12:34 /var/www/example.com

If your site uses uploads or caching (like WordPress), you may need to give Apache write access to specific directories:

  1. sudo chmod 775 /var/www/example.com/wp-content/uploads

Be cautious not to apply global write access, as it can open serious security risks.

5. Check DNS Configuration and Propagation

If your site works when accessed via its IP address but not through the domain name, it is usually a DNS or propagation issue.

First, check that your domain points to the correct server IP:

  1. dig example.com +short

Compare the result with your server’s public IP address:

  1. curl -4 icanhazip.com

If they don’t match, update your DNS records at your registrar or DNS provider.

You can also check global DNS propagation using a tool such as whatsmydns.net.

If you recently updated DNS records, remember that propagation can take several hours depending on the TTL (time-to-live) values configured for your domain.

If you’re hosting your DNS on DigitalOcean, make sure your A (IPv4) and AAAA (IPv6) records are correctly configured in the Networking -> Domains section of the control panel.

6. Verify Cloud and Local Firewall Rules

Sometimes Apache runs correctly but is inaccessible from the internet because traffic is being blocked by a firewall. Ubuntu uses UFW by default.

Check your firewall status:

  1. sudo ufw status

You should see entries like this:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Apache Full                ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Apache Full (v6)           ALLOW       Anywhere (v6)

If the Apache Full profile is missing, enable it:

  1. sudo ufw allow 'Apache Full'

Then reload UFW:

  1. sudo ufw reload

If you’re running Apache on a cloud provider such as DigitalOcean, confirm that the cloud firewall also allows inbound connections on ports 80 and 443.

For example, in the DigitalOcean Control Panel:

  1. Go to Networking -> Firewalls.
  2. Select your Droplet’s firewall.
  3. Ensure inbound rules for HTTP (80) and HTTPS (443) are both allowed.

If you’re using a load balancer or CDN, confirm that it is properly forwarding requests to your Droplet’s IP address and ports.

7. Identify and Fix Broken Virtual Host Configurations

Apache uses virtual hosts to map domain names to specific directories and configurations. A broken or conflicting virtual host file is one of the most common problems beginners face.

To list all active virtual hosts, use:

  1. sudo apache2ctl -S

This command shows each domain’s configuration file and port. Look for:

  • The correct ServerName (must match your domain).
  • A valid DocumentRoot path (should point to your web directory).
  • No duplicate entries for the same port.

If you see this warning:

AH00558: apache2: Could not reliably determine the server's fully qualified domain name

Add a global ServerName directive to fix it:

  1. echo "ServerName localhost" | sudo tee /etc/apache2/conf-available/servername.conf
  2. sudo a2enconf servername.conf
  3. sudo systemctl reload apache2

If one of your site configurations is broken and prevents Apache from starting, disable it temporarily:

  1. sudo a2dissite example.com.conf
  2. sudo systemctl reload apache2

Then review the file in /etc/apache2/sites-available/ for issues such as:

  • Missing </VirtualHost> closing tags
  • Incorrect indentation or misplaced directives
  • Wrong log or document paths

Once fixed, re-enable the site:

  1. sudo a2ensite example.com.conf
  2. sudo systemctl reload apache2

Your site should now load correctly.

Tip: When troubleshooting Apache, isolate each issue step-by-step. Start by confirming that the service is running, then check the configuration syntax, permissions, ports, and DNS. Apache’s error logs (journalctl and /var/log/apache2/error.log) almost always contain the clues you need.

FAQs

1. How do I install Apache on Ubuntu?

You can install Apache from Ubuntu’s default repositories. Update your package index and install Apache with:

  1. sudo apt update
  2. sudo apt install apache2

Once installed, Apache starts automatically. You can verify it with:

  1. sudo systemctl status apache2

2. How do I start, stop, or restart Apache?

Use the systemctl command to control the Apache service:

  1. sudo systemctl start apache2
  2. sudo systemctl stop apache2
  3. sudo systemctl restart apache2

To reload configuration changes without interrupting active connections, use:

  1. sudo systemctl reload apache2

You can also check if it starts automatically at boot using:

  1. sudo systemctl is-enabled apache2

3. How do I configure virtual hosts in Apache?

Virtual hosts let you host multiple sites on one server. Create a new configuration file in /etc/apache2/sites-available/:

  1. sudo nano /etc/apache2/sites-available/example.com.conf

Add a basic configuration block:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
</VirtualHost>

Save the file, enable the site, and reload Apache:

  1. sudo a2ensite example.com.conf
  2. sudo systemctl reload apache2

4. How do I allow HTTP and HTTPS traffic through the Ubuntu firewall?

If you’re using UFW, list the available application profiles with:

  1. sudo ufw app list

Then allow full Apache access (both HTTP and HTTPS):

  1. sudo ufw allow 'Apache Full'

Check your firewall status to confirm:

  1. sudo ufw status

5. How can I test if Apache is working correctly?

Open your browser and visit your server’s public IP address:

http://your_server_ip

You should see the default Apache welcome page. You can also check the service status with:

  1. sudo systemctl status apache2

If the page does not load, review the firewall settings and confirm that Apache is active.

6. Where is the default web root directory in Ubuntu?

By default, Apache serves content from /var/www/html.

You can replace or modify the index.html file in this directory to change what appears on your site’s home page. When hosting multiple domains, you can create additional directories such as /var/www/example.com.

7. How do I troubleshoot Apache not starting?

Start by checking for syntax errors:

  1. sudo apache2ctl configtest

If you see anything other than “Syntax OK,” fix the listed issue. Then review service logs for errors:

  1. sudo journalctl -u apache2 --no-pager

If ports 80 or 443 are already in use, identify the conflicting service with:

  1. sudo ss -tulpn | grep ':80\|:443'

Permission issues can also prevent Apache from reading files in /var/www/. Make sure your user and group ownership are correct and that directories are readable.

8. How do I enable SSL on Apache in Ubuntu?

Enable the SSL and headers modules first:

  1. sudo a2enmod ssl
  2. sudo a2enmod headers

You can then install Let’s Encrypt to get a free SSL certificate:

  1. sudo apt install certbot python3-certbot-apache
  2. sudo certbot --apache -d example.com -d www.example.com

Certbot will automatically configure HTTPS and handle renewals. Once installed, you can test renewal with:

  1. sudo certbot renew --dry-run

Summary

In this tutorial, you installed and configured the Apache web server on an Ubuntu server. You verified that Apache was running, allowed HTTP and HTTPS traffic through the firewall, and created virtual hosts for both protocols. You secured your site with Let’s Encrypt SSL certificates, applied key security settings, and learned how to manage Apache modules, logs, and configurations.

Your server is now fully configured and ready to host production websites. To continue exploring, check out the following articles:

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Erin Glass
Erin Glass
Author
Senior Manager, DevEd
See author profile

Open source advocate and lover of education, culture, and community.

Manikandan Kurup
Manikandan Kurup
Editor
Senior Technical Content Engineer I
See author profile

With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers.

Still looking for an answer?

Was this helpful?


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Thank you very much for your easy instructions on installing Apache2 server. it still proves that it takes a woman to get things right. I just switched over from centos 7 to the ubuntu 20.04 server due to vestacp problems and no kind of support for why my add on domains would not work but yet the main admin one would. still baffels me, but i’m a glutten for punishment so thought i would try it out on ubuntu 20.04. any way thanks for the excellent info and help the enternet needs more like you.

Hello!

Thanks for sharing this information. Here is a question

I have a website(example.com) already running in /var/www/html can i add another website (newdomain.com) by creating directory /var/www/newdomain.com and use it. Without changing the location of example.com as you know it will take time to transfer from /var/www/html to /var/www/example.com

Yes, i’m using Apache Web Server on Ubuntu 20.04 (LTS) x64

Please reply me ASAP

Now it’s easy, you can use easy-apache to set up everything for you, all you have to do is copy-paste below lines into your terminal, and enter your domain name when asked, it will also install SSL if you want

sudo add-apt-repository ppa:realpvn/easy-apache
sudo apt-get update
sudo apt-get install easy-apache

#to install Apache server
easy-apache -a

#to install SSL
easy-apache -s

#full setup, Apache and SSL
easy-apache -f

A very nice piece of Information. Nicely written. Thanks a lot. I was wondering for basic apache server setup. I will remember your name as my teacher. GBY.

how do I make my site visible to any other computer?

Issue: Error AH00558: Could not reliably determine the server’s fully qualified domain name

Solution: Add a line containing ServerName 127.0.0.1 to the end of the file:

sudo nano /etc/apache2/apache2.conf

Restart apache2

sudo systemctl restart apache2

=========================================================

Issue: can access the website via IP but not Domain Solution:

sudo nano /etc/hosts

add this code:

127.0.0.1    www.YOURDOMAIN.com

Restart apache2

sudo systemctl restart apache2

Worked great Thank you for the walkthrough!!!

Do we need to add /public_html to the directory if we want to add more than one virtual host site? If I add one using the above method it works fine but if I add a second one the second one won’t show up.

Thanks Erin!

Just a comment, that could help people. When following your tutorial after doing the configtest of apache I found ERROR AH00558. Since I was starting from scratch from a Desktop 20.04 Ubuntu distribution, I assume that it will happen to anybody doing the same thing.

The fix is easy, just add to your tutorial that if they find this error all they need to do is to add this line to their /etc/apache2/apache2.conf file using sudo nano /etc/apache2/apache2.conf, going to the end of the file and adding it, then <Ctrl>S, followed by <Ctrl>X

vim: syntax=apache ts=4 sw=4 sts=4 sr noet

ServerName 127.0.0.1

This is one of the best-written tutorials I’ve ever followed. Thanks, Erin!

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.