Apache 2

https://httpd.apache.org/

Install

apache2 is pre-installed on macOS Monterey as httpd.

Check the version:

$ httpd -v
Server version: Apache/2.4.56 (Unix)
Server built:   Aug 17 2023 06:34:44

Start/stop the server:

$ sudo apachectl start
$ sudo apachectl stop

Restart the server:

$ sudo apachectl -k restart

Check the config file:

$ apachectl configtest

Make it start at boot:

$ sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
$ sudo apt install apache2
$ sudo apache2 -v
Server version: Apache/2.4.65 (Debian)
Server built:   2025-07-29T20:18:46
$ systemctl status apache2
● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; preset: enabled)
     Active: active (running) since Tue 2025-12-23 03:42:21 CST; 31s ago
       Docs: https://httpd.apache.org/docs/2.4/
   Main PID: 1500 (apache2)
      Tasks: 55 (limit: 2236)
     Memory: 11.1M
        CPU: 135ms
     CGroup: /system.slice/apache2.service
             ├─1500 /usr/sbin/apache2 -k start
             ├─1501 /usr/sbin/apache2 -k start
             └─1502 /usr/sbin/apache2 -k start

Enable modules:

$ sudo a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
  systemctl restart apache2

Enable php

On macOS after Monterey, you need to install php mannually for it is deprecated.

Code signing is required on new macOS versions, so a certificate authority (CA) is needed to sign the php library. See How to create Certificate Authority for Code Signing in macOS to create a CA.

Tip

Certificates are stored in ~/Library/Application Support/Certificate Authority/.

Then sign the php lib (for Homebrew installed php on macOS Monterey):

$ codesign --sign 'XXXX' --force --keychain ~/Library/Keychains/login.keychain-db /usr/local/opt/php/lib/httpd/modules/libphp.so

Check the signature:

$ codesign -dv --verbose=4 /usr/local/opt/php/lib/httpd/modules/libphp.so 2>&1 | grep Authority=
Authority=XXXX's CA

On macOS Tahoe, the Homebrew installed packages are located in /opt/homebrew, so:

$ codesign --sign 'XXXX' --force --keychain ~/Library/Keychains/login.keychain-db /opt/homebrew/opt/php/lib/httpd/modules/libphp.so
/opt/homebrew/opt/php/lib/httpd/modules/libphp.so: replacing existing signature
$ codesign -dv --verbose=4 /opt/homebrew/opt/php/lib/httpd/modules/libphp.so 2>&1 | grep Authority=
Authority=XXXX's CA

Edit file /etc/apache2/mime.types to add php MIME types:

 video/x-sgi-movie				movie
 video/x-smv					smv
 x-conference/x-cooltalk				ice
+application/x-httpd-php                         php
+application/x-httpd-php-source                  phps

Edit apache config file /etc/apache2/httpd.conf:

 #LoadModule imagemap_module libexec/apache2/mod_imagemap.so
 #LoadModule actions_module libexec/apache2/mod_actions.so
 #LoadModule speling_module libexec/apache2/mod_speling.so
-#LoadModule userdir_module libexec/apache2/mod_userdir.so
+LoadModule userdir_module libexec/apache2/mod_userdir.so
 LoadModule alias_module libexec/apache2/mod_alias.so
-#LoadModule rewrite_module libexec/apache2/mod_rewrite.so
+LoadModule rewrite_module libexec/apache2/mod_rewrite.so
 #PHP was deprecated in macOS 11 and removed from macOS 12
+LoadModule php_module /usr/local/opt/php/lib/httpd/modules/libphp.so "XXXX's CA"
 #LoadModule perl_module libexec/apache2/mod_perl.so
 LoadModule hfs_apple_module libexec/apache2/mod_hfs_apple.so
 
 #
 # If your host doesn't have a registered DNS name, enter its IP address here.
 #
-#ServerName www.example.com:80
+ServerName localhost:80
 
 #
 # Deny access to the entirety of your server's filesystem. You must
 #Include /private/etc/apache2/extra/httpd-languages.conf
 
 # User home directories
-#Include /private/etc/apache2/extra/httpd-userdir.conf
+Include /private/etc/apache2/extra/httpd-userdir.conf
 
 # Real-time info on requests and configuration
 #Include /private/etc/apache2/extra/httpd-info.conf

Note

CA Name is appended to the LoadModule line for php.

Enable user directory access

Edit apache config file /etc/apache2/extra/httpd-userdir.conf:

 # Control access to UserDir directories.  The following is an example
 # for a site where these directories are restricted to read-only.
 #
-#Include /private/etc/apache2/users/*.conf
+Include /private/etc/apache2/users/*.conf
 <IfModule bonjour_module>
        RegisterUserSite customized-users
 </IfModule>

Create config file /etc/apache2/users/xxxx.conf for user xxxx:

<Directory "/Users/xxxx/Sites">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require host localhost
    Require ip 127
</Directory>

Create web root directory for user xxxx:

$ mkdir /Users/xxxx/Sites

Add user _www to staff group to allow apache to access the user’s web root directory:

$ sudo dseditgroup -o edit -t user -a _www staff
$ dseditgroup -o read staff

Warning

This is dangerous if you want to expose your web root directory to the public.

See this URL:

open http://localhost/~xxxx/