Skip to content

Instantly share code, notes, and snippets.

@zimmen zimmen/setup.md Secret
Created Aug 28, 2012

Embed
What would you like to do?
Developer System Setup [OS X]

My Mac OS X bare install guide

Apps & Tools


This is a list of applications and tools i use for development work and productivity.

  • Chrome
  • Firefox
  • iTerm -> Because Terminal.app sucks
  • Sublime Text 2 -> The best code editor. Has a complete section in this file.
  • PhpStorm -> Great (the best?) IDE.
  • Xcode -> Apple's development IDE
  • CodeKit -> "CodeKit helps you build websites faster and better", it's true!
  • Go2Shell -> Drop this in your finder toolbar
  • Alfred -> best launchpad tool out there
  • Spectacle -> Fast and clean window manager
  • Transmit -> FTP client that needs no introduction
  • Forklift -> File manager (old people that remember norton commander might like this)
  • atMonitor -> System monitor
  • Mou -> Markdown editor
  • SourceTree -> Git/Hg GUI with a lot of great options
  • ImageOptim -> What's in a name! It optimizes images!
  • DiffMerge -> For when the diffing gets tough.
  • CodeRunner -> Run small snippets of code. Great to test stuff or to create quick helper functions.

Xcode Command Line Tools

You need this. Without this, nothing will work.

Xcode > Preferences > Downloads > Command Line Tools

It's availible as a seperate download on Apple's developer website as well.

Homebrew

The must have package manager for OS X.

First we install homebrew itself

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

Then we install some nice tools

brew install git ack wget curl readline sqlite gdbm pkg-config

Sublime Text CLI

After installing Sublime Text 2 we create a symbolic link so we can sun Sublime Text from the shell. No need for this when you use oh-my-zsh and use the sublime plugin. (that is what i do)

sudo mkdir -p "/usr/local/bin/" && ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" "/usr/local/bin/st"

SaSS & Compass

Codekit has these bundled but i always want to have access to the latest versions so i install both on my system as well.

sudo gem install sass
sudo gem install compass

Coding fonts

This is what i currently like: Mensch coding font. This changes every now and then.

The Shell


I have my own particular shell setup. Use whatever you like best.

ZSH

I have switched to zsh after using the default bash shell for a long time. Especially the awesome oh-my-zsh package made me go for it.

Install ZSH

This is the one-line-does-it-all command to download oh-my-zsh and set zsh as your default shell:

curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh

To further personalize my shell i use the Monokai iTerm Color-scheme and created the Zimmen_prose.zsh-theme to put in /.oh-my-zsh/themes. Pick any theme that suits your needs. Mine is based on prose.zsh-theme and has a friendly touch to it!

Setup your ~/.zshrc

You can setup the shell in ~./zshrc

st ~/.zshrc

This file sets paths, the zsh theme, plugins, aliases etc. You could split all this into separate files and source them here but i didn't find that usefull with this small setup.

ZSH=$HOME/.oh-my-zsh
ZSH_THEME="Zimmen_prose"
plugins=(git git-flow sublime osx rails ruby github node npm brew)
source $ZSH/oh-my-zsh.sh
export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/zend/mysql/bin:/usr/X11/bin:$PATH

#Aliases
alias tu="top -o cpu" #cpu
alias tm="top -o vsize" #mem
alias ip="curl -s http://checkip.dyndns.com/ | sed 's/[^0-9\.]//g'"
alias localip="ipconfig getifaddr en0"
alias localip-wifi="ipconfig getifaddr en0"

#Functions
function take() {
    md "$1"
    cd "$1"
}

It's pretty self explanatory. More info on ZSH plugins is on the oh-my-zsh wiki

Git


Setup ssh key

You need this for ssh connections to Github and sorts (i'm using Bitbucket as well for private repo's)

Generate key

Use your own email address

ssh-keygen -t rsa -C "email@ddr.ess"

Copy key to clipboard

pbcopy < ~/.ssh/id_rsa.pub

Add this key to Github and Bitbucket.

test connection to github

ssh -T git@github.com

set git config values

Use your own name, email address and username

