Install nginx (with HTTP2), PHP 7.0 and MySQL 5.7 server on Mac OSX El Capitan 10.11

In this short article, I'll cover installing PHP 7.0, MySQL Server 5.7 and nginx 1.10 (with HTTP2/SSL) on Mac OSX El Capitan 10.11. Although, the article should cover most previous and all future versions of Mac OS X.

First, start by firing up Terminal and installing brew, a command line package manager for OSX.

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

MySQL

We'll start with MySQL, as it's the easiest.

brew install mysql  

This will install the latest version of MySQL and the command-line tools to connect. By default this installs MySQL server with no root password but locks it to localhost (so only local users can access it anyway), I deem this secure enough for my local environment. If you do want to secure it further, you can run mysql_secure_installation, provided by brew after installation.

To test this is working you can then type

mysql -u root -e 'STATUS'  

NOTE: Add -p to the end of the command if you did setup root with a password.

PHP

Next let's install PHP 7.0.

brew install homebrew/php/php70 homebrew/php/php70-mcrypt homebrew/php/php70-gmagick homebrew/php/php70-opcache homebrew/php/php70-xdebug  

As newer versions of OSX ship with php-fpm, you will need to give priority to our newly installed 7.0. This can be done by changing the order in which paths are checked, using the following command:

export PATH="/usr/local/sbin:$PATH"  
echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile  

Using php -v and php-fpm -v should both show PHP version 7.0.x — If they don't, it may be worth restarting the Terminal window.

To launch PHP type the following, we won't be able to test until later though:

php-fpm --fpm-config /usr/local/etc/php/7.0/php-fpm.conf -D  

You may also want to install install composer, a command-line utility used to install a lot of PHP packages and dependencies, such as Laravel, making our setup complete.

curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer  

Nginx

To install the nginx web server:

brew install --with-http2 nginx  

To configure nginx. We set nginx to use a virtual directory of ~/Hosts/(domain), more will be explained on this later. You can copy this entire whole command block, or edit the config yourself.

sudo bash -c "cat > /usr/local/etc/nginx/nginx.conf" <<- EOM  
user $(whoami) $(id -g -n);  
worker_processes auto;

events {  
    worker_connections  1024;
}

http {  
    include mime.types;
    default_type application/octet-stream;

    access_log /usr/local/var/log/nginx/access.log;
    error_log /usr/local/var/log/nginx/error.log;

    sendfile on;
    keepalive_timeout 5;

    gzip  on;

    server {
        listen 80 default_server;
        listen 443 ssl http2 default_server;

        server_name  _;

        ssl_certificate ssl/nginx.crt;
        ssl_certificate_key ssl/nginx.key;

        root /Users/$(whoami)/Hosts/\$host;

        index index.php;

        location / {
            try_files \$uri \$uri/ /index.php\$is_args\$args;
        }

        location ~ \.php\$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            try_files \$fastcgi_script_name =404;
            fastcgi_index index.php;
            include fastcgi.conf;
        }

        location ~ /\. {
            deny all;
        }
    }
}
EOM  

Generate some self-signed SSL keys. You will be prompted for information on this step, you can put whatever you like.

sudo mkdir /usr/local/etc/nginx/ssl/  
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /usr/local/etc/nginx/ssl/nginx.key -out /usr/local/etc/nginx/ssl/nginx.crt  

Note: You will also be alerted that the certificate is insecure, and have to click Advanced > Proceed to yoursite.dev, this is the only caveat with self signed certificates, and not really avoidable on development environments.

Ok let's check the nginx config and then launch. (we have to launch nginx as root so that it can use port 80.)

sudo nginx  

To check nginx is running you can run the following command:

curl --head http://localhost  

You should see Server: nginx/1.10.0.

And to test all of the above, let's create a localhost entry.

mkdir -p ~/Hosts/localhost/  
echo '<?php phpinfo();' > ~/Hosts/localhost/index.php  

If you navigate to http://localhost/ you should now see a PHP info page similar to the one below.

Launching these services

You can launch the services manually each time by using the following commands.

sudo nginx  
php-fpm --fpm-config /usr/local/etc/php/7.0/php-fpm.conf -D  
mysql.server start  

I recommend you add these alias's to .bash_profile.

alias servers.start='sudo nginx && php-fpm --fpm-config /usr/local/etc/php/7.0/php-fpm.conf -D && mysql.server start'  
alias servers.stop='sudo bash -c "killall -9 php-fpm && mysql.server stop && nginx -s stop"'  
alias nginx.logs='tail /usr/local/opt/nginx/access.log'  
alias nginx.errors='tail /usr/local/opt/nginx/error.log'  

Alternatively, To have these services all auto-start after reboot, use the following.

# Auto-start nginx
cp /usr/local/opt/nginx/homebrew.mxcl.nginx.plist ~/Library/LaunchAgents/  
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist  
# Auto-start PHP-FPM
cp /usr/local/opt/php70/homebrew.mxcl.php70.plist ~/Library/LaunchAgents/  
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.php70.plist  
# Auto-start MySQL Server
cp /usr/local/opt/mysql/homebrew.mxcl.mysql.plist ~/Library/LaunchAgents/  
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist  

Then, if you change your mind and want to stop these from loading on start-up.

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist  
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.php70.plist  
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist  
rm ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist  
rm ~/Library/LaunchAgents/homebrew.mxcl.php70.plist  
rm ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist  

Finally

Finally, instructions will be posted soon about how to setup dynamic hosts in ~/Hosts/ but you can pretty much create or symlink any folder in ~/Hosts/ and then add it to /etc/hosts e.g.

mkdir ~/Hosts/test.dev/  
sudo bash -c "echo '127.0.0.1 test.dev' >> /etc/hosts"  

For now, enjoy!