MacPorts LAMP Stack: Provisioning Apache, MySQL, and PHP on macOS

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.