git config --global user.name "Simon de Turck"
git config --global user.email "email@ddr.ess"
git config --global github.user zimmen
git config --global core.editor "st -w"
git config --global color.ui true

And when using oh-my-zsh, check out this git plugin (it is enabled in the ~./zshrc example above)

Set OS X Defaults


You get a list of settings from here. There is a more extensive one but i stripped that to suit my needs.

This basically sets some default OS X behaviors.

#Server

In the info below you can see i'm using exampledomain.nl. Naturally this isn't what you would use! In my case, i use the intranet domain of the company where i work

This is my server setup. My goal is to use the native Apache installation that comes with OS X. I want to have a simple to use setup where i can just add a folder and access this by [foldername].simon.exampledomain.nl.

foldername = the folder on my drive where the files live simon = my hostname exampledomain.nl = the domain

The folder structure would be like:

/Users/Simon/Development/vhosts/[projectname]/public_html/

The public_html is added so i can use the project folder for other stuff as well.

So when i create this folder: /Users/Simon/Development/vhosts/symphony-cms/public_html/

I can access it at http://symphony-cms.simon.exampledomain.nl. All automatically.

This is a pretty straightforward setup. On my company's network DNS server i have added a wildcard DNS A record *.simon.exampledomain.nl to point to my machine. This way all my colleagues and mobile devices on the network can access the projects as well and i don't have to edit a hosts file or run a tool like virtualhostx.

There are some caveats:

  • OS X has old php
  • MySQL has to be installed
  • I'm using a MacBook and i want this to work on every network (home, work, wherever)

So i will install a newer php, install mysql and install and setup dnsmasq… what?

Dnsmasq is a lightweight DNS forwarder that will enable me to add a wildcart DNS record for *.simon.exampledomain.nl on my local machine (so still no hosts file edits)

So here we go

Set hostname

sudo scutil --set HostName Simon

Install and configure dnsmasq

brew install dnsmasq

After installing, the instructions on how to enable the daemon are displayed on screen, copy those or use the code under Enable dnsmasq daemon below. Be sure to look at the version number as it is used in the path you have to copy the LaunchDaemon plist from!

Add DNS Domain(s) to dnsmasq

This is where the record gets added in the file /usr/local/etc/dnsmasq.conf

mkdir -p /usr/local/etc/ &&
echo "address=/.simon.exampledomain.nl/127.0.0.1" >> /usr/local/etc/dnsmasq.conf && 
echo "listen-address=127.0.0.1" >> /usr/local/etc/dnsmasq.conf

You add more record if you like.

Enable dnsmasq daemon

See the [CHECK VERSION] there? use the version you remembered before (or paste the code you copied)

sudo cp "/usr/local/Cellar/dnsmasq/[CHECK VERSION]/homebrew.mxcl.dnsmasq.plist" "/Library/LaunchDaemons" &&
sudo launchctl load -w "/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist"

Add Localhost to /etc/resolver

This makes dure your local DNS is queried. Not quite sure this still works in 10.8

sudo -s
sudo mkdir -p /etc/resolver
sudo echo 'nameserver 127.0.0.1' > /etc/resolver/build

To be on the safe side, i added 127.0.0.1 to my network settings DNS servers list (as first entry)

System Preferences -> Network -> Your interface -> Advanded -> DNS Servers

flush cache

dscacheutil -flushcache

Ensure it works

scutil --dns

Enable Apache virtual hosts

This virtual hosts setup makes the easy "create folder -> work" functionality

####Create the user config file

sudo touch /etc/apache2/users/$USER.conf 
sudo st /etc/apache2/users/$USER.conf

Add this to the config file. This is where the magic VirtualDocumentRoot stuff happens.

Make sure you use your own username in the path /Users/Simon/Sites/

DocumentRoot "/Users/Simon/Sites/"
NameVirtualHost *:80
<Directory "/Users/Simon/Sites/">
    Options Indexes MultiViews FollowSymLinks Includes
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>
<VirtualHost *:80>
    UseCanonicalName off
    VirtualDocumentRoot /Users/Simon/Sites/%1/public_html
</VirtualHost>

The line VirtualDocumentRoot /Users/Simon/Sites/%1/public_html inserts the first part of the URI into %1. You can do all kinds of crazy stuff with this

