Provisioning a local Apache, MySQL, and PHP development stack on macOS with MacPorts isolates all compiled binaries, headers, configuration files, and launchd plists cleanly inside the /opt/local prefix. Unlike modifying system-supplied macOS frameworks—which are overwritten during operating system upgrades—a MacPorts environment supports side-by-side PHP versions, custom compile variants, and deterministic launchd daemon management.
1. Installing MacPorts and Configuring Shell Paths
Before installing MacPorts, ensure the Xcode Command Line Tools are installed (xcode-select --install) and the Xcode license has been accepted. After installing the official MacPorts package for your macOS release (or building from source), prepend /opt/local/bin and /opt/local/sbin to your shell PATH in ~/.zshrc or ~/.profile:
# Add MacPorts binary directories to your shell profile
export PATH="/opt/local/bin:/opt/local/sbin:$PATH"
export MANPATH="/opt/local/share/man:$MANPATH"
# Synchronize the port tree and upgrade base MacPorts
sudo /opt/local/bin/port -v selfupdate
Running port selfupdate synchronizes the local port definitions tree and compiles any newer release of the MacPorts base infrastructure.
2. Compiling cURL with TLS/SSL and Provisioning MySQL
First, verify that the MacPorts curl binary is built with TLS/SSL support enabled so that PHP extensions and package managers like Composer can negotiate HTTPS connections:
sudo port install curl +ssl
Installing and Initializing the MySQL Server
When installing MySQL via MacPorts, always install the -server port (such as mysql8-server for modern stacks or mysql5-server when maintaining legacy databases) so that MacPorts generates the corresponding launchd startup wrapper:
# Install the MySQL server port and register its launchd daemon
sudo port install mysql5-server
sudo port load mysql5-server
# Initialize the system tables under the dedicated _mysql user
sudo -u _mysql mysql_install_db5
Aligning the Unix Domain Socket (mysql.sock)
By default, many CLI tools look for the local MySQL socket at /tmp/mysql.sock, whereas MacPorts places its runtime socket inside /opt/local/var/run/mysql5/mysqld.sock. Configure /opt/local/etc/mysql5/my.cnf and create a symbolic link so both paths resolve cleanly:
[mysqld_safe]
socket = /tmp/mysql.sock
[client]
socket = /tmp/mysql.sock
sudo ln -sf /tmp/mysql.sock /opt/local/var/run/mysql5/mysqld.sock
3. Installing Apache (apache2) and PHP with MySQL Native Driver
MacPorts allows compiling PHP alongside the Apache handler module, PEAR, FastCGI/FPM, and the MySQL Native Driver (+mysqlnd):
# Install PHP with Apache2 module, FastCGI, and MySQL native driver variants
sudo port install php5 +apache2 +pear +fastcgi php5-mysql +mysqlnd
# Install common cryptographic, image processing, and debugging extensions
sudo port install php5-openssl php5-curl php5-gd php5-iconv php5-http php5-mcrypt php5-xdebug
# Register Apache 2 to start automatically via launchd
sudo port load apache2
Configuring php.ini
Copy the template configuration file inside /opt/local/etc/php5/ and set an explicit date.timezone and error-reporting level:
cd /opt/local/etc/php5/
sudo cp php.ini-development php.ini
; /opt/local/etc/php5/php.ini
date.timezone = America/Los_Angeles
display_errors = On
error_reporting = E_ALL
pdo_mysql.default_socket = /tmp/mysql.sock
mysqli.default_socket = /tmp/mysql.sock
4. Registering the PHP Module and Virtual Hosts in Apache
Use the Apache Extension Tool (apxs) to register libphp5.so inside /opt/local/apache2/conf/httpd.conf:
cd /opt/local/apache2/modules
sudo /opt/local/apache2/bin/apxs -a -e -n "php5" libphp5.so
Next, update /opt/local/apache2/conf/httpd.conf so Apache serves index.php directory indexes, parses .php scripts, and loads virtual host definitions from httpd-vhosts.conf:
<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>
<IfModule mime_module>
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
</IfModule>
# Enable named virtual hosts
Include conf/extra/httpd-vhosts.conf
Defining Local Virtual Hosts in httpd-vhosts.conf
Map your local development hostname in /etc/hosts:
127.0.0.1 localhost
127.0.0.1 testing.example.com
Then configure the corresponding <VirtualHost *:80> block inside /opt/local/apache2/conf/extra/httpd-vhosts.conf:
<VirtualHost *:80>
ServerAdmin webmaster@testing.example.com
DocumentRoot "/opt/local/apache2/vhosts/testing.example.com"
ServerName testing.example.com
ServerAlias www.testing.example.com
ErrorLog "logs/testing.example.com-error_log"
CustomLog "logs/testing.example.com-access_log" common
<Directory "/opt/local/apache2/vhosts/testing.example.com">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Create the document root directory and verify the Apache configuration syntax before restarting the daemon:
sudo mkdir -p /opt/local/apache2/vhosts/testing.example.com
sudo chmod -R 755 /opt/local/apache2/vhosts/testing.example.com
# Validate configuration syntax and restart Apache via MacPorts
sudo /opt/local/apache2/bin/apachectl configtest
sudo port reload apache2
5. Ongoing Maintenance and Port Upgrades
| MacPorts Command | Operational Purpose |
|---|---|
sudo port selfupdate |
Syncs the remote port tree and updates MacPorts core. |
port outdated |
Lists installed ports that have newer upstream versions available. |
sudo port upgrade outdated |
Compiles and activates updated versions of all outdated ports. |
sudo port uninstall inactive |
Removes older deactivated port versions to reclaim disk space. |
