Skip to content

Instantly share code, notes, and snippets.

@ppizarror
Forked from kitloong/mac-homebrew-lamp.md
Last active June 12, 2025 01:50
Show Gist options
  • Save ppizarror/ec260247bd1c918ffcf5c9d3a267a9dd to your computer and use it in GitHub Desktop.
Save ppizarror/ec260247bd1c918ffcf5c9d3a267a9dd to your computer and use it in GitHub Desktop.
Mac - Install Apache, PHP, MySQL + phpMyAdmin with Homebrew

Install Homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

PHP

Install PHP
brew install [email protected]
brew install composer

To enable PHP in Apache add the following to (sudo vim /etc/apache2/httpd.conf) and restart Apache:

LoadModule php_module /opt/homebrew/opt/php/lib/httpd/modules/libphp.so

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

Finally, check DirectoryIndex includes index.php:

DirectoryIndex index.php index.html

The php.ini and php-fpm.ini file can be found in:

/opt/homebrew/etc/php/8.1/

To restart php after an upgrade:

brew services restart php

Or, if you don't want/need a background service you can just run:

/opt/homebrew/opt/php/sbin/php-fpm --nodaemonize

Finally, check version:

PHP 8.4.8 (cli) (built: Jun  3 2025 16:29:26) (NTS)
Copyright (c) The PHP Group
Built by Homebrew
Zend Engine v4.4.8, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.8, Copyright (c), by Zend Technologies
Update config

php -i | grep "additional .ini" Scan this dir for additional .ini files => /opt/homebrew/etc/php/8.4/conf.d

Instead of modify setting in default .ini file, /opt/homebrew/etc/php/8.4/php.ini, You should vi new .ini file to /opt/homebrew/etc/php/8.4/conf.d. Set following:

echo "memory_limit = 512M" > /opt/homebrew/etc/php/8.4/conf.d/memory-limit.ini
echo "session.gc_maxlifetime = 86400" > /opt/homebrew/etc/php/8.4/conf.d/session-lifetime.ini
echo "upload_max_filesize = 100M" > /opt/homebrew/etc/php/8.4/conf.d/uploads.ini
echo "post_max_size = 100M" >> /opt/homebrew/etc/php/8.4/conf.d/uploads.ini

Verify settings with:

php --ini
Configuration File (php.ini) Path: /opt/homebrew/etc/php/8.4
Loaded Configuration File:         /opt/homebrew/etc/php/8.4/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.4/conf.d
Additional .ini files parsed:      /opt/homebrew/etc/php/8.4/conf.d/ext-opcache.ini,
/opt/homebrew/etc/php/8.4/conf.d/memory-limit.ini

php -i | grep "memory_limit"               
memory_limit => 512M => 512M

Apache

Install Apache
brew install httpd

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.

To restart httpd after an upgrade:

brew services restart httpd

Or, if you don't want/need a background service you can just run:

/opt/homebrew/opt/httpd/bin/httpd -D FOREGROUND

Finally, check version:

httpd -v
Server version: Apache/2.4.62 (Unix)
Server built:   Apr 18 2025 22:52:07
Create httpd-php.conf

Insert following settings in /opt/homebrew/etc/httpd/extra/httpd-php.conf:

DirectoryIndex index.php index.html

<FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
Update Apache config

Update /opt/homebrew/etc/httpd/httpd.conf:

Listen 8080

# Enable following modules by uncomment
LoadModule proxy_module lib/httpd/modules/mod_proxy.so
LoadModule proxy_fcgi_module lib/httpd/modules/mod_proxy_fcgi.so
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so

# Append at the end of the conf
# Load php fcgi configuration
Include /opt/homebrew/etc/httpd/extra/httpd-php.conf

Then, restart:

brew services restart httpd

Finally, open http://localhost:8080 in browser to confirm it works.

MySQL

Install MySQL
brew install [email protected]

We've installed your MySQL database without a root password. To secure it run:

mysql_secure_installation

