Update 22 Oct 2019: Instructions updated for OSX 10.15 Catalina
After suffering some pretty bad issues with MAMP, I decided to set everything up with homebrew instead. The result was surprisingly a much faster and (in my opinion) easier to configure setup.
As a tl;dr, we’ll be setting up Homebrew MySQL and PHP and using OSX’s built in Apache.
In this tutorial I’m using the subl command which will open a file for editing in Sublime Text. If you don’t use Sublime Text, replace subl with nano or vi or any other app you use to edit text/config files.
Homebrew Setup
Homebrew is a package manager for OSX. It makes installation of a wide variety of useful apps super easy.
Installation instructions are on the homebrew homepage but you can also just run the following:
1 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" |
MySQL
I lied! We’re installing MariaDB instead! At the time of writing MySQL version 8.0.11 has just changed its default authentication method to caching_sha2_password which isn’t supported in PHP. It’s a huge hassle so we’ll just use the drop-in replacement MariaDB instead.
Install and configure MariaDB.
1 2 3 4 | # Install MariaDB brew install mariadb # Open my.cnf config file for editing subl /usr/local/etc/my.cnf |
Add the following to the end of the file to add support for large imports:
1 2 | max_allowed_packet = 2G innodb_file_per_table = 1 |
Make MySQL start when you log in:
1 | brew services start mariadb |
The default installation comes with a passwordless root user. So secure it with:
1 | mysql_secure_installation |
SSL
Like all developers I like working on a custom subdomain – in this case localhost.com. We need to create a self-signed wildcard SSL certificate and get Chrome accepting it.
Create a folder /Users/your_username/Sites/certs and inside it run the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # Generate a temporary OpenSSL config file cat > openssl.cnf <<-EOF [req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] CN = *.localhost.com [v3_req] keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = *.localhost.com DNS.2 = localhost.com EOF # Generate the certificates openssl req \ -new \ -newkey rsa:2048 \ -sha1 \ -days 3650 \ -nodes \ -x509 \ -keyout server.key \ -out server.crt \ -config openssl.cnf # Delete the temporary config file rm openssl.cnf |
This should have created two files – server.crt and server.key which will be used in the apache config below to get HTTPS up and running.
But first, because this certificate is self-signed, it’ll result in a This site’s security certificate is not trusted! error in Chrome. That can be fixed through adding the cert to OSX’s keychain app.
- open /Applications/Utilities/Keychain\ Access.app (In OSX 10.15 this was only visible in Finder and not Terminal for some reason)
- Under Keychains at the top left click System
- Click File – Import Items and select your server.crt file
- Now in the list find your newly added cert, double click it, expand the Trust section and set everything to Always Trust
- These changes will only take effect after a browser restart.
Apache and PHP
OSX 10.15 Catalina comes (at the time of writing) with Apache 2.4.41.
To configure apache (with SSL):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # Install PHP 7.3 brew install php@7.3 brew link --overwrite --force php@7.3 # Open httpd.conf for editing subl /etc/apache2/httpd.conf # Enable the PHP and SSL modules by removing the # at the start of the line LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so LoadModule ssl_module libexec/apache2/mod_ssl.so LoadModule php7_module /usr/local/opt/php@7.1/lib/httpd/modules/libphp7.so # A few extras I like to have enabled LoadModule deflate_module libexec/apache2/mod_deflate.so LoadModule expires_module libexec/apache2/mod_expires.so LoadModule headers_module libexec/apache2/mod_headers.so LoadModule rewrite_module libexec/apache2/mod_rewrite.so # Point the document root to a htdocs folder in your home directory and enable .htaccess # I've removed all the comments for succinctness but feel free to leave them in DocumentRoot "/Users/your_username/htdocs" <Directory "/Users/your_username/htdocs"> Options FollowSymLinks Multiviews MultiviewsMatch Any AllowOverride All Require all granted </Directory> # Add PHP to your default file list <IfModule dir_module> DirectoryIndex index.html index.php </IfModule> # And make it work <FilesMatch \.php |
gt;
SetHandler application/x-httpd-php
</FilesMatch>
# As with content, we want to load all site definitions from a Sites folder in our
# home directory. At the bottom replace the following:
# Include /private/etc/apache2/other/*.conf
IncludeOptional /Users/your_username/Sites/*.conf
# The error and custom logs too
CustomLog “/Users/your_username/Sites/logs/apache2/access_log” common
ErrorLog “/Users/your_username/Sites/logs/apache2/error_log”
# Uncomment to load the SSL config
Include /private/etc/apache2/extra/httpd-ssl.conf
Now configure the default SSL options:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Open httpd.conf for editing subl /etc/apache2/extra/httpd-ssl.conf # Point to our same document root as before DocumentRoot "/Users/your_username/htdocs" # Update log file locations ErrorLog "/Users/your_username/Sites/logs/apache2/error_log" TransferLog "/Users/your_username/Sites/logs/apache2/access_log" CustomLog "/Users/your_username/Sites/logs/apache2/ssl_request_log" \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" # Point to the certs we created SSLCertificateFile "/Users/your_username/Sites/certs/server.crt" SSLCertificateKeyFile "/Users/your_username/Sites/certs/server.key" |
Since this is a development machine, you’ll probably also want to enable the ever popular xdebug which luckily for us comes pre-compiled with OSX. What OSX doesn’t come with, however, is a default php.ini though it does have a sample file. We can use that:
1 | sudo cp /etc/php.ini.default /etc/php.ini |
Then simply add extension=xdebug.so below all the extension= lines in your new /etc/php.ini file.
VirtualHosts
I like to split virtualhosts up into one for each site and store them all in /Users/your_username/Sites/ folder.
Create a file /Users/your_username/Sites/mysite.localhost.com.conf and add the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <VirtualHost *:80> ServerAdmin webmaster@localhost ServerName mysite.localhost.com ServerAlias mysite.localhost.com DocumentRoot /Users/your_username/htdocs/mysite.com ErrorLog /Users/your_username/Sites/logs/mysite.com.error.log LogLevel warn CustomLog /Users/your_username/Sites/logs/mysite.com.access.log varnishcombined <Directory /Users/your_username/htdocs/mysite.com/> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> <IfModule ssl_module> <VirtualHost *:443> ServerAdmin webmaster@localhost ServerName mysite.localhost.com ServerAlias mysite.localhost.com DocumentRoot /Users/your_username/htdocs/mysite.com ErrorLog /Users/your_username/Sites/logs/mysite.com.error.log LogLevel warn CustomLog /Users/your_username/Sites/logs/mysite.com.access.log varnishcombined <Directory /Users/flynsarmy/htdocs/work/qpsmedia/qpsstats/> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> SSLEngine on SSLCertificateFile /Users/your_username/Sites/certs/server.crt SSLCertificateKeyFile /Users/your_username/Sites/certs/server.key <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> </VirtualHost> </IfModule> |
Finally, restart apache and you should be good to go!
1 | sudo apachectl restart |
Resources
- Much of the content of this article came from David Marcus’s really great post Set up localhost on macOS High Sierra (Apache, MySQL, and PHP 7) with SSL/HTTPS.
- To get SSL certs working correctly in the browser I followed the instructions on Jed Schmidt’s gist How to set up stress-free SSL on an OS X development machine.
- Because I’m positive I’ve missed or incorrectly written at least some of this article I’ve uploaded copies of all relevant files. httpd.conf httpd-ssl.conf mysite.localhost.com.conf