We are using MySQL 5.7 in our development environment. This is the version that is included in All-Inkl hosting and in many other managed hosting packages.
- Install and link brew package
brew install mysql@5.7
brew link --force mysql@5.7
- Start MySQL service
brew services start mysql@5.7
- Configure MySQL
$(brew --prefix)/opt/mysql@5.7/bin/mysql_secure_installation
- Do NOT install the VALIDATE PASSWORD plugin (just hit enter)
- New password should be
root
- Remove anonymous users (hit
y
and enter) - Disallow root login remotely (hit
y
and enter) - Remove test database and access to it (hit
y
and enter) - Reload privilege tables now (hit
y
and enter)
We are using PHP-FPM. By default we only install those ones supported by core homebrew. These are 7.4 and 8.0 at the moment. 7.3 does not have a bottle for arm64 (M1/Silicon).
Each PHP-FPM service runs on its own port, so we can run them all simultaneously. The port numbers are 9074, 9080, for the respective PHP version.
The process manager is on demand, so that we only use system resources, if request are coming in.
We also install the additional imagemagick module to get better image performance in WordPress.
-
Install all PHP version and ImageMagick
brew install php php@7.4 imagemagick
-
Edit the
www.conf
files of all PHP versions in$(brew --prefix)/etc/php/X.Y/php-fpm.d/www.conf
to includelisten = 127.0.0.1:90XY pm = ondemand pm.max_children = 15
-
Install the imagick module for all 7.4 (prefix can be autodetected). For 8.0 there are compilation errors and an open ticket on GitHub
$(brew --prefix)/opt/php@7.4/bin/pecl install imagick
Instead of sharing real certificates for our local development enironments, we now use a tool called mkcert
to trust self-signed certificates system-wide.
-
Install package
brew install mkcert nss
-
Install local certificate authority
mkcert -install
-
Generate development certificate
mkdir ~/certs cd ~/certs mkcert -key-file local.blee.ch_key.pem -cert-file local.blee.ch_cert.pem local.blee.ch "*.local.blee.ch" "*.dfp-dfa-website.local.blee.ch" "*.ebay-kleinanzeigen.local.blee.ch" "*.mitvergnuegen-website.local.blee.ch" localhost 127.0.0.1 ::1
Apache runs on port 8080 and 8443. This way we do not need admin rights (sudo) in order to restart the server. We later use port forwarding to route traffic from 80 to 8080 and 443 to 8443.
We also use the MPM Event module for better performance and a couple of other necessary modules.
With the new Macs, we also change the setup a bit so that we can create new virtual hosts easier, and that we set the used PHP version inside of the .htaccess
of the projects.
To set everything up, do the following:
-
Install package
brew install httpd
-
Create the file
$(brew --prefix)/etc/httpd/extra/h5bp-performance.conf
with the following content# ###################################################################### # # WEB PERFORMANCE # # ###################################################################### # ---------------------------------------------------------------------- # | Compression | # ---------------------------------------------------------------------- <IfModule mod_deflate.c> # Force compression for mangled `Accept-Encoding` request headers # https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html <IfModule mod_setenvif.c> <IfModule mod_headers.c> SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding </IfModule> </IfModule> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Compress all output labeled with one of the following media types. # # (!) For Apache versions below version 2.3.7 you don't need to # enable `mod_filter` and can remove the `<IfModule mod_filter.c>` # and `</IfModule>` lines as `AddOutputFilterByType` is still in # the core directives. # # https://httpd.apache.org/docs/current/mod/mod_filter.html#addoutputfilterbytype <IfModule mod_filter.c> AddOutputFilterByType DEFLATE "application/atom+xml" \ "application/javascript" \ "application/json" \ "application/ld+json" \ "application/manifest+json" \ "application/rdf+xml" \ "application/rss+xml" \ "application/schema+json" \ "application/vnd.geo+json" \ "application/vnd.ms-fontobject" \ "application/x-font-ttf" \ "application/x-javascript" \ "application/x-web-app-manifest+json" \ "application/xhtml+xml" \ "application/xml" \ "font/eot" \ "font/opentype" \ "image/bmp" \ "image/svg+xml" \ "image/vnd.microsoft.icon" \ "image/x-icon" \ "text/cache-manifest" \ "text/css" \ "text/html" \ "text/javascript" \ "text/plain" \ "text/vcard" \ "text/vnd.rim.location.xloc" \ "text/vtt" \ "text/x-component" \ "text/x-cross-domain-policy" \ "text/xml" </IfModule> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Map the following filename extensions to the specified # encoding type in order to make Apache serve the file types # with the appropriate `Content-Encoding` response header # (do note that this will NOT make Apache compress them!). # # If these files types would be served without an appropriate # `Content-Enable` response header, client applications (e.g.: # browsers) wouldn't know that they first need to uncompress # the response, and thus, wouldn't be able to understand the # content. # # https://httpd.apache.org/docs/current/mod/mod_mime.html#addencoding <IfModule mod_mime.c> AddEncoding gzip svgz </IfModule> </IfModule>
-
Change the following settings in
$(brew --prefix)/etc/httpd/httpd.conf
-
Enable (uncomment) the following modules:
mpm_event_module socache_shmcb_module deflate_module expires_module proxy_module proxy_fcgi_module ssl_module http2_module vhost_alias_module rewrite_module
-
Disable (comment out) the following modules:
mpm_worker_module mpm_prefork_module
-
Add / adjust the following settings, if you do not find a directive (like
Protocols
), add it to a new line.DirectoryIndex index.php index.html ServerName localhost Protocols h2 http/1.1
-
Enable (uncomment) the include statements for the following config files
httpd-mpm.conf httpd-ssl.conf
-
Add the following includes to the bottom of the file (replace
$BREW_PATH
with the output ofbrew --prefix
)Include $BREW_PATH/etc/httpd/extra/h5bp-performance.conf
-
Add the global certificates (replace $HOME with your home directory)
SSLProtocol -all +TLSv1.2 +TLSv1.3 SSLHonorCipherOrder Off SSLCipherSuite ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM SSLCipherSuite TLSv1.3 TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256 SSLCertificateFile $HOME/certs/local.blee.ch_cert.pem SSLCertificateKeyFile $HOME/certs/local.blee.ch_key.pem
-
Add the following magic virtualhost with default PHP version of 7.4 (replace
$BREW_PATH
with the output ofbrew --prefix
)<Virtualhost *:8443> SSLEngine On AddHandler proxy:fcgi://127.0.0.1:9074 .php VirtualDocumentRoot "$BREW_PATH/var/www/%1" ServerName local.blee.ch ServerAlias *.local.blee.ch UseCanonicalName Off <Directory "$BREW_PATH/var/www/*"> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> </Virtualhost>
-
Add default rewrite settings with a redirect from
http
tohttps
for all requests<IfModule mod_rewrite.c> RewriteEngine On RewriteOptions Inherit RewriteCond %{HTTPS} !=on RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L] </IfModule>
-
-
Remove the entire
<Virtualhost ...>
directive from$(brew --prefix)/etc/httpd/extra/httpd-ssl.conf
.
We do portwarding from 80 to 8080 and 443 to 8443 so that apache can be run and restarted without admin right.
For this we have to create a launch daemon and run it as root on boot. You usually do not have to worry about it anymore.
-
Create the file
/Library/LaunchDaemons/local.bleech.httpdfwd.plist
with the following content (trysudo touch /Library/LaunchDaemons/local.bleech.httpdfwd.plist
before editing with vs-code):<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>local.bleech.httpdfwd</string> <key>ProgramArguments</key> <array> <string>sh</string> <string>-c</string> <string>echo "rdr pass proto tcp from any to any port {80,8080} -> 127.0.0.1 port 8080" | pfctl -a "com.apple/260.HttpFwdFirewall" -Ef - && echo "rdr pass proto tcp from any to any port {443,8443} -> 127.0.0.1 port 8443" | pfctl -a "com.apple/261.HttpFwdFirewall" -Ef - && sysctl -w net.inet.ip.forwarding=1</string> </array> <key>RunAtLoad</key> <true/> <key>UserName</key> <string>root</string> </dict> </plist>
-
Load the daemon
sudo launchctl load -Fw /Library/LaunchDaemons/local.bleech.httpdfwd.plist
Dnsmasq automatically routes all request to a given domain, in our case local.blee.ch
to a specific IP. This way we do not have to add entries for the virtualhosts to /etc/hosts
.
-
Install package
brew install dnsmasq
-
Change
$(brew --prefix)/etc/dnsmasq.conf
to includeaddress=/.local.blee.ch/127.0.0.1 listen-address=127.0.0.1 port=35353
-
Create the file (and directory)
/etc/resolver/local.blee.ch
with the following contentnameserver 127.0.0.1 port 35353
In order to control the tools we just set up, we use brew services
. The most relevant subcommands are list|start|stop|restart
. Started services will be automatically launched at boot / login.
Here are some helpfull commands (run all of these now, in order to get all services started)
# show all services with status
brew services list
# restart apache, eg. after config change
brew services restart httpd
# restart fpm process for PHP 7.4
brew services restart php@7.4
# restart fpm process for PHP 8.0
brew services restart php@8.0
# restart mysql server
brew services restart mysql@5.7
# restart dnsmasq
brew services restart dnsmasq
If you do not need specific services or versions of PHP, you can also stop them via brew services stop php@8.0
, for example.
Unfortunately the service for PHP-FPM 8.0, sometimes shows an error, although it is running. If you see a red error status when doing brew services list
do the following:
- Open the
.plist
file next to the PHP service. - Copy the executed command to the command line (it should be something like
/opt/homebrew/opt/php/sbin/php-fpm --nodaemonize
). - Run
brew services stop php@8.0
- Execute the command you copied from the
.plist
, for example/opt/homebrew/opt/php/sbin/php-fpm --nodaemonize
. - If this does not return an error, the service should be running just fine. Hit
control + c
, and runbrew services start php@8.0
, again.
In order to create a virtualhost, you can create a symlink to the docroot with the project name in $(brew --prefix)/var/www
. It will be serverd with the default PHP version. For example
ln -nfs ~/www/bleech-website/wordpress $(brew --prefix)/var/www/bleech-website
As a best practise, always add the used PHP version to the .htaccess
of each project. Like
AddHandler proxy:fcgi://127.0.0.1:9080 .php
Install the following packages
brew install nave composer wp-cli