Skip to content

Instantly share code, notes, and snippets.

@lennardv2
Last active February 29, 2024 07:57
Show Gist options
  • Save lennardv2/538d93ae35297b35e8b56db95b49469c to your computer and use it in GitHub Desktop.
Save lennardv2/538d93ae35297b35e8b56db95b49469c to your computer and use it in GitHub Desktop.
Native PHP development / MAMP stack on Apple silicon M1

Building the MAMP stack (php, apache & mysql) on Apple Silicon ARM (native)

Update! This tutorial is outdated. Nowadays brew installes m1 binaries just fine. Also use valet: https://laravel.com/docs/9.x/valet. It's 10x easier.

In this tutorial, we'll build the the nescessary packages for ARM via homebrew. After that we'll configure apache2 for using virtual hosts. The native php is ofcourse way faster, see the results of this benchmark below.

TEST NAME SECONDS OP/SEC
Rosetta2 191.654 sec 1.96 MOp/s
Intel i7-4790K (imac 2014) 156.791 sec 2.39 MOp/s
Intel i5-8500B (mini 2018) 141.381 sec 2.65 MOp/s
ARM m1 43.745 sec 8.58 MOp/s

Installing homebrew

cd ~
mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
sudo mv homebrew /opt/homebrew

This way homebrew will be installed to the /opt/homebrew folder. We can then initiate homebrew by cd to that directory and run brew in the bin folder.

cd /opt/homebrew/bin
./brew update

If not installed already, the system will ask to install the command-line tools for developers for you. Go ahead.

Now add the homebrew/bin directory to your path by editing/creating a .zshrc file in your home directory.

nano ~/.zshrc
export PATH="/opt/homebrew/bin:$PATH"

Build the packages

Note: checkout this comment if you have problems building python.

Update: Building is probably not necessary anymore, you can omit the -s flag.

brew install -s mysql php@7.4 httpd

This might take some time (30mins) or so. When everything is done it will list some next steps like adding the php module to apache.

Configuration

Make life a bit easier by symlinking the config directories to a rememberable path:

mkdir ~/MAMP
mkdir ~/MAMP/www
ln -s /opt/homebrew/etc/httpd ~/MAMP/httpd
ln -s /opt/homebrew/etc/php/7.4 ~/MAMP/php

Now, let's add some scripts to this directory

nano ~/MAMP/start.sh

start.sh:

#!/bin/zsh

brew services start mysql
brew services start php@7.4
brew services start httpd

stop.sh:

#!/bin/zsh

brew services stop mysql
brew services stop php@7.4
brew services stop httpd

restart.sh:

#!/bin/zsh

brew services restart mysql
brew services restart php@7.4
brew services restart httpd

Make 'em writable:

chmod +x ~/MAMP/start.sh
chmod +x ~/MAMP/stop.sh
chmod +x ~/MAMP/restart.sh

Oke, lets configure apache/httpd for usage with php and enable mod_rewrite along the way:

nano ~/MAMP/httpd/httpd.conf

Uncomment:

# LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so

Change the DocumentRoot:

DocumentRoot "/Users/{username}/MAMP/www"
<Directory "/Users/{username}/MAMP/www">

And add the following to the bottom:


LoadModule php7_module /opt/homebrew/opt/php@7.4/lib/httpd/modules/libphp7.so

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

