Configure Apache on the Ubuntu operating system
The Ubuntu operating system uses a different Apache layout than those used in non-Debian-based operating systems. The differences are small, but helpful in configuring and deploying websites. This article explains some of the site and module configuration settings for Apache on the Ubuntu operating system, and describes how to enable and disable sites and modules as needed.
Apache Installation
Use aptitude to install Apache on your server running the Ubuntu operating system.
The advantage of using aptitude is that you will get any security updates from the Ubuntu operating system (if and when distributed), and dependencies are automatically installed.
Installation Of Apache2:
### Update your system package repository and install Apache:
$ sudo apt update
Hit:1 https://mirror.rackspace.com/ubuntu noble InRelease
Hit:2 https://mirror.rackspace.com/ubuntu noble-updates InRelease
Hit:3 https://mirror.rackspace.com/ubuntu noble-backports InRelease
Hit:4 https://mirror.rackspace.com/ubuntu noble-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
154 packages can be upgraded. Run 'apt list --upgradable' to see them.
$ sudo apt install apache2
Reading package lists... Done
Building dependency tree... Done
......
Created symlink /etc/systemd/system/multi-user.target.wants/apache2.service → /usr/lib/systemd/system/apache2.service.
Created symlink /etc/systemd/system/multi-user.target.wants/apache-htcacheclean.service → /usr/lib/systemd/system/apache-htcacheclean.service.
Processing triggers for ufw (0.36.2-6) ...
Processing triggers for man-db (2.12.0-4build2) ...
Processing triggers for libc-bin (2.39-0ubuntu8.4) ...Verify the installation and check Apache version:
$ sudo apache2 -v
Server version: Apache/2.4.58 (Ubuntu)
Server built: 2025-08-11T11:10:09Starting and Enabling Apache:
$ sudo apache2ctl -t
$ sudo systemctl enable --now apache2
Synchronizing state of apache2.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable apache2
$ sudo systemctl is-active apache2.service
active
$ sudo systemctl status apache2.service ## (You should see active (running) in the output.)Configuring the Firewall:
If you are using the Firewall at the OS end, the details would be helpful for you.
Allow HTTP and HTTPS traffic through Ubuntu's UFW firewall:
$ sudo ufw status numbered
$ sudo ufw allow 'Apache Full'
$ sudo ufw reload
Firewall reloaded
$ sudo ufw status
Status: active
To Action From
-- ------ ----
Apache Full ALLOW Anywhere
Apache Full (v6) ALLOW Anywhere (v6) Verifying the Installation
Open your web browser and navigate to your server's IP address:
http://your_server_ip
Or you can use CURL
$ curl -IkL http://your_server_ip (The output will look like below)
HTTP/1.1 200 OK
Date: Tue, 13 Jan 2026 13:24:16 GMT
Server: Apache/2.4.58 (Ubuntu)
Last-Modified: Tue, 13 Jan 2026 13:19:33 GMT
ETag: "29af-64844d7b1e0ea"
Accept-Ranges: bytes
Content-Length: 10671
Vary: Accept-Encoding
Content-Type: text/html
You should see the default Apache welcome page indicating successful installation.
Understanding Apache Directory Structure
Apache on Ubuntu follows a specific organizational pattern designed for easy management:
Main Configuration:
/etc/apache2/apache2.conf - Primary server configuration file
/etc/apache2/ports.conf - Port listening configuration
/etc/apache2/envvars - Environment variables for Apache
Site Configurations:
/etc/apache2/sites-available/ - Available site configuration files
/etc/apache2/sites-enabled/ - Active site configurations (symlinks)
Module Management
/etc/apache2/mods-available/ - Available Apache modules
/etc/apache2/mods-enabled/ - Enabled modules (symlinks)
Configuration Snippets:
/etc/apache2/conf-available/ - Additional configuration snippets
/etc/apache2/conf-enabled/ - Enabled configuration snippets
Web Content:
By default, Apache serves web content from /var/www/html, but you can change the document root to any directory that meets your requirements. Just make sure the new location has the correct permissions and ownership (typically www-data or apache), and update the DocumentRoot directive in your virtual host configuration
/var/www/html/ - Default document root
/var/www/ - Recommended location for hosting multiple sites
Log Files:
/var/log/apache2/access.log - Access logs
/var/log/apache2/error.log - Error logs
View the configuration file
To view the contents of the Apache configuration file, run the following commands:
$ cd /etc/apache2
$ lsThe output should look as follows:
$ ls
apache2.conf conf-available conf-enabled envvars magic mods-available mods-enabled ports.conf sites-available sites-enabledConfiguration Directory/Files
This section explains the configuration settings in the following folders:
- sites-available
- sites-enabled
- mods-available
- mods-enabled
sites-available
The sites-available folder contains the configurations for each site that you
want to serve. These are known as virtual hosts, or vhosts.
If you look inside this folder, you should see that there is one (default) site available:
$ ls sites-available/
...
000-default.conf default-ssl.conf
The Apache installation has a 000-default and a default-ssl vhost available. When you
navigate to the IP address of your cloud server and get the "It works!" message, the
default file is telling Apache what to do and where the files were located.
Note: A file in the sites-available folder is not automatically active. It is simply available
for serving if you enable it.
sites-enabled
The sites-enabled folder contains symlinks to the sites that you are actually serving.
For example, you could have two vhosts configured and ready for use in the sites-available
folder, but only the vhost that has a symlink from the site-enabled folder is being served.
If you look inside this folder, you see which site is currently enabled:
$ ls -l sites-enabled/
...
lrwxrwxrwx 1 root root 35 Jan 7 10:25 000-default.conf -> ../sites-available/000-default.conf
This result shows that the default site is enabled. The symlink named 000-default
links to the 000-default file in the sites-available folder.
Note: A domain can point to your cloud
server's IP address but have no site configuration file. In such a case, the first enabled
site (alphabetically) is displayed. For example, the configuration for 000-default would be used.
mods-available
The mods-available folder contains the modules that are available to be loaded.
Look inside the folder by running the following command:
$ ls mods-available
A list of modules is available from the base installation, but they are not all enabled; they are just available for use. Just as with the vhosts files, any modules that you want to use must be enabled.
mods-enabled
The mods-enabled folder contains symlinks to the modules that are enabled.
Use the following command to look inside the folder:
$ ls mods-enabled
This resulting list is much shorter than the list of available modules, and it includes enabled modules such as mpm_event.conf.
Enable and Disable sites and modules
You can use the commands in this section to enable and disable sites and modules.
a2ensite
The a2ensite command establishes a symlink to a site that is not already enabled.
Useful for enabling the website.
a2: Apache2 (what Ubuntu calls Apache)en: enablesite: website virtual host
Enable the default site with the following command:
$ sudo a2ensite sitename
$ sudo a2ensite 000-default
You should see output similar to the following:
Enabling site 000-default.
To activate the new configuration, you need to run:
systemctl reload apache2
Reload Apache with the following command to ensure that the site is enabled:
$ sudo apache2ctl -t
$ sudo systemctl reload apache2
If you visit your cloud server's IP address in a web browser, you will see that the default page is being served.
a2dissite
The a2dissite command deletes the symlink to a site that you have previously enabled.
Useful for disabling your website.
- a2: Apache2 (what Ubuntu calls Apache)
- dis: disable
- site: website virtual host
For example, to disable the default site, run the following command:
$ sudo a2dissite sitename
$ sudo a2dissite
Your choices are: 000-default
Which site(s) do you want to disable (wildcards ok)?
OR
$ sudo a2dissite 000-default
The symlink to the 000-default site in the sites-enabled folder is deleted. You should see output similar to the following:
$ sudo a2dissite 000-default
Site 000-default disabled.
To activate the new configuration, you need to run:
systemctl reload apache2
Reload Apache with the following command to ensure that the site is fully disabled:
$ sudo apache2ctl -t
$ sudo systemctl reload apache2
When you now visit your cloud server's IP address in a web browser, you will get a 404 Not Found message instead of the "It Works!" page.
Note: The main vhosts file in the sites-available folder still exists. The a2dissite
Command just removed the symlink to it in the sites-enabled folder.
a2dismod
The a2dismod command disables any modules you have previously enabled.
- a2: Apache2 (what Ubuntu calls Apache)
- dis: disable
- mod: Module
For example, disable the mpm_event module with the following command:
$ sudo a2dismod
Your choices are: access_compat alias auth_basic authn_core authn_file authz_core authz_host authz_user autoindex deflate dir env filter mime mpm_event negotiation reqtimeout setenvif status
Which module(s) do you want to disable (wildcards ok)?
You should see output similar to the following output:
$ sudo a2dismod mpm_event
Module mpm_event disabled.
To activate the new configuration, you need to run:
systemctl restart apache2
If you look in the mods-enabled folder, you will see that the mpm_event.conf
and mpm_event.load symlinks have been deleted.
Note: Be sure to reload Apache after each module change for your cloud server's IP address to reflect any changes that you have made.
a2enmod
The a2enmod command enables any module that is in the mods-available folder.
- a2: Apache2 (what Ubuntu calls Apache)
- en: enable
- mod: Module
For example, enable the mpm_event module by running the following command:
$ sudo a2enmod mpm_event
You should see output similar to the following output:
$ sudo a2enmod mpm_event
Considering conflict mpm_worker for mpm_event:
Considering conflict mpm_prefork for mpm_event:
Enabling module mpm_event.
To activate the new configuration, you need to run:
systemctl restart apache2
$ sudo a2enmod ssl
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
systemctl restart apache2
If you check the mods-enabled folder, you will see the mpm_event.conf and
mpm_event.load symlinks.
Note: Be sure to reload Apache after each module change for your cloud server's
IP address to reflect any changes that you have made.
Service Control:
$ sudo apache2ctl -t
$ sudo systemctl restart apache2 # Full restart
$ sudo systemctl reload apache2 # Reload configuration
$ sudo systemctl stop apache2 # Stop serviceConfiguring Virtual Hosts
Virtual hosts enable hosting multiple websites on a single server, each with its own domain and configuration.
Creating Directory Structure
Create directories for your first website:
$ sudo mkdir -p /var/www/example.com/public_html
$ sudo mkdir -p /var/www/example.com/logsCreate directories for a second website:
$ sudo mkdir -p /var/www/testdomain.net/public_html
$ sudo mkdir -p /var/www/testdomain.net/logsSet appropriate ownership:
$ sudo chown -R $USER:$USER /var/www/example.com
$ sudo chown -R $USER:$USER /var/www/testdomain.netConfigure proper permissions:
$ sudo chmod -R 755 /var/wwwCreating Sample Content
Create a test page for the first site:
$ sudo tee /var/www/example.com/public_html/index.html > /dev/null <<'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to Example.com</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
background-color: #f4f4f4;
}
h1 { color: #333; }
</style>
</head>
<body>
<h1>Success! Example.com is Working</h1>
<p>This Apache virtual host has been configured successfully.</p>
<p>Server Time: <?php echo date('Y-m-d H:i:s'); ?></p>
</body>
</html>
EOF
Create a test page for the second site:
$ sudo tee > /var/www/testdomain.net/public_html/index.html > /dev/null << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to TestDomain.net</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
background-color: #e8f4f8;
}
h1 { color: #0066cc; }
</style>
</head>
<body>
<h1>Success! TestDomain.net is Working</h1>
<p>Your second Apache virtual host is configured correctly.</p>
</body>
</html>
EOFCreating Virtual Host Configuration Files:
$ sudo vim /etc/apache2/sites-available/example.com.conf
$ sudo vim /etc/apache2/sites-available/testdomain.net.conf<VirtualHost *:80>
ServerAdmin [email protected]
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
<Directory /var/www/example.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
# Security headers
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Disable server signature
ServerSignature Off
</VirtualHost>Similarly, you can do this for the second website as well.
Understanding Virtual Host Directives
ServerAdmin : Email address displayed in error pages and used for administrative contact.
ServerName : Primary domain name for this virtual host.
ServerAlias : Additional domain names that serve the same content (e.g., www subdomain).
DocumentRoot : Directory containing the website files Apache will serve.
Options :
Indexes : Disables directory listing (security best practice)
FollowSymLinks : Allows following symbolic links
AllowOverride All : Permits .htaccess files to override configuration.
Require all granted : Allows access from all IP addresses.
ErrorLog / CustomLog : Specifies custom log file locations for this virtual host.
Enabling Virtual Hosts:
Refer previous details to enable the websites.
$ sudo a2enmod headersEnable your newly created sites:
$ sudo a2ensite example.com.conf
$ sudo a2ensite testdomain.net.confDisable the default site (optional but recommended):
$ sudo a2dissite 000-default.confTest your configuration for syntax errors:
$ sudo apache2ctl configtestIf the test returns Syntax OK, reload Apache:
$ sudo apache2ctl -t
$ sudo systemctl reload apache2
$ sudo systemctl status apache2Testing with Local Hosts File (Development)
Refer Modify your Hosts File
Security Configuration and Hardening
Securing Apache is critical to protecting your websites and server from vulnerabilities and attacks.
Hiding Apache Version Information:
$ sudo vim /etc/apache2/conf-enabled/security.conf## Set these directives:
ServerTokens Prod
ServerSignature Off
### Uses
ServerTokens Prod : Only sends "Apache" in headers (not version details).
ServerSignature Off : Removes version information from error pages.
Disabling Unnecessary Modules
List enabled modules:
$ sudo apache2ctl -MDisable modules you don't need (example):
$ sudo a2dismod status
$ sudo a2dismod autoindex### Common modules to review:
autoindex - Directory listings (usually disabled)
status - Server status information (disable on production)
userdir - User public_html directories (disable if unused)
Implementing Security Headers
Enable the headers module if not already enabled:
$ sudo a2enmod headers
$ sudo vim /etc/apache2/conf-available/security-headers.confAdd comprehensive security headers:
<IfModule mod_headers.c>
# Prevent clickjacking
Header always set X-Frame-Options "SAMEORIGIN"
# Prevent MIME type sniffing
Header always set X-Content-Type-Options "nosniff"
# Enable XSS filtering
Header always set X-XSS-Protection "1; mode=block"
# Control referrer information
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Content Security Policy (adjust based on your needs)
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
# Remove potentially sensitive information
Header always unset X-Powered-By
Header always unset X-AspNet-Version
</IfModule>
Enable the configuration:
$ sudo a2enconf security-headers
Enabling conf security-headers.
To activate the new configuration, you need to run:
systemctl reload apache2
$ sudo apache2ctl -t
$ sudo systemctl reload apache2Restricting Access by IP Address:
To restrict access to specific IP addresses for a directory or site:
<Directory /var/www/example.com/admin>
Require ip 192.168.1.100
Require ip 203.0.113.0/24
</Directory>Preventing Directory Traversal
Add this to your virtual host file:
<Directory /var/www>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>Protecting Sensitive Files
Add this to your virtual host or .htaccess file:
<FilesMatch "\.(htaccess|htpasswd|ini|log|sh|sql|conf)$">
Require all denied
</FilesMatch>
# Protect hidden files
<FilesMatch "^\.">
Require all denied
</FilesMatch>Enabling ModSecurity (Optional but Recommended):
ModSecurity is a Web Application Firewall (WAF):
$ sudo apt install libapache2-mod-security2 -y
$ sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
$ sudo nano /etc/modsecurity/modsecurity.confChange SecRuleEngine DetectionOnly to:
SecRuleEngine On$ sudo apache2ctl -t
$ sudo systemctl restart apache2SSL/TLS Certificate Implementation
HTTPS is now essential for all websites. You can purchase it from a verified vendor or can use Let's Encrypt for free SSL certificates. Use install-and-use-the-lets-encrypt-certbot-utility-on-centos7-with-apache
Understanding the SSL Virtual Host Configuration
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# Modern SSL configuration
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
# HSTS (uncomment after testing)
# Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
<Directory /var/www/example.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
</VirtualHost>Enabling HTTP Strict Transport Security (HSTS)
$ sudo vim /etc/apache2/sites-available/example.com-le-ssl.confUncomment or add:
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"Reload Apache:
$ sudo apache2ctl -t
$ sudo systemctl reload apache2Additional Content:
Optimizing Apache MPM Configuration
Check current MPM module:
$ sudo apache2ctl -V | grep MPMFor most modern servers, use the event MPM
$ sudo vim /etc/apache2/mods-available/mpm_event.confOptimize based on your server resources (example for 2GB RAM server):
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 3000
</IfModule>Restart Apache after changes:
$ sudo apache2ctl -t
$ sudo systemctl restart apache2Enabling HTTP/2
Enable the http2 module:
$ sudo a2enmod http2Add to your SSL virtual hosts:
<VirtualHost *:443>
Protocols h2 http/1.1
# ... rest of configuration
</VirtualHost>Reload Apache:
$ sudo apache2ctl -t
$ sudo systemctl reload apache2 Optimize Apache to handle traffic efficiently and reduce resource consumption.
_Note:- Example only — review and test before applying in production.
Enabling Compression (mod_deflate)
$ sudo a2enmod deflateCreate a compression configuration:
$ sudo vim /etc/apache2/conf-available/compression.conf<IfModule mod_deflate.c>
# Compress HTML, CSS, JavaScript, Text, XML and fonts
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
# Remove browser bugs (only needed for really old browsers)
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
Header append Vary User-Agent
</IfModule>Enable and reload:
$ sudo a2enconf compression
$ sudo apache2ctl -t
$ sudo systemctl reload apache2Enabling Browser Caching (mod_expires)
If your site serves static assets (images, CSS, JS, fonts), enabling browser caching significantly improves performance.
OR you can use a CDN instead.
_Note: - Example only — review and test before applying in production.
Enable the expires module:
$ sudo a2enmod expiresCreate caching configuration:
$ sudo vim /etc/apache2/conf-available/caching.conf<IfModule mod_expires.c>
ExpiresActive On
# Images
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
# Video
ExpiresByType video/mp4 "access plus 1 year"
ExpiresByType video/mpeg "access plus 1 year"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
# Fonts
ExpiresByType application/x-font-ttf "access plus 1 year"
ExpiresByType font/opentype "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
ExpiresByType application/font-woff "access plus 1 year"
ExpiresByType application/font-woff2 "access plus 1 year"
# Others
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
# HTML and HTM default
ExpiresDefault "access plus 1 week"
</IfModule>Enable and reload:
$ sudo a2enconf caching
$ sudo apache2ctl -t
$ sudo systemctl reload apache2_Note: - Proper log management prevents disk space issues and maintains system performance. Always review your logrotation for access and error logs or any custom log for Apache.
Troubleshooting some common Issues:
$ sudo apache2ctl configtest
Syntax OK
Common errors and solutions:
AH00526: Syntax error - Check for typos in directive names
AH00548: NameVirtualHost has no effect - Remove NameVirtualHost directive (deprecated in Apache 2.4+)Could not reliably determine the server's fully qualified domain name - Add ServerName directive to /etc/apache2/apache2.conf:
ServerName localhostConfirm Port listening (80/443).
If another service is running or any other instance is running on ports, you are unable to start Apache.
$ sudo lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 120857 root 5u IPv4 937022 0t0 TCP *:http (LISTEN)
nginx 120857 root 6u IPv6 937023 0t0 TCP *:http (LISTEN)
nginx 120858 www-data 5u IPv4 937022 0t0 TCP *:http (LISTEN)
nginx 120858 www-data 6u IPv6 937023 0t0 TCP *:http (LISTEN)
nginx 120859 www-data 5u IPv4 937022 0t0 TCP *:http (LISTEN)
nginx 120859 www-data 6u IPv6 937023 0t0 TCP *:http (LISTEN)Tail logs if something's off:
$ sudo journalctl -u apache2 -e --no-pager
Jan 07 10:25:33 testing-Dev systemd[1]: Starting apache2.service - The Apache HTTP Server...
Jan 07 10:25:33 testing-Dev apachectl[6132]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 2001:4802:7803:104:be76:4eff:fe20:206a. Set the 'ServerName' directive globally to suppress this message
...
$ tail -f /var/log/apache2/error.log
[Wed Jan 07 10:42:08.396584 2026] [mpm_event:notice] [pid 6133:tid 126500079703936] AH00493: SIGUSR1 received. Doing graceful restart
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 2001:4802:7803:104:be76:4eff:fe20:206a. Set the 'ServerName' directive globally to suppress this message
...Permission Denied Errors
- Review file ownership.
- Review directory permissions.
- Review file permissions.
403 Forbidden Errors
Check directory configuration allows access:
<Directory /var/www/example.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Best Practices
- Always test configurations before reloading Apache in production.the
- Keep Apache and Ubuntu up to date with the latest security patches.
- Use HTTPS everywhere - SSL certificates are free with Let's Encrypt.
- Implement security headers to protect against common vulnerabilities.
- Review if enabling compression and caching can increase performance.
- Monitor logs regularly for errors and suspicious activity.
- Set up log rotation to prevent disk space issues.
- Backup configurations before making changes.
- Use virtual hosts to organize multiple websites cleanly.
- Disable unused modules to reduce attack surface and resource usage.
- Restrict access to sensitive directories and files.
- Document your changes for future reference.
Updated 6 days ago
