Local WordPress development via Homebrew

Mac laptop with code editor in view

Here’s a follow-up to my March 2022 article on LocalWP power usage. LocalWP has gotten too slow and eats-up loads of precious storage space. Some sites won’t shut down. The ones that do shut down take time to save backups each time. Starting up sites takes much longer than it used to. It’s become a pain!

I’ve used lots of different local hosting environments over the years. I describe some of those in the above article and also in my 2020 local development update article as well.

Enter Homebrew package manager for macOS. Homebrew, or your package manager of choice for your operating system, can be used to install and maintain a high efficiency local hosting environment.

Here’s technical details describing how to set this up:

Install LAMP services

brew install httpd [email protected] wp-cli mariadb phpmyadmin;
brew unlink php;
brew link [email protected];
brew services start httpd;
brew services start [email protected];

Setup and tune the database service

brew services start mariadb;
sudo mysqladmin password root;

Edit /opt/homebrew/etc/my.cnf with the following additions:

innodb_buffer_pool_size = 128M

Tune PHP and PHP-FPM service

Edit /opt/homebrew/etc/php/8.2/php.ini with the following changes:

max_execution_time = 30
memory_limit = 256M
post_max_size = 64M
upload_max_filesize = 64M

Edit /opt/homebrew/etc/php/8.2/php-fpm.d/www.conf with the following changes:

user = [username]
group = admin
listen = /opt/homebrew/var/run/php-fpm.sock
pm = ondemand
pm.max_children = 151

Setup Apache web service

Edit /opt/homebrew/etc/httpd/httpd.conf with the following changes:

  • Listen 80
  • User [username]
  • Group admin
  • Uncomment / load modules (towards the top):
    • socache_shmcb_module
    • proxy_module
    • proxy_fcgi_module
    • ssl_module
    • rewrite_module
  • Uncomment / include config files (towards the bottom):
    • /usr/local/etc/httpd/extra/httpd-mpm.conf
    • /usr/local/etc/httpd/extra/httpd-ssl.conf
  • DirectoryIndex index.php index.html (adding index.php)
  • Under under Directory /usr/local/var/www
    • AllowOverride All
    • Add the following sections for PHP and PhpMyAdmin:
<IfModule proxy_fcgi_module>
    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/opt/homebrew/var/run/php-fpm.sock|fcgi://localhost"

Alias /phpmyadmin /opt/homebrew/share/phpmyadmin
<Directory /opt/homebrew/share/phpmyadmin/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    <IfModule mod_authz_core.c>
        Require all granted
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Allow from all

Setup a self-signed SSL certificate

openssl req -x509 -newkey rsa:4096 \
  -sha256 -days 3650 -nodes \
  -keyout /opt/homebrew/etc/httpd/server.key \
  -out /opt/homebrew/etc/httpd/server.crt \
  -subj "/CN=localhost";

Edit /opt/homebrew/etc/httpd/extra/httpd-ssl.conf with the following changes:

  • Listen 443
  • <VirtualHost _default_:443>
  • ServerName localhost:443

Restart all services

brew services restart --all;
brew services list;

Install and configure WordPress

Download WordPress and unzip it into /opt/homebrew/var/www/ without the sub-folder.

Add the file /opt/homebrew/var/www/.htaccess containing the following:

<IfModule mod_rewrite.c>

RewriteEngine On

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# When Images Not Found, Load From Production
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^client1/uploads/(.+)\.(jpe?g|png|gif|svg|woff2)$ https://client1.com/wp-content/uploads/$1.$2 [R=302,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]


Optionally use the RewriteRule to pull client site images from production.

Be sure to back this file up because some greedy plugins will overwrite it from time to time.

Edit /opt/homebrew/var/www/wp-config.php with the following changes


// Set Site
$site = 'sandbox';
$table_prefix = 'wp_';

// Set WP Content Folder By Site
define( 'WP_CONTENT_FOLDERNAME', $site );
define( 'WP_CONTENT_URL', 'https://localhost/' . WP_CONTENT_FOLDERNAME );

// DB Connection
define( 'DB_NAME', $site );
define( 'DB_USER', 'root' );
define( 'DB_PASSWORD', 'root' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

// Paste Random Salt Definitions Here

// Debug Mode?
define( 'WP_DEBUG', false );

// Required Settings
if ( ! defined( 'ABSPATH' ) ) {
        define( 'ABSPATH', __DIR__ . '/' );
require_once ABSPATH . 'wp-settings.php';

Rename the wp-content folder to sandbox if you need a multi environment installation.

Importing your sites

Import other sites wp-content contents into their own named folders within the web root. I recommend naming the site content folders and database the same for switching convenience.

Access PhpMyAdmin from the URL https://localhost/phpmyadmin and default DB credentials root / root to add databases for each of your sites and import them accordingly. Use the command wp search-replace “https://client1.com” “https://localhost” –all-tables to update the URLs and remember to run variations of http://, https://, with and without www.

  • Access the site https://localhost/
  • Access PhpMyAdmin https://localhost/phpmyadmin/
  • Switch sites using the command: wp config set site [sitename]

Share this:

Note: I may receive compensation for referrals.

WP Engine - A smarter way to WordPress
The best email marketing tool, responsive templates, automations, Worldwide support, tracking and reports, Benchmark Email, free plan available
Sell everywhere. Use Shopify to sell in-store and online.
Klaviyo partner badge
Okendo Partner, certified
WooCommerce, the most customizable eCommerce platform for building your online business. Click to get started.
Jetpack, a stronger, customizable site without sacrificing safety. Click to get started.