Skip to content

Instantly share code, notes, and snippets.

@ogrrd
Last active November 12, 2020 22:16
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save ogrrd/5824274 to your computer and use it in GitHub Desktop.
Save ogrrd/5824274 to your computer and use it in GitHub Desktop.
Installing nginx, PHP and MySQL on OS X Mavericks

Installing a Web Developer setup on OS X Mavericks

Install Command Line Tools

This is a requirement for brew in the next step. You can install XCode and then install Command Line Tools through the XCode preferences, or you can install just the Command Line Tools.

Install Command Line Tools

$ xcode-select --install

Install XQuartz

A version of the X.Org X Window System that runs on OS X

Download and install xquartz.macosforge.org

Install Brew

Homebrew or Brew is a package manager for OS X and will allow us to install PHP, MySQL and nginx.

  1. Open a Terminal window

  2. Install brew

$ ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go)


1. Make sure your system is ready to brew!

  ```bash
$ brew doctor
  1. Now update brew so we're installing the latest packages
$ brew update
  1. Install wget
$ brew install wget
  1. Edit your bash profile
$ nano ~/.bash_profile
  1. Put the following lines at the bottom (don't worry if this file is empty!)

PATH=/usr/local/sbin:/usr/local/bin:$PATH; source brew --prefix/Library/Contributions/brew_bash_completion.sh


1. Save and exit with `CTRL` + `O`, `Return` and then `CTRL` + `X`
1. Reload bash profile without relogging

	```bash
$ source ~/.bash_profile

Install Git

Only do this if you'd like to use Git as part of your development process.

  1. Install

$ brew install git


1. Configure

	```bash
$ git config --global user.name "your name here"
$ git config --global user.email "your email here"
  1. I don't like vi so let's use nano instead

$ git config --global core.editor "nano"


1. Let's get some colour coding in our Git shell! *(optional)*

	```bash
$ git config --global color.ui true
  1. Let's get Git info in our shell! Follow the instructions here (optional)

Install (E)nginx, MySQL, PHP

Visit the amazing brew-emp Homebrew (E)nginx MySQL PHP Installer and follow the instructions!

Install memcache

brew-emp installs the PHP extension memcached, installing the memcache extension as well adds support for more projects, such as CakePHP out of the box.

$ brew install php55-memcache

Secure your setup (optional)

MySQL ships with no root password and an anonymous account and lets anyone connect from your LAN. If you're at a conference or just in the office, that means anyone can access your databases with root!

$ mysql_secure_installation

...and follow the prompts.

Install Composer

The Dependency Manager for PHP

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

This way allows us to perform composer selfupdate without ill effects.

Create nginx conf for regular PHP sites

Modify /usr/local/etc/nginx/common/php

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_buffer_size 4k;
    fastcgi_buffers 256 4k;
    fastcgi_max_temp_file_size 0;
    include        fastcgi_params;
}

Make core config for Symfony2 sites

Create /usr/local/etc/nginx/common/symfony2

location = /favicon.ico {
    log_not_found off;
    access_log off;
}

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

location ~ \..*/.*\.php$ {
    return 403;
}

location / {
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /app.php/$1 last;
}

location ~ ^/(app|app_dev|config)\.php(/|$) {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTPS off;
    fastcgi_buffer_size 4k;
    fastcgi_buffers 256 4k;
    fastcgi_max_temp_file_size 0;
}

Make core config for plain PHP sites

Create /usr/local/etc/nginx/common/index for index.php sites

include /usr/local/etc/nginx/common/php;

location = /favicon.ico {
    log_not_found off;
    access_log off;
}

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

location ~ \..*/.*\.php$ {
    return 403;
}

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

Make an equivalent for index_dev.php sites, call it index_dev

Create skeleton for local dev sites

Create /usr/local/etc/nginx/sites-available/mysite.dev

server {
    listen       80;
    server_name  mysite.dev;
    root /Users/og/Sites/mysite.dev;

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

    include /usr/local/etc/nginx/common/index; # or /usr/local/etc/nginx/common/index_dev
}

Copy this file to myproject.dev (or whatever) and change every instance of "mysite" with "mygreatproject"

Enable new sites

$ cd /usr/local/etc/nginx
$ rm -r sites-enabled
$ ln -s sites-available sites-enabled