MySQL is configured to only allow connections from localhost by default. To connect run:

mysql -uroot

[email protected] is keg-only, which means it was not symlinked into /opt/homebrew, because this is an alternate version of another formula. If you need to have [email protected] first in your PATH, run:

echo 'export PATH="/opt/homebrew/opt/[email protected]/bin:$PATH"' >> ~/.zshrc

For compilers to find [email protected] you may need to set:

export LDFLAGS="-L/opt/homebrew/opt/[email protected]/lib"
export CPPFLAGS="-I/opt/homebrew/opt/[email protected]/include"

To restart [email protected] after an upgrade:

brew services restart [email protected]

Or, if you don't want/need a background service you can just run:

/opt/homebrew/opt/[email protected]/bin/mysqld_safe --datadir=/opt/homebrew/var/mysql

Then, link mysql to [email protected]

brew link [email protected] --force
brew services restart [email protected]

Finally, test version:

mysql -V
mysql  Ver 8.4.5 for macos15.2 on arm64 (Homebrew)

phpMyAdmin

Install phpMyAdmin
brew install phpmyadmin

Then, update config (vim /opt/homebrew/etc/phpmyadmin.config.inc.php):

# Extend cookies lifetime
$cfg['LoginCookieValidity'] = 86400;
$cfg['Servers'][$i]['AllowNoPassword'] = false; # optional
Create phpMyAdmin.conf
vim /opt/homebrew/etc/httpd/extra/phpmyadmin.conf

# Insert following
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>
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Allow from all
    </IfModule>
</Directory>

Then, save this to Apache (vim /opt/homebrew/etc/httpd/httpd.conf):

# Append at the end of the conf
# Load phpMyAdmin configuration
Include /opt/homebrew/etc/httpd/extra/phpmyadmin.conf

Restart httpd:

brew services restart httpd

Finally, validate:

curl -I http://localhost:8080/phpmyadmin
Multi Hosts
vim /opt/homebrew/etc/phpmyadmin/config.inc.php

# Add
$i++;
$cfg['Servers'][$i]['verbose'] = 'Server Name';
$cfg['Servers'][$i]['host'] = '128.0.0.2'; // New host
$cfg['Servers'][$i]['port'] = 3306;
$cfg['Servers'][$i]['socket'] = '';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['AllowNoPassword'] = false;
Prefix credential in config
vim /opt/homebrew/etc/phpmyadmin/config.inc.php

$cfg['Servers'][$i]['auth_type'] = 'config'; # Use config

$cfg['Servers'][$i]['user'] = 'username';
$cfg['Servers'][$i]['password'] = 'password';

Server script

#!/bin/bash

echo "========== Starting server =========="

# Start in a new process group so we can kill everything on Ctrl+C
set -m

# Function to stop all services
cleanup() {
  echo ""
  echo "[!] Caught exit signal. Stopping all services..."

  # Kill the entire process group
  kill -- -$$

  echo "[✓] All services terminated."
  exit 0
}

# Trap Ctrl+C (SIGINT) and SIGTERM
trap cleanup SIGINT SIGTERM

# Start Redis
echo "[+] Starting Redis..."
/opt/homebrew/opt/redis/bin/redis-server /opt/homebrew/etc/redis.conf &
sleep 1

# Start MySQL
echo "[+] Starting MySQL..."
/opt/homebrew/opt/[email protected]/bin/mysqld_safe --datadir=/opt/homebrew/var/mysql &
sleep 2

# Start Apache (httpd)
echo "[+] Starting Apache (httpd)..."
/opt/homebrew/opt/httpd/bin/httpd -f /opt/homebrew/etc/httpd/httpd.conf &
sleep 1

# Start PHP-FPM in the foreground — this keeps the script alive
echo "[+] Starting PHP-FPM (in foreground)..."
/opt/homebrew/opt/php/sbin/php-fpm --nodaemonize

# If PHP-FPM exits naturally, also clean up
cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment