When I ran into problems running Drupal on my local install of OSX 10.5 / Leopard a few years ago, I turned to MAMP to save my sanity. MAMP is a simple all-in-one installer with Apache HTTP Server, MySQL and PHP for running PHP web apps on your Mac. It provides a really great way of getting a full *AMP stack running on your Mac, with many more PHP extensions than are normally installed on the built-in version of Apache, and it can easily be removed should you need to. It's also worth mentioning that one of MAMP's strongest features for running Drupal vs alternatives, e.g. Acquia's DAMP / Dev Desktop, is that it can run Apache on port 80, the normal HTTP port, which is great for beginners and experienced developers who hate having to type a port number in the URL to access their local websites.
I originally installed MAMP 1.9 and never updated it because, honestly, it worked, so why bother? On a normal day nobody from the outside world was going to be accessing my web server as my local network is firewalled, and the laptop itself has a firewall so that nobody can access it while I'm using an unsecured network, e.g. at a coffee shop. Thanks to finally having a Drupal 8 issue I really wanted to fix (#1067120) I finally had a reason to upgrade. Drupal 8 requires PHP v5.3.3 or newer, whereas MAMP 1.9 only had v5.3.2. So, time to upgrade.
When MAMP is installed it is required to be ran from /Applications/MAMP—there are lots of configuration files included that depend upon that path, so I'm sure it could be moved if you felt up for the task, or bored. All of the various command line tools, bundled PHP apps and databases are installed in subdirectories, so the normal Mac technique of "delete and replace" for updating the software will run into a major problem: the databases. While MAMP will make your websites automatically available from http://localhost/~myusername/, excluding any custom virtual hosts that are added, the databases are still all created in the /Applications/MAMP/db directory, so these need to be accounted for prior to upgrading.
The first thing I did when I tried upgrading was to copy the MAMP 1.9 databases into the MAMP 2.0 directory structure, but it didn't work, so I had to try another plan. My final process was a quick export of 1.9's databases and then to recreate & reload each one on 2.0; hopefully the following will help you make this upgrade too.
Step 1: Export databases
The first step is to export all of the existing databases. The simplest way I found was:
- Make sure MAMP v1.9 is running.
- Also make sure you know the existing MySQL root username and password, which will be used later on as ROOTUSER and ROOTPASSWD respectively.
- In terminal do a directory listing of /Applications/MAMP/db/mysql with each directory on its own line, e.g.: ls /Applications/MAMP/db/mysql | grep -v '\.'
- In a text editor with regex search/replace (e.g. TextMate), open a new window and paste the list from terminal into a new editor window; you can remove the 'test' line as that's a default database you probably weren't using, but the rest need to be kept.
- In your text editor of choice, search for the string "(.*)\n" and replace it with "mysqldump -Q --add-drop-table -c --order-by-primary --extended-insert=FALSE --no-create-db=TRUE -uROOTUSER -pROOTPASSWD $1 > $1.sql\n". This runs the usual "mysqldump" command to export the database to a file and uses to settings to make the export file a little simpler to deal with.
- You should end up with a set of lines like this:
mysqldump -Q --add-drop-table -c --order-by-primary --extended-insert=FALSE --no-create-db=TRUE -uROOTUSER -pROOTPASSWD example > example.sql mysqldump -Q --add-drop-table -c --order-by-primary --extended-insert=FALSE --no-create-db=TRUE -uROOTUSER -pROOTPASSWD joeschmoley > joeschmoley.sql mysqldump -Q --add-drop-table -c --order-by-primary --extended-insert=FALSE --no-create-db=TRUE -uROOTUSER -pROOTPASSWD monkey > monkey.sql
- Paste the lines back into terminal, one at a time if you prefer; this will create export files for each of the database in the format "databasename.sql", which keeps things nice and simple, and scriptable.
- Side note: some utilities (*cough* phpMyAdmin *cough*) may create a slightly invalid database dump file, the options provided to "mysqldump" above are one I've found to work really well and help avoid some of the odd problems that can arise.
Step 2: The MAMPy Shuffle
The next step is to swap around the MAMP installs and tweak the configuration of MAMP v2 so the database dump files will be able to load.
Before you do any file shuffling, turn off MAMP 1.9 (hit the "Stop services" button) and then quit the MAMP application. Just to confirm it is fully disabled, try visiting one of your local development sites, it should say that the web server is unavailable. Once that is done, go to /Applications and rename the "MAMP" directory to e.g. "MAMP 1.9" as we'll need it later.
Install MAMP / MAMP Pro v2 as normal, which will go into /Applications/MAMP - exactly where the old version was. At this point I'd like to go on a tangent and wish you could choose where it's installed, but it's not usually *that* big of a deal. But, I digress. Once it's installed, start the MAMP control panel.
Now that MAMP is installed it needs to be configured so the database dump files can be loaded. The first think you'll want to do is change it to use PHP 5.3 (on the PHP settings tab), as Drupal (and contrib modules especially) isn't currently fully compatible with the default of PHP 5.4. Incidentally, it seems that you can only pick PHP 5.3 if you're using MAMP Pro, the basic MAMP only allows you to pick 5.2 or 5.4, so give the Pro version a trial run to make these changes.
While you're in the configuration tool you'll also want to turn on the APC caches, and on the General settings click the "Default Ports" button to change all three services (Apache, SSL and MySQL) to their respective default port (80, 443 and 3306) rather than the custom ones MAMP ships with. That said, just be aware that the system will validate account password when MAMP is started or stopped due to OSX's standard UNIX security practices - only the admin can run programs on ports lower than 1000, i.e. Apache HTTP server's use of ports 80 and 443.
At this point it's safe to hit the Apply button to save all changes, and it should also be possible to click the Start button to launch MAMP. Should any errors occur be sure to check the log files, tweak the settings and try again.
The next thing is to fix PHP so it uses more memory and has a higher execution timeout limit than the default. To do so, open the "php.ini" file for each version of PHP that's available, i.e. edit /Applications/MAMP/conf/php5.2.17/php.ini for PHP 5.2, etc. The following line(s) will need to be changed to the value(s) shown:
- memory_limit = 128M
or even more if you have a lot of memory in your machine:
- memory_limit = 256M
If you don't use Drush you'll also want to change "max_execution_time" to 60 or maybe even 180, just to be safe. Also, shame on you for not using Drush!
Make the above changes for each version of PHP installed (at the time of writing - 5.2.7, 5.3.14, 5.4.4), then stop & start MAMP again to ensure the settings have taken effect properly.
The final configuration step is to fix MySQL. Out of the box it has several problems - it doesn't listen to requests on the TCP/IP port, it has a limit on the query length that'll cause problems with Drupal's cache tables & others (the "max_allowed_packet" setting), and has some really low memory limits for InnoDB that need improving. I've attached a copy of the my.cnf file that I use (it's zipped, so just download it and extract if necessary to get the raw "my.cnf" file), which should be placed in /Applications/MAMP/conf. Again, restart MAMP for the settings to take effect.
Step 3: Loading the databases
With my databases I use the simple convention of having a user for each database, with the same name for each, and the password set to the same value too, e.g. the "example" database is accessible by a user "example" with the password "example". This keeps it super simple to remember what's what, avoids me storing my root password in multiple text files which would then be uploaded to a code repository for others to see, and makes it scriptable. Add to this another dash of regular expressions and the database setup becomes child's play, almost.
There is one thing to watch for when import the SQL file. There's honestly no need to import the data into Drupal's cache tables as they can be recompiled at runtime, so we'll tweak the import commands to ignore those lines.
Anyway, on with the show:
- Copy the list of database names into a new text editor window again, removing the "test" item once again.
- Search for the string "(.*)\n" and replace it with (all one line!):
echo '$1';mysqladmin -uROOTUSER -pROOTPASSWD create $1 --default-character-set=utf8;mysql -uROOTUSER -pROOTPASSWD -e "CREATE USER '$1'@'localhost' IDENTIFIED BY '$1';GRANT ALL PRIVILEGES ON $1.* TO '$1'@'localhost'";grep -v "INSERT INTO \`cache" $1.sql | mysql -u$1 -p$1 $1;\n
- This should result in lines like the following:
echo 'example';mysqladmin -uROOTUSER -pROOTPASSWD create example --default-character-set=utf8;mysql -uROOTUSER -pROOTPASSWD -e "CREATE USER 'example'@'localhost' IDENTIFIED BY 'example';GRANT ALL PRIVILEGES ON example.* TO 'example'@'localhost'";grep -v "INSERT INTO \`cache" example.sql | mysql -uexample -pexample example; echo 'joeschmoley';mysqladmin -uROOTUSER -pROOTPASSWD create joeschmoley --default-character-set=utf8;mysql -uROOTUSER -pROOTPASSWD -e "CREATE USER 'joeschmoley'@'localhost' IDENTIFIED BY 'joeschmoley';GRANT ALL PRIVILEGES ON joeschmoley.* TO 'joeschmoley'@'localhost'";grep -v "INSERT INTO \`cache" joeschmoley.sql | mysql -ujoeschmoley -pjoeschmoley joeschmoley; echo 'monkey';mysqladmin -uROOTUSER -pROOTPASSWD create monkey --default-character-set=utf8;mysql -uROOTUSER -pROOTPASSWD -e "CREATE USER 'monkey'@'localhost' IDENTIFIED BY 'monkey';GRANT ALL PRIVILEGES ON monkey.* TO 'monkey'@'localhost'";grep -v "INSERT INTO \`cache" monkey.sql | mysql -umonkey -pmonkey monkey;
- Either copy each line to the terminal and run it, or save it as a file (e.g. save as "db_migrate.sh" then run "sh db_migrate.sh"); when ran as a script the "echo" command will tell you what database file is being imported, so if any errors show you'll have an easier time identifying which database had the error.
And that should be it! You now should be able to run all of your sites on MAMP 2 without any any problems.
Extra Brownie points
There are a few other improvements that can be made to the MAMP installation. e.g.:
- Install the "uploadprocess" PECL extension:
- Download PHP source code and run ./configure
- Run the following command from the terminal: pecl install uploadprogress
- Change some additional php.ini settings: memory_limit magic_quotes_gpc, magic_quotes_runtime, max_input_vars
- Set the terminal's PATH so Apache, PHP and MySQL's commands are available without headaches.
- Changed MAMP's settings so it launches on start but doesn't stop on quit.
- Disable some Apache modules, e.g. authn_dbm_module, authn_dbd_module, authz_gropfile_module, authz_dbm_module, all cache modules, dbd_module, bucketeer_module, dumpio_module, echo_module, example_module, case_filter_module, case_filter_in_module, reqtimeout_module, ext_filter_module, include_module, substitute_module, charset_lite_module, logio_module, cern_meta_module, unique_id_module, version_module, the proxy modules, the dav modules, asis_module, the cgi modules, imagemap, and speling_module.
If you have suggestions on how to improve this, including other plugins/extensions that you find essential, or ways to further optimize the export/import process let me know!