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 imagemagick php pkg-config wp-cli mariadb go mailhog phpmyadmin redis;
pecl install imagick redis;
go install github.com/mailhog/mhsendmail@latest;
brew services start httpd php mailbag redis;
Setup and tune the database service
brew services start mariadb;
sudo mysqladmin password root;
Edit /usr/local/etc/my.cnf with the following additions:
[mysqld]
innodb_buffer_pool_size = 1024M
Tune PHP and PHP-FPM service
Edit /usr/local/etc/php/8.2/php.ini with the following changes:
max_execution_time = 300
memory_limit = 512M
post_max_size = 100M
upload_max_filesize = 100M
sendmail_path = /Users/<mac-user>/go/bin/mhsendmail
Edit /usr/local/etc/php/8.2/php-fpm.d/www.conf with the following changes:
user = [username]
group = admin
listen = /usr/local/var/run/php-fpm.sock
pm = ondemand
pm.max_children = 40
Setup Apache web service
Edit /usr/local/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:/usr/local/var/run/php-fpm.sock|fcgi://localhost"
</FilesMatch>
</IfModule>
Alias /phpmyadmin /usr/local/share/phpmyadmin
<Directory /usr/local/share/phpmyadmin/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from all
</IfModule>
</Directory>
Setup a self-signed SSL certificate
openssl req -x509 -newkey rsa:4096 \
-sha256 -days 3650 -nodes \
-keyout /usr/local/etc/httpd/server.key \
-out /usr/local/etc/httpd/server.crt \
-subj "/CN=localhost";
Edit /usr/local/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 /usr/local/var/www/ without the sub-folder.
Add the file /usr/local/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]
</IfModule>
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 /usr/local/var/www/wp-config.php with the following changes
<?php
// Set Site
$site = 'sandbox';
$table_prefix = 'wp_';
// Set WP Content Folder By Site
define( 'WP_CONTENT_FOLDERNAME', $site );
define( 'WP_CONTENT_DIR', ABSPATH . WP_CONTENT_FOLDERNAME );
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 MailHog https://localhost:8025/
- Access PhpMyAdmin https://localhost/phpmyadmin/
- Switch sites using the command: wp config set site [sitename]