Create symbolic link to your development folder

This is optional but i like to have all my stuff in the Developent folder. Why didn't i just use this folder in the user config? well, because the User/Simon/Sites is apple's convention. This way i have 1 place where the files are but i can have many links to it.

sudo ln --Fhis ~/Sites ~/Development/vhosts

Configure httpd.conf

I am using the httpd.conf with comments removed. It's pretty default. The only thing different is the enabled php module (more on that in the php section) and added php_module directions.

open apache config

st /etc/apache2/httpd.conf

Paste this configuration

Again, this is what suits me, change as you deem neccesarry. Be sure to change the ServerAdmin and ServerName directives.

ServerRoot "/usr"

Listen 80

LoadModule authn_file_module libexec/apache2/mod_authn_file.so
LoadModule authn_dbm_module libexec/apache2/mod_authn_dbm.so
LoadModule authn_anon_module libexec/apache2/mod_authn_anon.so
LoadModule authn_dbd_module libexec/apache2/mod_authn_dbd.so
LoadModule authn_default_module libexec/apache2/mod_authn_default.so
LoadModule authz_host_module libexec/apache2/mod_authz_host.so
LoadModule authz_groupfile_module libexec/apache2/mod_authz_groupfile.so
LoadModule authz_user_module libexec/apache2/mod_authz_user.so
LoadModule authz_dbm_module libexec/apache2/mod_authz_dbm.so
LoadModule authz_owner_module libexec/apache2/mod_authz_owner.so
LoadModule authz_default_module libexec/apache2/mod_authz_default.so
LoadModule auth_basic_module libexec/apache2/mod_auth_basic.so
LoadModule auth_digest_module libexec/apache2/mod_auth_digest.so
LoadModule cache_module libexec/apache2/mod_cache.so
LoadModule disk_cache_module libexec/apache2/mod_disk_cache.so
LoadModule mem_cache_module libexec/apache2/mod_mem_cache.so
LoadModule dbd_module libexec/apache2/mod_dbd.so
LoadModule dumpio_module libexec/apache2/mod_dumpio.so
LoadModule reqtimeout_module libexec/apache2/mod_reqtimeout.so
LoadModule ext_filter_module libexec/apache2/mod_ext_filter.so
LoadModule include_module libexec/apache2/mod_include.so
LoadModule filter_module libexec/apache2/mod_filter.so
LoadModule substitute_module libexec/apache2/mod_substitute.so
LoadModule deflate_module libexec/apache2/mod_deflate.so
LoadModule log_config_module libexec/apache2/mod_log_config.so
LoadModule log_forensic_module libexec/apache2/mod_log_forensic.so
LoadModule logio_module libexec/apache2/mod_logio.so
LoadModule env_module libexec/apache2/mod_env.so
LoadModule mime_magic_module libexec/apache2/mod_mime_magic.so
LoadModule cern_meta_module libexec/apache2/mod_cern_meta.so
LoadModule expires_module libexec/apache2/mod_expires.so
LoadModule headers_module libexec/apache2/mod_headers.so
LoadModule ident_module libexec/apache2/mod_ident.so
LoadModule usertrack_module libexec/apache2/mod_usertrack.so
#LoadModule unique_id_module libexec/apache2/mod_unique_id.so
LoadModule setenvif_module libexec/apache2/mod_setenvif.so
LoadModule version_module libexec/apache2/mod_version.so
LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so
LoadModule proxy_ftp_module libexec/apache2/mod_proxy_ftp.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
LoadModule proxy_scgi_module libexec/apache2/mod_proxy_scgi.so
LoadModule proxy_ajp_module libexec/apache2/mod_proxy_ajp.so
LoadModule proxy_balancer_module libexec/apache2/mod_proxy_balancer.so
LoadModule ssl_module libexec/apache2/mod_ssl.so
LoadModule mime_module libexec/apache2/mod_mime.so
LoadModule dav_module libexec/apache2/mod_dav.so
LoadModule status_module libexec/apache2/mod_status.so
LoadModule autoindex_module libexec/apache2/mod_autoindex.so
LoadModule asis_module libexec/apache2/mod_asis.so
LoadModule info_module libexec/apache2/mod_info.so
LoadModule cgi_module libexec/apache2/mod_cgi.so
LoadModule dav_fs_module libexec/apache2/mod_dav_fs.so
LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
LoadModule negotiation_module libexec/apache2/mod_negotiation.so
LoadModule dir_module libexec/apache2/mod_dir.so
LoadModule imagemap_module libexec/apache2/mod_imagemap.so
LoadModule actions_module libexec/apache2/mod_actions.so
LoadModule speling_module libexec/apache2/mod_speling.so
LoadModule userdir_module libexec/apache2/mod_userdir.so
LoadModule alias_module libexec/apache2/mod_alias.so
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
#LoadModule perl_module libexec/apache2/mod_perl.so

