Eventhough Apache ships with macOS, a better maintained version would be coming from Homebrew, also Apple is making noises about not supporting legacy software like PHP so in the future this may be more of a compulsory option.
macOS use to ship with both MySQL & PHP, but now since macOS Monterey, PHP has also been deprecated.
In this guide we look to add both MySQL and PHP and structure the workflow to use the User Sites folder as the document root. For MySQL/MariaDB you can either also install from Homebrew or as a standalone package.
First thing to do would be to remove the builtin Apache version of which in macOS Monterey Big Sur is Apache/2.4.46. or 2.4.48
Remove built-in Apache in macOS
You can test if Apache is running by issuing this command, which is checking Port 80:
sudo lsof -i:80
Output you may get back would be:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 107 root 4u IPv6 0xe356c4f54c26d40f 0t0 TCP *:http (LISTEN) httpd 395 _www 4u IPv6 0xe356c4f54c26d40f 0t0 TCP *:http (LISTEN)
This tells us that indeed httpd/Apache is running, no output would mean it’s not running.
Stop Apache running on computer restart by issuing:
sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
That will unload the start up daemon and make the builtin macOS Apache incapacitated, test by issuing the previous command:
sudo lsof -i:80
Installing Apache with Homebrew
First make sure you have Homebrew set up and ready to go.
Install Apache which is known as the package name ‘httpd’:
brew install httpd
Final command line output should be:
DocumentRoot is /usr/local/var/www. The default ports have been set in /usr/local/etc/httpd/httpd.conf to 8080 and in /usr/local/etc/httpd/extra/httpd-ssl.conf to 8443 so that httpd can run without sudo. To have launchd start httpd now and restart at login: brew services start httpd Or, if you don't want/need a background service you can just run: apachectl start ==> Summary ???? /usr/local/Cellar/httpd/2.4.46_2: 1,657 files, 31.4MB
Set Apache to auto-start now and on computer restart:
brew services start httpd
The other 2 commands to stop or Restart Apache are:
brew services stop httpd brew services restart httpd
By default the Apache Homebrew package is listening on Port 8080 and 8443, test by issuing:
sudo lsof -i:8080
Test the location of Apache/httpd
which httpd
Homebrew location is:
/usr/local/bin/httpd
If you are getting the default macOS location of /usr/sbin/httpd:
/usr/sbin/httpd
Restart the computer and try the location test again.
Changing the Port Number
Next is to change the port numbers from 8080 to 80
nano /usr/local/etc/httpd/httpd.conf
And change Listen 8080 to:
Listen 80
Restart Apache and web files will now be served over the default port 80.
brew services restart httpd
Changing the document root to be the old sites folder
Previously in macOS the web root directory which is missing by default is the ‘~/Sites’ folder in the User account. This makes sense to set up as a document root as it is logical and easily accessible.
You need to make a “Sites” folder at the root level of your account and then it will work. Once you make the Sites folder you will notice that it has a unique icon which is a throwback from a few versions older. Make that folder before you set up the configuration changes below
In the /usr/local/etc/httpd/httpd.conf file, find:
DocumentRoot "/usr/local/var/www"
Change to:
DocumentRoot /Users/shortusername/Sites
Change the shortusername to the one on your macOS account
Find:
<Directory "/usr/local/var/www"">
Change to:
<Directory "/Users/shortusername/Sites">
Find:
# # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: # AllowOverride FileInfo AuthConfig Limit # AllowOverride None
Change to:
# # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: # AllowOverride FileInfo AuthConfig Limit # AllowOverride All
Find:
User _www Group _www
Change:
User shortusername Group staff
Find:
#ServerName www.example.com:8080
Change:
ServerName localhost
Find and uncomment:
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so
Now the webroot is /Users/shortusername/Sites/ just add a index.html file there and view file via localhost/index.html in your browser
Apache Log File
To check any Apache errors or access you can find its log files:
/usr/local/var/log/httpd/error_log /usr/local/var/log/httpd/access_log
Getting PHP Working
Follow this Homebrew PHP guide to download your required PHP versions.
In the /usr/local/etc/httpd/httpd.conf file add in required module – example uses PHP 8.
LoadModule php_module /usr/local/opt/[email protected]/lib/httpd/modules/libphp.so
Find:
<IfModule dir_module> DirectoryIndex index.html </IfModule>
Change:
<IfModule dir_module> DirectoryIndex index.php index.html </IfModule>
Also at the end of the file add in:
<FilesMatch .php> SetHandler application/x-httpd-php </FilesMatch>
Restart Apache:
brew services restart httpd
You can check PHP is running by adding <?php phpinfo(); ?>
to a .php web hosted file and view the output.
That’s it, Apache is now set up and running with PHP enabled.
To remove Apache httpd
brew remove httpd
10 comments
ErikBw
After upgrading to Ventura I can only reach my Apache webserver from the server itself (ie not even on the same LAN from a different computer, let alone externally).
lsof shows httpd is listening to 8080 and 443. Opening php-info.php responds as expected when called from a browser on the server.
I already turned of the Apple firewall but it doesn’t help. The httpd access log only shows activity when a call from a browser on the server is made. No ‘strange’ error messages in the error log either.
What can I do to pinpoint the issue?
This used to work fine on my LAN and WAN (running dokuwiki).
Todd Ferguson
ATTENTION THERE IS ONE MISTAKE YOU MUST CORRECT:
The last thing he says to add should be:
SetHandler application/x-httpd-php
He accidentally formatted the closing > wrong which turned into the
gt; SetHandler….
Neil Gowran
Thanks – updated
jei-em
Thank you for the detailed instructions and I have it working with your help =)… however, i’ve got “404 error The requested URL was not found on this server” particularly for the subdirectories…
Simon KRAMER
Hi,
I’m getting different output (with different paths):
==
DocumentRoot is /opt/homebrew/var/www.
The default ports have been set in /opt/homebrew/etc/httpd/httpd.conf to 8080 and in
/opt/homebrew/etc/httpd/extra/httpd-ssl.conf to 8443 so that httpd can run without sudo.
==
Best,
Simon
James
everything is running but the page is not showing up
not sure why
X
You have an error in your HTML – you can see it in your PHP section after
Also at the end of the file add in
I tried guessing what the code actually was, but then I didn’t have the proper format, which temporarily broke my whole setup. Then I saw that, after the greater than sign, line breaks were also necessary, and now it’s working fine ;)
Given most of us might be idiots like myself, just thought maybe you might want to edit it? I literally just copy and paste what gurus like yourself provide ;)
And please obviously delete all of my stupid comments.
Thanks again for such an AWESOME resource! Worked like a charm!
X
I apologize – please ignore/delete my comment. I somehow missed the step to rewrite:
Once I fixed that, all is golden. Thanks VERY much for the awesome resource!
Dennis Nolan
Having trouble with php.
New iMac so is a virgin configuration.
All well until I add the following to the httpd.conf file
LoadModule php_module /usr/local/opt/[email protected]/lib/httpd/modules/libphp.so
I am getting
crbug/1173575, non-JS module files deprecated.
(anonymous) @ VM413:6774
This is in Google Chrome
In Safari: None of the js files are loaded and the console message for each js file is:
Failed to load resource: Could not connect to the server
Any help would be appreciated.
Patrick Leevers
The clearest, most effective tutorial of its kind I’ve ever seen! This put me back on track after failing to sort out a bungled previous encounter with httpd.