Fix some things in php.ini

$ pico /usr/local/etc/php/5.5/php.ini

Fix the timezone

Locate and update the date.timezone variable as per best practice

date.timezone = "Europe/London"

Fix the include path

Locate and update include_path variable

include_path = ".:/usr/local/lib/php:/usr/local/opt/php55/lib/php"

Fix permissions

Fix the user in php-fpm.conf

$ pico /usr/local/etc/php/5.5/php-fpm.conf

Locate and update the user and group variables so files are written as you

user = whateveryourshortusernameis
group = staff

Fix the user in nginx.conf

$ pico /usr/local/etc/nginx/nginx.conf

Append a user directive to the top, I expect you'll find work_processes at the top by default.

user whateveryourshortusernameis staff;

Restart all the things!

$ brew-emp stop && brew-emp start

brew-emp restart doesn't seem to actually reload nginx

@davidyell
Copy link

I would propose adding into your Git setup

$ git config --global color.ui true

Also as an aside you should always configure your timezone to be UTC rather than whatever you locale is. This is because it is easier to work out timezone differences from UTC, even things like BST.

@ogrrd
Copy link
Author

ogrrd commented Jun 21, 2013

The reason I use Europe/London is so I get the right time in summer and winter, as per http://stackoverflow.com/questions/16900339/is-there-a-difference-between-europe-london-and-utc-in-php

@davidyell
Copy link

You can calculate daylight savings from UTC, that's the whole idea. If your reference point is in BST and you send an email to another part of the world, you then need to calculate time based off BST which is then GMT+1 whereas the UTC time will always remain the same allowing you to calculate it even for countries which don't have any daylight savings time.

Personally, I wouldn't put much stock in a SO question which has two downvotes and only 5 upvotes on the answer. Unfortunately this is something that I've had engrained into me, but I'm not sure where from, so I can't link to a more reputable source.

@ogrrd
Copy link
Author

ogrrd commented Jun 21, 2013

Sorry I meant it as a quick example, I certainly didn't base my understanding of it on that one SO post. I don't see any disadvantage in setting the timezone to UTC offset DST (Europe/London) over UTC yet, but I'll continue to investigate as if there's something silently going wrong somewhere, I want (need!) to know about it.

@ogrrd
Copy link
Author

ogrrd commented Jun 21, 2013

Ah, interesting, I'm discovering bits and pieces talking about the UNIX timestamp returned from a non UTC timezone and how you should use UTC in PHP and MySQL and then return the timestamp to the browser to let it show local time to the user. This is interesting. This could be a basis for wanting to keep it all UTC as timestamp doesn't contain any timezone information. Learning something new here...

@ogrrd
Copy link
Author

ogrrd commented Jun 21, 2013

Alright, we're there. This, I think, is a more suitable SO post. http://stackoverflow.com/questions/2532729/daylight-saving-time-and-timezone-best-practices

I shall update the gist now!

Thank you, David!

@davidyell
Copy link

@hackzilla
Copy link

I'd suggest linking composer.phar to composer

mv /usr/local/bin/composer.phar /usr/local/bin/composer
ln -s /usr/local/bin/composer /usr/local/bin/composer.phar

That way you can just run composer selfupdate as normal.

@hackzilla
Copy link

I think you need to mention running nginx as root.

@ogrrd
Copy link
Author

ogrrd commented Jul 3, 2013

@hackzilla thanks for the heads up on the composer.phar! As for the nginx as root bit, brew-emp start will ask you for a password and run nginx on port 80. I avoided talking about LaunchDaemons to keep it manually controlled.

@hackzilla
Copy link

in "Make core config for Symfony2 sites" don't include php, as you've already defined in that file.

@ogrrd
Copy link
Author

ogrrd commented Aug 19, 2013

@hackzilla ah yes, I see. Thanks!

@hackzilla
Copy link

if you want phpunit then you need this:

sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover pear.symfony.com
sudo pear install --alldeps phpunit/phpunit
ln -s $(brew --prefix josegonzalez/php/php54)/bin/phpunit /usr/local/bin/

php.ini
include_path = ".:/usr/local/opt/php54/lib/php"

@dimaninc
Copy link

dimaninc commented May 2, 2018

please fix brew configuring: paulirish/dotfiles#80

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