#Default OSX php (disabled)
#LoadModule php5_module libexec/apache2/libphp5.so

# Homebrew-php 5.3 (active)
LoadModule php5_module /usr/local/Cellar/php53/5.3.15/libexec/apache2/libphp5.so

# Homebrew-php 5.4 (disabled)
#LoadModule php5_module /usr/local/Cellar/php54/5.4.5/libexec/apache2/libphp5.so

#LoadModule hfs_apple_module libexec/apache2/mod_hfs_apple.so

<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>

User _www
Group _www

</IfModule>
</IfModule>


ServerAdmin info@exampledomain.nl

ServerName simon.exampledomain.nl

DocumentRoot "/Library/WebServer/Documents"

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

<Directory "/Library/WebServer/Documents">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>

<FilesMatch "^\.([Hh][Tt]|[Dd][Ss]_[Ss])">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

<Files "rsrc">
    Order allow,deny
    Deny from all
    Satisfy All
</Files>

<DirectoryMatch ".*\.\.namedfork">
    Order allow,deny
    Deny from all
    Satisfy All
</DirectoryMatch>

ErrorLog "/private/var/log/apache2/error_log"

LogLevel warn

<IfModule log_config_module>

    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    CustomLog "/private/var/log/apache2/access_log" common

</IfModule>

<IfModule alias_module>
    ScriptAliasMatch ^/cgi-bin/((?!(?i:webobjects)).*$) "/Library/WebServer/CGI-Executables/$1"
</IfModule>

<IfModule cgid_module>
</IfModule>

<Directory "/Library/WebServer/CGI-Executables">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>

DefaultType text/plain

<IfModule mime_module>

    TypesConfig /private/etc/apache2/mime.types

    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz

</IfModule>

TraceEnable off

Include /private/etc/apache2/extra/httpd-mpm.conf
Include /private/etc/apache2/extra/httpd-autoindex.conf
Include /private/etc/apache2/extra/httpd-languages.conf
Include /private/etc/apache2/extra/httpd-userdir.conf
Include /private/etc/apache2/extra/httpd-manual.conf

<IfModule ssl_module>
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
</IfModule>

<IfModule php5_module>
    AddType application/x-httpd-php .php
    AddType application/x-httpd-php-source .phps
    <IfModule dir_module>
        DirectoryIndex index.html index.php
    </IfModule>
</IfModule>

