Apache 2
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/