Configuring macOS For Software Development
So you got yourself a new machine and configuring macOS for software development is presenting a bit of a challenge? Perhaps looking back at your old machine you wish it had been a bit cleaner setup? Well I sure do. This post will be a living post where I keep adding up the tips and tricks on macOS for a software developer. We’re going to be starting from a clean MacBook Pro 2016 with macOS Sierra 10.12.4.
UPDATE Nov 24, 2017: Updated for High Sierra 10.13.4, scroll to the bottom!
Basic Software That is Handy
I’ll first get a bunch of productivity software installed including:
- Chrome and/or Firefox Developer Edition
- Collab tools – Skype, Slack, etc.
- Sublime Text 3
- XCode and XCode command line tools – now I have git! Even if you are not developing iOS or macOS apps install it.
- Box.com – simple and easy file synch from one machine to another (dropbox.com is another option).
Configuring macOS For Software Development – Configuration Basics
Using macOS for software development requires editing environment settings (PATH and stuff like that ). They are set by editing the .bash_profile file in your user’s home directory. There are lots of ways to edit this file, but from a terminal using nano is the simplest thing to do.
Other macOS configuration items I like to have:
- Put the screen lock back on the menu bar so it is easy to lock your screen when you step away for coffee.
- Go into Keychain Access and then get into the Preferences to enable the lock icon.
- Go into Security and Privacy if you want to add a custom lock message.
- Add a custom login screen image by dropping an image into /Library/Caches if you like
- The image must match your screen’s resolution exactly
Customizing the Menu Bar
The menu bar looks to be a great productivity enhancement. The settings are in the keyboard preference control panel. Open up the panel and then literally drag icons from the panel and off-screen to the bar. The pointer will locate and light up on the bar, just keep dragging until you see it. Do the opposite to remove a button. If you get stuck try here: https://macperformanceguide.com/blog/2016/20161118_2304-2016MacBookPro-touchbar-Siri.html
Configuring macOS For Software Development – Tools
Homebrew will be the main configuration/dependency manager that I will use to configure macOS for software development. NPM will have to be used for Node.JS stuff, but I’ve learned that whenever possible using Homebrew is the best way to keep things simple. This is particularly true for anything you’ll be using from the command line and anything that will be running as a service, server, or part of a web development framework.
I’m also generally going to say that you really should not use any of the developer tools that ship with macOS for software development. PHP, Python, and Java to name a few. These should all be replaced with clean builds using Homebrew (or another package manager). Why? Because Apple tends to mess with them and definitely will update them with macOS updates so anything you do to customize them can get wiped out. Better to just install clean versions outside of Apple’s reach.
Don’t forget that “which” is your friend. If something isn’t working right, maybe you’re calling the wrong binary. To see which python you are using “which python” will tell you the location of the binary. Homebrew will symlink them to /usr/local/bin/ so if you get something other than that, then you’ll need to check/repeat your brew install.
- To install homebrew, use this command:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Make sure it works by running “brew doctor”
- Install Node.JS and NPM with hombrew (“brew install node”)
export PATH="/usr/local/bin:$PATH"Make sure it works by installing something like express. Use the -g option for express.
- Its a good idea to set all the “names” for your machine to the same thing or you can have odd problems:
scutil –set ComputerName “some name”
scutil –set LocalHostName “some name”
scutil –set HostName “some name”
- Install Java and JDK (Provided this gist still is around at the time of reading, otherwise…)
You can see my various posts on Java, but they are always changing. Currently this will do the trick:
- brew cask install java
- Then edit your .bash_profile to include Java home: export JAVA_HOME=$(/usr/libexec/java_home)
- SSH Keys – add them to github and/or bitbucket.
- Create new ones using instructions here.
Copy to the clipboard with: pbcopy < ~/.ssh/id_rsa.pub
Add it to your local agent so you don’t have to type the passphrase everytime: ssh-add ~/.ssh/id_rsa
- Move Your Existing SSH Keys From a Current MBP (optional)
- Easiest way is to cp ~/.ssh/id_rsa* /Users/yourHome/keys
- Zip them and either move via box.com or a USB stick to the same place on the new machine
- If you are using multiple key sizes don’t forget to also grab the config file that tells your machine when to use which key
- Create new ones using instructions here.
- Check Apache httpd
- You can use the default or install a clean apache with brew. Highly recommend installing httpd with Homebrew
- Use: brew install httpd
- You can determine where the httpd.conf file is with this command: apachectl -t -D DUMP_INCLUDES
- Ensure that the PHP mime type is in the httpd.conf file
- AddType application/x-httpd-php .phtml .pwml .php5 .php4 .php3 .php2 .php .inc .htm .html
- You can use the default or install a clean apache with brew. Highly recommend installing httpd with Homebrew
- Update Apache httpd to point to a webroot in your home directory
- You will need to update permissions so that _www can access and execute files.
- macOS Sierra only! See below for High Sierra. Add self-signed certificates to Apache httpd for local development (NOT PRODUCTION!)
- These instructions assume a homebrew based installation where configuration files are stored in /usr/local/etc/apache2/2.4 – cd to this directory and create a folder there called “ssl”
- Execute teh following command to generate some keys:
sudo openssl genrsa -out /usr/local/etc/apache2/2.4/server.key 2048 sudo openssl genrsa -out /usr/local/etc/apache2/2.4/ssl/localhost.key 2048 sudo openssl rsa -in /usr/local/etc/apache2/2.4/localhost.key -out /usr/local/etc/apache2/2.4/ssl/localhost.key.rsa
- Create a localhost.conf file in the ssl directory and add the following to it:
[req] default_bits = 1024 distinguished_name = req_distinguished_name req_extensions = v3_req [req_distinguished_name] [v3_req] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = localhost DNS.2 = *.localhost
- Then you will need to execute the following commands to create certificate requests:
sudo openssl req -new -key /usr/local/etc/apache2/2.4/server.key -subj "/C=/ST=/L=/O=/CN=/emailAddress=/" -out /usr/local/etc/apache2/2.4/server.csr sudo openssl req -new -key /etc/apache2/ssl/localhost.key.rsa -subj "/C=/ST=/L=/O=/CN=localhost/" -out /usr/local/etc/apache2/2.4/ssl/localhost.csr -config /usr/local/etc/apache2/2.4/ssl/localhost.conf
- In the above commands you’ll need to replace the following with the actual values for you.
C=eq. Country: The two-letter ISO abbreviation for your country.
ST=eq. State or Province: The state or province where your organization is legally located.
L=eq. City or Locality: The city where your organization is legally located.
O=eq. Organization: he exact legal name of your organization.
CN=eq. Common Name: The fully qualified domain name for your web server
- Now use the certificate requests to sign your SSL certificates:
sudo openssl x509 -req -days 365 -in /usr/local/etc/apache2/2.4/server.csr -signkey /usr/local/etc/apache2/2.4/server.key -out /usr/local/etc/apache2/2.4/server.crt sudo openssl x509 -req -extensions v3_req -days 365 -in /usr/local/etc/apache2/2.4/ssl/localhost.csr -signkey /usr/local/etc/apache2/2.4/ssl/localhost.key.rsa -out /usr/local/etc/apache2/2.4/ssl/localhost.crt -extfile /usr/local/etc/apache2/2.4/ssl/localhost.conf
- Add the certificate to the keychain:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /usr/local/etc/apache2/2.4/ssl/localhost.crt
- Next enable the following modules in the main apache configuration file:
LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so LoadModule ssl_module libexec/apache2/mod_ssl.so
- Enable SSL configurations in the main conf file removing the “#” from the line
- Finally, configure a virtual host in the httpd-vhosts.conf file like this:
<VirtualHost *:443> ServerName localhost DocumentRoot "/Library/WebServer/Documents" SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile /usr/local/etc/apache2/2.4/ssl/localhost.crt SSLCertificateKeyFile /usr/local/etc/apache2/2.4/ssl/localhost.key <Directory "/Library/WebServer/Documents"> Options Indexes FollowSymLinks AllowOverride All Order allow,deny Allow from all Require all granted </Directory> </VirtualHost>
- Restart apache and you should be able to load up https://localhost
- You will get browser warnings because this is a self-signed cert, but you can over-ride that.
- Kudos to Nicholas Rollier for all of this! I only put it here in case his post “disappears” from the interwebs. I converted his stuff to a brew apache and tested it on macOS Sierra. Works great!
- Install MySQL
- You can install it with brew or from the download. I did use the binary installers for both MySQL and the Workbench.Why did I break my rule? Installation of the GUI Workbench software seemed easier by just downloading it. Its not updated very often and since there are full GUI installers that are pretty reliable I went this way. Also – unlike Java, you don’t need to access this one from the command line so you do not have the trouble as with Java installers and conflicts with which Java you are trying to execute.
- Install PHP
- brew tap homebrew/dupes
- brew tap homebrew/versions
- brew tap homebrew/homebrew-php
- Install php and a new apache httpd: brew install php71 –with-httpd24
- Or just php and then configure it with the apple installed apache: brew install php71
- You will need to update the php shared object location in http.conf
- Hombrew should update the conf files correctly. Check the httpd.conf file to make sure the Load Module command for PHP is correct. The config file should be in /usr/local/etc/apache.
- Make sure there is a php type: AddType application/x-httpd-php .php in the mime_module section
- Android Studio (Canary is here. Stable is here.) is great for Android development and can be installed with the binary installer. Pretty self explanatory for updating it. There’s an internal SDK manager you can find with this button for updating Android SDK materials —->
- PHPStorm (PHP IDE) and IntelliJ (Java IDE) – pretty straightforward binary installers from Jetbrains.
- If you need to work with Tomcat:
- Confirm the right JRE is working from terminal
- Install with homebrew: brew install tomcat
- Update the config file located in /usr/local/Cellar/tomcat/[version]/libexec/conf/tomcat-users.xml to contain a user with privs to the admin gui
<user username=”admin” password=”a_password” roles=”tomcat,manager-gui”/>
- Optionally add the bin to your .bash_profile
- start it up with /usr/local/Cellar/tomcat/[version]/bin/catalina run
- I mentioned above using the git installed with XCode, for more git tips see my post here.
- If you need to work with Node.JS:
- install Node with brew: brew install node
- Then you can install packages, use -g to globally install key things like express and bower
Configuring macOS For Software Development – Keeping the Machine Updated
Regular maintenance is the key to keeping your machine in good shape.
Usually Apple will mess around with XCode when it updates macOS so its a good idea to run this command prior to updating with homebrew:
This command checks to see if the command line tools are installed and working. If you get a homebrew error like this: configure: error: Cannot find libz, then you need to run the command above.
Maintain all your brew installed stuff with:
Its good to visit the doctor so be sure to run that every once in a while. That third command will upgrade everything you’ve installed. That can take a while. Specify a package name to just upgrade one thing.
After updating PHP always make sure the brew script correctly updated httpd.conf to the new binary.
Maintain Node.js packages with:
npm update -g or npm update in a directory with a packages.json file.
The other thing that can help quite a bit is to prune things you are not using. If you are no longer working with a framework then remove it from your machine. This also includes code – I tend to look at lots of stuff and build up a lot of old projects that I don’t really need. Keeping down the clutter, just like keeping your basement clean, can really help out in times of trouble. This is another great use of box.com or dropbox.com (insert your tool of choice) – move thing you aren’t using there and get them off your local machine.
macOS High Sierra Updates (11/24/2017)
There are a number of changes required for macOS 10.13.1. Sigh…things change. One change that I’ve noticed is that case sensitivity on paths in configuration files seems to be enforced now. “/Users” and “/users” was interpreted the same, but now in apache configuration files you will get 403 errors because the path is not found for “/users”.
With Apache httpd I found that the best approach was to completely remove it. Save your configuration directory /usr/local/etc/apache/2.4 however when you reinstall you will notice that the location will change anyway. To remove it use this command:
brew uninstall –ignore-dependencies httpd24
Then reinstall with:
brew install httpd24 or with brew install httpd
I suggest that you do not copy your old configuration files to the new location: /usr/local/etc/httpd, instead go into the new files and make all the edits above. I’ve kept my document root at /Users/myId/www, but make sure you have a capital “U” as this now seems to be case sensitive.
The new brew httpd configuration runs on 8080 and 8443 by default. Hate that…set them back to the standard ports. The goal of 8080 was to avoid using sudo to start/stop it, but I still get permission errors with write access to log files. Not worth it. Use 80/443.
The SSL configuration above is pretty complicated. I came across this post, which greatly simplifies the steps. It seems to work, but again be careful of case sensitivity. I’ve put the steps here because these super awesome pages always seem to disappear. This is not for production servers!
Changes to httpd.conf, unrem these lines:
- LoadModule socache_shmcb_module lib modules/mod_socache_shmcb.so
- LoadModule ssl_module lib modules/mod_ssl.so
- Include local httpd httpd-ssl.conf
Next edit your httpd-ssl.conf to change the Listen port to 443. Find the virtual host block, change the 8443 to just 443 and rem out the DocumentRoot and ServerName lines.
Now edit httpd-vhosts.conf:
- Rem out or deleted the samples (I rem’d out)
Add a virtualhost configuration block
<VirtualHost *:443> DocumentRoot "/Users/your_user/Sites" ServerName localhost SSLEngine on SSLCertificateFile "/usr/local/etc/httpd/server.crt" SSLCertificateKeyFile "/usr/local/etc/httpd/server.key" </VirtualHost>
Rember the paths are case sensitive!
Switch directories to /usr/local/etc/httpd and run this command:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt
Now restart apache and browse to the site. Should be good to go! If not then tail your logs:
tail -f /usr/local/var/log/httpd/error_log
macOS High Sierra Updates (04/8/2018)
It seems that each update brings some twists. In this update it seems that a few kernel settings get changed that impact Node.JS and React.JS development. The impact: npm and yarn will no longer work. To fix things you will need to run these two commands from terminal:
sudo sysctl -w kern.maxfiles=5242880
sudo sysctl -w kern.maxfilesperproc=524288
Hopefully this has helped you configure macOS for software development. I’ll be updating this regularly as I learn new things all the time that I do not want to forget. I’ll post change log here at the end.