Include /private/etc/apache2/other/*.conf

Install php

I have chosen homebrew-php to install and keep php up to date. Follow these instructions a detailed install.

The short version:

brew tap homebrew/dupes
brew tap josegonzalez/homebrew-php
brew install php53

Oh, and installing php can take a while … it's going to build you a fresh copy!

You can install multiple versions (see the instructions). In the httpd.conf above i have version 5.3 enabled. if you want to install 5.4 as well, run

brew install php54

and change the httpd.conf to load php 5.4

Install XDebug

Time to take php debugging seriously… die(), print_r(), var_dump() et al is history. This works great with PhpStorm.

brew install php53-xdebug

Configure php.ini

Php needs some configuring.

create php.ini

sudo touch /etc/php.ini && st /etc/php.ini
Paste this config

Change whatever you need.

[PHP]
engine = On
short_open_tag = On
asp_tags = Off
precision = 14
y2k_compliance = On
output_buffering = 4096
;output_handler =
zlib.output_compression = On
zlib.output_compression_level = -1
zlib.output_handler =
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 17
allow_call_time_pass_reference = Off
safe_mode = Off
safe_mode_gid = Off
safe_mode_include_dir =
safe_mode_exec_dir =
safe_mode_allowed_env_vars = PHP_
safe_mode_protected_env_vars = LD_LIBRARY_PATH
disable_functions =
disable_classes =
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL | E_STRICT
display_errors = On
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = On
;error_prepend_string = "<span style='color: #ff0000'>"
;error_append_string = "</span>"
;error_log = php_errors.log
;error_log = syslog
variables_order = "GPCS"
request_order = "GP"
register_globals = Off
register_long_arrays = Off
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 8M
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "utf-8"
include_path = ".:/usr/lib/php/pear"
doc_root =
user_dir =
extension_dir = "/usr/lib/php/extensions/no-debug-non-zts-20090626"
enable_dl = Off
file_uploads = On
upload_max_filesize = 8M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60


[Date]

date.timezone = "Europe/Amsterdam"

[filter]

[iconv]

[intl]

[sqlite]

[sqlite3]

[Pcre]

[Pdo]

[Pdo_mysql]

pdo_mysql.cache_size = 2000
pdo_mysql.default_socket=/var/mysql/mysql.sock

[Phar]

[Syslog]

define_syslog_variables  = Off

[mail function]

SMTP = localhost
smtp_port = 25
mail.add_x_header = On

[SQL]

sql.safe_mode = Off

[ODBC]

odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1

[Interbase]

ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"

[MySQL]

mysql.allow_local_infile = On
mysql.allow_persistent = On
mysql.cache_size = 2000
mysql.max_persistent = -1
mysql.max_links = -1
mysql.default_port = 3306
mysql.default_socket = /var/mysql/mysql.sock
mysql.default_host =
mysql.default_user =
mysql.default_password =
mysql.connect_timeout = 60
mysql.trace_mode = Off

[MySQLi]

mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket = /var/mysql/mysql.sock
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off

[mysqlnd]

mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off

[OCI8]

[PostgresSQL]

pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0

[Sybase-CT]

sybct.allow_persistent = On
sybct.max_persistent = -1
sybct.max_links = -1
sybct.min_server_severity = 10
sybct.min_client_severity = 10

[bcmath]

bcmath.scale = 0

[browscap]

[Session]

session.save_handler = files
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.bug_compat_42 = Off
session.bug_compat_warn = Off
session.referer_check =
session.entropy_length = 0
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"

[MSSQL]

mssql.allow_persistent = On
mssql.max_persistent = -1
mssql.max_links = -1
mssql.min_error_severity = 10
mssql.min_message_severity = 10
mssql.compatability_mode = Off
mssql.secure_connection = Off

[Assertion]

[COM]

[mbstring]

[gd]

[exif]

[Tidy]

tidy.clean_output = Off

[soap]

soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5

[sysvshm]

[ldap]

ldap.max_links = -1

[mcrypt]

[dba]

[xdebug]
zend_extension="/usr/local/Cellar/php53-xdebug/2.2.1/xdebug.so"
xdebug.idekey="macgdbp"
xdebug.remote_enable=1 
xdebug.remote_handler=dbgp 
xdebug.remote_mode=req 
xdebug.remote_host=127.0.0.1 
xdebug.remote_port=9000 
xdebug.profiler_append=1 
xdebug.profiler_enable=1
xdebug.profiler_enable_trigger=1 
xdebug.profiler_output_name = cachegrind.out.%s 
xdebug.profiler_output_dir=/tmp/

Install MySQL

You can install MySQL on your local dev system as well.

brew install mysql

setup daemon

mkdir -p ~/Library/LaunchAgents && cp /usr/local/Cellar/mysql/5.5.20/homebrew.mxcl.mysql.plist ~/Library/LaunchAgents/ && launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

Set up databases to run as your user account

unset TMPDIR && mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp

####start mysql

mysql.server start

secure mysql

/usr/local/Cellar/mysql/5.5.20/bin/mysql_secure_installation

Restart apache

sudo apachectl graceful
@kanduvisla

This comment has been minimized.

Copy link

commented Jul 19, 2013

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.