Include /opt/homebrew/etc/httpd/vhosts/*.conf

Now create a directory named vhosts

mkdir ~/MAMP/httpd/vhosts

Addding a website / virtual host

mkdir ~/MAMP/www/dev.example.com
mkdir ~/MAMP/www/dev.example.com/public_html
mkdir ~/MAMP/www/dev.example.com/logs
nano ~/MAMP/httpd/vhosts/dev.example.com.conf

Add:

<VirtualHost *:8080>
    DocumentRoot "/Users/{username}/MAMP/www/dev.example.com/public_html"
    ServerName dev.example.com
    ErrorLog "/Users/{username}/MAMP/www/dev.example.com/logs/error.log"
    CustomLog "/Users/{username}/MAMP/www/dev.example.com/logs/custom.log" common
</VirtualHost>

<Directory /Users/{username}/MAMP/www/dev.example.com/public_html>
        Options FollowSymLinks Includes
        AllowOverride All
        Order allow,deny
        Allow from all
</Directory>

Add dev.example.com to your hosts file

echo '127.0.0.1 dev.example.com' | sudo tee -a /etc/hosts

Now restart:

~/MAMP/restart.sh

Troubleshooting

Check the output of the following commands:

sudo apachectl start 

If you have see a message saying something like Address already in use: AH00072: make_sock: could not bind to address, try changing the Listen config in httpd.conf to:

Listen 0.0.0.0:8080

Check if your config is valid:

apachectl configtest

Vist http://dev.example.com:8080

Hits

@kevzz1994
Copy link

Using php 7.4? or 8?

@gillesgoetsch
Copy link

PHP 7.4 see brew install -s mysql php@7.4 httpd

@mikeploeger
Copy link

brew install -s mysql
results in:

==> Installing mysql dependency: protobuf
==> ./configure --prefix=/opt/homebrew/Cellar/protobuf/3.14.0 --with-zlib
==> make
==> make check
==> make install
==> /opt/homebrew/opt/python@3.9/bin/python3 -c import setuptools... --no-user-cfg install --prefix=/opt/homebrew/Cellar/protobuf/3.14.0/libexec --install-scripts=/opt
==> /opt/homebrew/opt/python@3.9/bin/python3 -c import setuptools... --no-user-cfg install --prefix=/opt/homebrew/Cellar/protobuf/3.14.0/libexec --install-scripts=/opt
Last 15 lines from /Users/USERNAME/Library/Logs/Homebrew/protobuf/06.python3:
--prefix=/opt/homebrew/Cellar/protobuf/3.14.0/libexec
--install-scripts=/opt/homebrew/Cellar/protobuf/3.14.0/libexec/bin
--single-version-externally-managed
--record=installed.txt
--cpp_implementation

Traceback (most recent call last):
  File "<string>", line 3, in <module>
  File "setup.py", line 211, in <module>
    if mac_target and (pkg_resources.parse_version(mac_target) <
  File "/opt/homebrew/lib/python3.9/site-packages/pkg_resources/__init__.py", line 113, in parse_version
    return packaging.version.Version(v)
  File "/opt/homebrew/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/version.py", line 275, in __init__
    match = self._regex.search(version)
TypeError: expected string or bytes-like object

Do not report this issue to Homebrew/brew or Homebrew/core!

These open issues may also help:
protobuf: macOS big sur compatibility https://github.com/Homebrew/homebrew-core/pull/66337

Error: You are running macOS on a arm64 CPU architecture.
We do not provide support for this (yet).
Reinstall Homebrew under Rosetta 2 until we support it.
You will encounter build failures with some formulae.
Please create pull requests instead of asking for help on Homebrew's GitHub,
Twitter or any other official channels. You are responsible for resolving
any issues you experience while you are running this
unsupported configuration.

Help appreciated!

@atomiix
Copy link

atomiix commented Dec 7, 2020

@Emovere It should be ok now!

@bugigas
Copy link

bugigas commented Dec 8, 2020

sudo apachectl start  
httpd: Syntax error on line 535 of /opt/homebrew/etc/httpd/httpd.conf: 
Cannot load /opt/homebrew/opt/php@7.4/lib/httpd/modules/libphp7.so into server: dlopen(/opt/homebrew/opt/php@7.4/lib/httpd/modules/libphp7.so, 10): 
no suitable image found.  
Did find:\n\t/opt/homebrew/opt/php@7.4/lib/httpd/modules/libphp7.so: mach-o, 
but wrong architecture\n\t/opt/homebrew/Cellar/php@7.4/7.4.13_1/lib/httpd/modules/libphp7.so: mach-o, but wrong architecture

got this error now idk how to fix it...

@skimenlo
Copy link

[similar to "bugugas" 22 days ago"] trying to install [native] PHP on M1 MacBook.

I did " brew install php@8.0", which put "libphp.so" in the httpd/modules folder as expected.

I have httpd.conf at /usr/local/etc/httpd, and it contains:

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

But, I get this error when launching apache:

MacBook-Pro:modules skip$ apachectl -k restart
httpd: Syntax error on line 195 of /usr/local/etc/httpd/httpd.conf: Cannot load /opt/homebrew/Cellar/php/8.0.0_1/lib/httpd/modules/libphp.so into server: dlopen(/opt/homebrew/Cellar/php/8.0.0_1/lib/httpd/modules/libphp.so, 10): no suitable image found. Did find:\n\t/opt/homebrew/Cellar/php/8.0.0_1/lib/httpd/modules/libphp.so: mach-o, but wrong architecture\n\t/opt/homebrew/Cellar/php/8.0.0_1/lib/httpd/modules/libphp.so: mach-o, but wrong architecture

@GaylordP
Copy link

GaylordP commented Jan 9, 2021

Thank you very much, everything went well :)

Can you just clarify how to make php 7.4 Homebrew the default version on the system? when i do 'php -v' 7.3 returned.

Thanks you

@asterisx
Copy link

I did manage to get it working! I first had to wipe all my previous installations and also uninstall brew that all came with migrating from my previous system. I also enabled ssl / 443 listeners.

For mysql to work with root / root I had to do this:
https://stackoverflow.com/a/49935803/2553904
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';

The only thing that doesn't work is the stop / start scripts.
I have to do it with sudo apachectl start to get the listeners showing.
With sudo apachectl configtest I was able to debug my vhosts, which tells me the syntax is ok.

@lvoogdt
Any tips on that? When I use the .sh script, everything looks fine (no errors) but no listeners appear through sudo lsof -i -n -P | grep LISTEN

@kevzz1994
Performance through native Webserver is outstanding and a good amount faster than my 16" i9 pageload.
Which is what I was looking for, but still got surprised:

Unached Complex Wordpress Pageload with debug on:
MacPro 12 Core | 6.6s
MacBook Pro 16" i9 | 4s
MacBook Air M1 (base) | 1.6s

Another Clean Wordpress Site in debug mode:
MacPro 12 Core | 1.5s
MacBook Pro 16" i9 | 1.0s
MacBook Air M1 (base) | 0.4s

Webpack yarn theme build (which happens on watch / filechange):
MacPro 12 Core | 24s
MacBook Pro 16" i9 | 12s
MacBook Air M1 (base) | 5s

I'm kinda getting warm with developing on this M1 after first solving through some x86 obstacles..

Hey mate, can you share the apache configuration you used to setup SSL and the files that needed to be changed?

@jnovakdev
Copy link

Thank you very much, everything went well :)

Can you just clarify how to make php 7.4 Homebrew the default version on the system? when i do 'php -v' 7.3 returned.

Thanks you

Same here, have you fixed it somehow? Thanks in advance!

@davebra
Copy link

davebra commented Feb 2, 2021

Thank you very much, everything went well :)

Can you just clarify how to make php 7.4 Homebrew the default version on the system? when i do 'php -v' 7.3 returned.

Thanks you

@GaylordP @jnovak-dev

Link the php bin to the homebrew's one:
brew link --overwrite --force php@7.4

Export homebrew's php@7.4 bin to your paths:
echo 'export PATH="/opt/homebrew/opt/php@7.1/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/opt/homebrew/opt/php@7.1/sbin:$PATH"' >> ~/.zshrc

Restart your terminal

@duyphuongg
Copy link

Can I install phpmyadmin in mac arm ?

@ashimghimire
Copy link

I have downloaded the mysql http and php from home brew but not yet found the httpd.conf file inside httpd ...httpd is not a folder

@ramlev
Copy link

ramlev commented Feb 8, 2021

I have downloaded the mysql http and php from home brew but not yet found the httpd.conf file inside httpd ...httpd is not a folder

/usr/local/etc/apache2 or /usr/local/etc/httpd ?

@santyzu13
Copy link

santyzu13 commented Feb 10, 2021

Hello, I'm getting this error after the command brew install -s php@7.4

_cli.o main/fastcgi.o sapi/cgi/cgi_main.o -ltidy -largon2 -lresolv -lncurses -laspell -lpspell -lpq -lpq -lsybdb -lldap -llber -lstdc++ -liconv -lgmp -lintl -lbz2 -lm -lxml2 -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lssl -lcrypto -lpcre2-8 -lsqlite3 -lz -lcurl -lxml2 -lffi -lssl -lcrypto -lgd -licuio -licui18n -licuuc -licudata -lonig -lodbc -lodbc -lsqlite3 -ledit -lxml2 -lxml2 -lsodium -largon2 -lxml2 -lxml2 -lxml2 -lxml2 -lxslt -lxml2 -lz -lpthread -licucore -lm -lxml2 -lexslt -lxslt -lxml2 -lz -lpthread -licucore -lm -lxml2 -lzip -lz -lssl -lcrypto -o sapi/cgi/php-cgi /bin/sh /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/libtool --silent --preserve-dup-deps --mode=install cp ext/opcache/opcache.la /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules Generating phar.php /bin/sh: line 1: 91734 Killed: 9 if test -x "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/sapi/cli/php"; then /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/sapi/cli/php -n"; if test "x" != "x"; then /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- " -d extension_dir=/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules"; for i in bz2 zlib phar; do if test -f "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules/$i.la"; then . /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules/$i.la; /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- " -d extension=$dlname"; fi; done; fi; else /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/sapi/cli/php"; fi; -n -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1' -d phar.readonly=0 /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/ext/phar/build_precommand.php > ext/phar/phar.php make: *** [ext/phar/phar.php] Error 137 make: *** Waiting for unfinished jobs....

Can someone help me please?

Full Log Here https://pastebin.com/LRMKLxm

@santyzu13
Copy link

Hello, I'm getting this error after the command brew install -s php@7.4

_cli.o main/fastcgi.o sapi/cgi/cgi_main.o -ltidy -largon2 -lresolv -lncurses -laspell -lpspell -lpq -lpq -lsybdb -lldap -llber -lstdc++ -liconv -lgmp -lintl -lbz2 -lm -lxml2 -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lssl -lcrypto -lpcre2-8 -lsqlite3 -lz -lcurl -lxml2 -lffi -lssl -lcrypto -lgd -licuio -licui18n -licuuc -licudata -lonig -lodbc -lodbc -lsqlite3 -ledit -lxml2 -lxml2 -lsodium -largon2 -lxml2 -lxml2 -lxml2 -lxml2 -lxslt -lxml2 -lz -lpthread -licucore -lm -lxml2 -lexslt -lxslt -lxml2 -lz -lpthread -licucore -lm -lxml2 -lzip -lz -lssl -lcrypto -o sapi/cgi/php-cgi /bin/sh /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/libtool --silent --preserve-dup-deps --mode=install cp ext/opcache/opcache.la /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules Generating phar.php /bin/sh: line 1: 91734 Killed: 9 if test -x "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/sapi/cli/php"; then /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/sapi/cli/php -n"; if test "x" != "x"; then /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- " -d extension_dir=/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules"; for i in bz2 zlib phar; do if test -f "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules/$i.la"; then . /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/modules/$i.la; /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- " -d extension=$dlname"; fi; done; fi; else /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/build/shtool echo -n -- "/private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/sapi/cli/php"; fi; -n -d 'open_basedir=' -d 'output_buffering=0' -d 'memory_limit=-1' -d phar.readonly=0 /private/tmp/php-7.4-20210210-48230-7jo1pi/php-7.4.15/ext/phar/build_precommand.php > ext/phar/phar.php make: *** [ext/phar/phar.php] Error 137 make: *** Waiting for unfinished jobs....

Can someone help me please?

Full Log Here https://pastebin.com/LRMKLxm

It was reolved. I removed homebrew folder and I install all again.

@elloxar
Copy link

elloxar commented Mar 5, 2021

Everything worked 'almost' fine with my installation, including phpMyAdmin which I've installed with the following command:

brew install phpmyadmin

Added the following to httpd.conf:

# Load phpMyAdmin Module
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>

And restart Apache

brew services restart httpd

imagick

Can anyone offer advice on how to install and activate Imagick?

@Amelia-Lopez
Copy link

ImageMagick

Install ImageMagick using Homebrew:

brew install imagemagick

Get pecl on your path:

export PATH=$PATH:/opt/homebrew/Cellar/php@7.4/7.4.16/bin

Compile and register the PHP extension:

pecl install imagick

Verify the PHP extension is available:

/opt/homebrew/Cellar/php@7.4/7.4.16/bin/php -m | grep magic

Restart Apache as needed.

@elloxar
Copy link

elloxar commented Mar 7, 2021

ImageMagick

Install ImageMagick using Homebrew:

brew install imagemagick

Get pecl on your path:

export PATH=$PATH:/opt/homebrew/Cellar/php@7.4/7.4.16/bin

Compile and register the PHP extension:

pecl install imagick

Verify the PHP extension is available:

/opt/homebrew/Cellar/php@7.4/7.4.16/bin/php -m | grep magic

Restart Apache as needed.

Works like a charm, thank you @Amelia-Lopez

@rfos
Copy link

rfos commented Apr 6, 2021

The perfect guide! Thank you

@rajeshstarlite
Copy link

rajeshstarlite commented May 2, 2021

Hello @lvoogdt

Thanks for the guide. I can run the test website http://dev.example.com:8080/, how can we access it without port 8080?

how we can access just root folder, I mean /Users/{username}/MAMP/www/ by opening http://localhost ?

@elloxar,

Yes, I followed the phpmyadmin steps, how can I access it in browser.

I tried http://localhost/phpmyadmin, but It throws error localhost refused to connect.

Any kind of help will be appreciated.

@lennardv2
Copy link
Author

Hello @lvoogdt

Thanks for the guide. I can run the test website http://dev.example.com:8080/, how can we access it without port 8080?

You can do that by changing the port in virtual host file to port 80. Be aware you'll probably need to run httpd as root user. Something like``sudo brew services start httpd``` maybe.

<VirtualHost *:8080> --------> <VirtualHost *:80>

@rajeshstarlite
Copy link

rajeshstarlite commented May 3, 2021

Hello @lvoogdt
Thanks for the guide. I can run the test website http://dev.example.com:8080/, how can we access it without port 8080?

You can do that by changing the port in virtual host file to port 80. Be aware you'll probably need to run httpd as root user. Something like``sudo brew services start httpd``` maybe.

<VirtualHost *:8080> --------> <VirtualHost *:80>

Thanks for the help. I will try again soon. I tried that yesterday itself without sudo so I think somehow couldn't manage to open it without the port.

@rajeshstarlite
Copy link

You can do that by changing the port in virtual host file to port 80. Be aware you'll probably need to run httpd as root user. Something like``sudo brew services start httpd``` maybe.

<VirtualHost *:8080> --------> <VirtualHost *:80>

@lvoogdt Thanks, it works. I forgot last time sudo apachectl restart

@elloxar, it also sorted out.

Copy link

ghost commented Jul 8, 2021

i Have a error after sudo apachectl restart
AH00557: httpd: apr_sockaddr_info_get() failed for Zennns-MacBook-Pro.local
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
(48)Address already in use: AH00072: make_sock: could not bind to address [::]:8080
(48)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:8080
no listening sockets available, shutting down
AH00015: Unable to open logs
zennn@Zennns-MacBook-Pro ~ % nano ~/MAMP/httpd/httpd.conf
zennn@Zennns-MacBook-Pro ~ % apachectl configtest
AH00557: httpd: apr_sockaddr_info_get() failed for Zennns-MacBook-Pro.local
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK

run in MBP M1

@Iznaur
Copy link

Iznaur commented Jul 15, 2021

did anyone have errors when trying install any pecl extension(i tried ssh2, gearman)? Homebrew/homebrew-core#67768 something like described there, how fix this?

Copy link

ghost commented Jul 16, 2021 via email

@pom2fer
Copy link

pom2fer commented Apr 3, 2022

Hello!!! You can make your life 10 times easier by using Valet!
//same than in this tuto
brew install php
brew install mysql
brew services start php
brew services start mysql
//To manage your hosts use Valet https://laravel.com/docs/9.x/valet
composer global require laravel/valet
valet install
cd YOUR_WWW_DIRECTORY
//the command below will do that each subfolder will become a website hosted on http://subfolder.test it's magical :-)
valet park
//Use PHPMonitor to get PHP versions on top bar and Valet integrations
brew tap nicoverbruggen/homebrew-cask
brew install --cask phpmon

I hope it helps :-)

@sr2ds
Copy link

sr2ds commented May 20, 2022

Hello! Someone with PHP 8 and phpunit very very very very slow on M1 too?
I thinked the problem was because running in docker or volumes but without docker with pure PHP on mac, the same performance.
So Bad 😔

@tonypartridge
Copy link

Ohhhh Amazing :-)

@lennardv2
Copy link
Author

lennardv2 commented Oct 26, 2022

Hello! Someone with PHP 8 and phpunit very very very very slow on M1 too? I thinked the problem was because running in docker or volumes but without docker with pure PHP on mac, the same performance. So Bad 😔

I seem to have slowness problems with 8.1/8.2
8.0 runs fine though..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment