On AlmaLinux and Rocky Linux, Apache is packaged as httpd. It is not the same layout as Ubuntu: there is no sites-available folder and no a2ensite command, and SELinux is on by default. This guide installs httpd, opens the firewall, explains where configuration lives and shows how to serve a site from a custom folder without SELinux blocking it.
Before you start
- A Linux VPS running AlmaLinux or Rocky Linux 8 or 9.
- An SSH login as root or as a user with
sudo. If you only have root, create a sudo user first. - Nothing else listening on ports 80 and 443. If Nginx is installed, stop it or Apache will fail to start.
- Optional: a domain whose A record points at your server IP, if you want to test with a name instead of the IP.
Install httpd with dnf
Update the package index and install Apache plus the SSL module:
sudo dnf update -y
sudo dnf install -y httpd mod_sslmod_ssl is not needed to serve plain HTTP, but you will want it later for HTTPS and certbot, so it is easier to add now.
Check the installed version:
httpd -vStart Apache and enable it on boot
Packages on RHEL-family systems do not start services for you. Start httpd and enable it in one step:
sudo systemctl enable --now httpd
sudo systemctl status httpdYou should see active (running). Press q to leave the status view.
The other commands you will use often:
sudo systemctl reload httpd # apply config changes without dropping connections
sudo systemctl restart httpd # full restart, needed after module changes
sudo apachectl configtest # check syntax before reloadingTip: Make apachectl configtest a habit. It should print Syntax OK. Reloading a broken config is the most common reason a site goes down after an edit.
Open HTTP and HTTPS in firewalld
AlmaLinux and Rocky ship with firewalld. Allow the web services permanently and reload the rules:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-servicesThe last command should list http and https next to ssh. If firewalld is new to you, read up on zones before changing other rules.
Warning: Do not remove the ssh service from the zone while you are connected over SSH. You can lock yourself out. If that happens, use the browser console in your VPS provider's control panel.
Understand the configuration layout
Everything lives under /etc/httpd:
/etc/httpd/conf/httpd.conf: the main file. It sets the user (apache), the defaultDocumentRootof/var/www/htmland loads the other folders./etc/httpd/conf.d/*.conf: your own files go here. Every.conffile in this folder is read in alphabetical order.ssl.confandwelcome.confcome from packages./etc/httpd/conf.modules.d/*.conf: one file per group of modules, withLoadModulelines./var/log/httpd/:access_loganderror_log.
So instead of enabling a site with a command, you create a file such as /etc/httpd/conf.d/example.com.conf. To disable it, rename it so it no longer ends in .conf, for example example.com.conf.off, and reload.
A minimal site file looks like this:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public
ErrorLog /var/log/httpd/example.com-error.log
CustomLog /var/log/httpd/example.com-access.log combined
</VirtualHost>The full walkthrough, with several domains, is in Apache virtual hosts for multiple websites.
Set SELinux contexts for web roots
SELinux decides what httpd may read, separately from normal file permissions. Files under /var/www already carry the right label, httpd_sys_content_t. A folder elsewhere, for example /srv/sites, does not, and Apache will return 403 Forbidden even if the permissions look right.
Check that SELinux is enforcing:
getenforceCreate the web root and add a test page:
sudo mkdir -p /var/www/example.com/public
echo '<h1>It works</h1>' | sudo tee /var/www/example.com/public/index.htmlIf you use a folder outside /var/www, add a permanent labelling rule and apply it:
sudo dnf install -y policycoreutils-python-utils
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/sites(/.*)?"
sudo restorecon -Rv /srv/sitesFor folders the application must write to, such as upload or cache directories, use the read-write type instead:
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/example.com/public/uploads(/.*)?"
sudo restorecon -Rv /var/www/example.com/public/uploadsTwo booleans come up often:
sudo setsebool -P httpd_can_network_connect 1 # Apache as a reverse proxy, or PHP calling external APIs
sudo setsebool -P httpd_can_network_connect_db 1 # PHP connecting to a remote databaseNote: Do not turn SELinux off to make an error go away. Find the denial and fix the label instead. Fix SELinux denials shows how to read the audit log.
Check it works
From the server itself:
curl -I http://localhostA HTTP/1.1 200 OK or 403 Forbidden with Server: Apache means httpd answers. The 403 here is the default welcome page shown when /var/www/html is empty; it is normal.
Then open http://203.0.113.10 in a browser, using your server IP. You should see the AlmaLinux or Rocky test page. Once your virtual host is in place, http://example.com should show your own page.
Confirm Apache is listening on port 80:
sudo ss -tlnp | grep httpdTroubleshooting
- Browser times out but
curl localhostworks: the firewall is blocking port 80. Re-run the firewalld commands and checkfirewall-cmd --list-services. Address already in usewhen starting httpd: another program holds port 80, usually Nginx. Find it withsudo ss -tlnp | grep:80and stop it.- 403 Forbidden on a custom folder: most likely the SELinux label. Run
ls -Zon the folder; if it showsdefault_toruser_home_t, apply thesemanage fcontextandrestoreconsteps above. AH00558: Could not reliably determine the server's fully qualified domain name: a warning, not an error. AddServerName example.comto/etc/httpd/conf/httpd.confto silence it.- Config changes have no effect: your file must end in
.confand sit in/etc/httpd/conf.d/. Reload after every change.
Next steps
- Host more than one domain: Set up Apache virtual hosts.
- Add HTTPS: Secure Apache with Let's Encrypt.
- Using Ubuntu or Debian instead? See Install Apache on Ubuntu and Debian.
