OSX Fresh Install Semi Automatic Setup
Getting upto speed effortlessly.
Xcode command line tools
We need the xcode command line tools to compile stuff. So
$ xcode-select --install
Accept the dialog box to install the tools. You may download XCode from the App Store if needed.
oh-my-zsh
Zsh has some nifty features over bash, particularly the recursive globbing.
$ curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh
Homebrew
It’s nice to have a package manager do the work.
$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
Now that homebrew is up and running, let’s get some tools and apps. The below linked gist can be downloaded as a shell script and executed. While you’re at it, you can add your own tools and apps to the list.
#!/bin/sh | |
# Scroll to bottom of this file to comment out sections that you don't need. | |
# This script exits whenever a particular tool / app / driver installation gives an error. | |
# Do watch out for apps that need you to open the installer from Homebrew's cache i.e Cellar. Ex: Little Snitch | |
######################## | |
# Script Functions - Will be called later in the script | |
######################## | |
function separator() { | |
printf %"$(tput cols)"s |tr " " "=" | |
printf "\n" | |
} | |
function getc() { | |
local save_state | |
save_state="$(/bin/stty -g)" | |
/bin/stty raw -echo | |
IFS='' read -r -n 1 -d '' "$@" | |
/bin/stty "${save_state}" | |
} | |
function ring_bell() { | |
# Use the shell's audible bell. | |
if [[ -t 1 ]] | |
then | |
printf "\a" | |
fi | |
} | |
function wait_for_user() { | |
local c | |
echo | |
echo "Press ${tty_bold}RETURN${tty_reset}/${tty_bold}ENTER${tty_reset} to continue or any other key to abort:" | |
getc c | |
# we test for \r and \n because some stuff does \r instead | |
if ! [[ "${c}" == $'\r' || "${c}" == $'\n' ]] | |
then | |
exit 1 | |
fi | |
} | |
function install_command_line_tools() { | |
if ! [ $(xcode-select -p) ]; then | |
echo "Xcode Command Line Tools is not installed, installing now ..." | |
xcode-select --install | |
echo "Press any key when the installation has completed." | |
ring_bell | |
getc | |
sudo xcode-select --switch /Library/Developer/CommandLineTools | |
#sudo xcodebuild -license accept | |
else | |
echo "Xcode Command Line Tools is already installed, skipping ..." | |
fi | |
separator | |
sleep 1 | |
} | |
function install_ohmyzsh() { | |
if [ -d ~/.oh-my-zsh ]; then | |
echo "oh-my-zsh is already installed, skipping ..." | |
else | |
echo "oh-my-zsh is not installed, installing now ..." | |
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" | |
fi | |
separator | |
sleep 1 | |
} | |
function install_rosetta2() { | |
if [[ "$(sysctl -n machdep.cpu.brand_string)" == *'Apple'* ]]; then | |
if arch -x86_64 /usr/bin/true 2> /dev/null; then | |
echo "Rosetta 2 is already installed, skipping ..." | |
else | |
echo "Rosetta 2 is not installed, installing now ..." | |
softwareupdate --install-rosetta --agree-to-license | |
fi | |
fi | |
separator | |
sleep 1 | |
} | |
function install_homebrew() { | |
if ! command -v brew &> /dev/null; then | |
echo "Homebrew is not installed, installing now ..." | |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
echo "Updating .zprofile ..." | |
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> $HOME/.zprofile | |
eval "$(/opt/homebrew/bin/brew shellenv)" | |
else | |
echo "Homebrew is already installed, skipping ..." | |
fi | |
separator | |
sleep 1 | |
} | |
function brew_tap_repositories() { | |
echo "Tapping Homebrew Repositories..." | |
for repo in "${REPOS[@]}" | |
do | |
brew tap $repo | |
done | |
separator | |
sleep 1 | |
} | |
function install_mac_appstore_apps() { | |
# Install "mas" from Homebrew | |
if ! command -v mas &> /dev/null; then | |
brew install mas | |
fi | |
echo "Please login with your Apple ID to install apps from the App Store." | |
echo "Choose Install once you've logged in:" | |
ring_bell | |
select option in "Install" "Skip"; do | |
case $option in | |
"Install" ) | |
echo "Installing apps from App Store..." | |
mas install ${MASAPPS[@]} | |
echo "Updating existing apps from App Store..." | |
mas upgrade | |
separator | |
sleep 1 | |
return 1;; | |
"Skip" ) | |
echo "Skipping apps from App Store." | |
separator | |
sleep 1 | |
return 1;; | |
esac | |
done | |
} | |
function install_tools() { | |
echo "Installing Tools..." | |
for tool in "${TOOLS[@]}" | |
do | |
brew install "$tool" | |
if [ $? -ne 0 ] | |
then | |
echo "\xE2\x9C\x98 Error encountered with installing: $tool" | |
fi | |
done | |
separator | |
} | |
function install_apps() { | |
echo "Installing Apps..." | |
for app in "${APPS[@]}" | |
do | |
brew install "$app" | |
if [ $? -ne 0 ] | |
then | |
echo "\xE2\x9C\x98 Error encountered with installing: $app" | |
fi | |
done | |
separator | |
} | |
function install_device_apps() { | |
echo "Installing Device Apps..." | |
for app in "${DEVICE_APPS[@]}" | |
do | |
brew install "$app" | |
if [ $? -ne 0 ] | |
then | |
echo "\xE2\x9C\x98 Error encountered with installing: $app" | |
fi | |
done | |
separator | |
} | |
function install_fonts() { | |
echo "Installing Fonts..." | |
for font in "${FONTS[@]}" | |
do | |
brew install "$font" | |
if [ $? -ne 0 ] | |
then | |
echo "\xE2\x9C\x98 Error encountered with installing: $font" | |
fi | |
done | |
separator | |
} | |
######################## | |
# Homebrew repositories | |
######################## | |
REPOS=( | |
#homebrew/cask-fonts | |
#homebrew/cask-versions | |
#varunyellina/homebrew-casks-old | |
) | |
######################## | |
# Tools that can be installed with Homebrew | |
######################## | |
TOOLS=( | |
ack | |
curl | |
git | |
htop | |
psgrep | |
ssh-copy-id | |
wget | |
imagemagick | |
) | |
######################## | |
# Apps from Homebrew Cask | |
######################## | |
APPS=( | |
## communication | |
#mailmate | |
#thunderbird | |
postbox | |
protonmail-bridge | |
telegram | |
slack | |
#notion-calendar | |
## design | |
affinity-designer | |
affinity-photo | |
affinity-publisher | |
figma | |
#sketch | |
#rive | |
imageoptim | |
## browsers & tools | |
arc | |
firefox | |
google-chrome | |
#transmission | |
#browserosaurus | |
#velja - from Mac app store | |
resilio-sync | |
## documents handling & storage | |
adobe-acrobat-reader | |
microsoft-office | |
pdf-expert | |
google-drive | |
proton-drive | |
#dropbox | |
#arq | |
## security tools | |
protonvpn | |
#blockblock | |
#knockknock | |
#little-snitch | |
#oversight | |
#do-not-disturb | |
## tools & utilities | |
appcleaner | |
#airfoil | |
#alfred | |
android-file-transfer | |
#anvil | |
bartender | |
#caffeine | |
#carbon-copy-cloner | |
#keka | |
#lulu | |
raycast | |
#rectangle | |
vlc | |
## dev tools | |
android-platform-tools | |
android-studio | |
#docker | |
fork | |
iterm2 | |
#kaleidoscope | |
sublime-text | |
sublime-merge | |
visual-studio-code | |
#postman | |
## virtualisation | |
#onyx | |
#utm | |
vmware-fusion | |
## Quicklook plugins | |
#suspicious-package | |
#quicklookase | |
#qlvideo | |
#qlimagesize | |
#quicklook-json | |
#qlmarkdown | |
#qlstephen | |
) | |
######################## | |
# Apps to modify Device functionality | |
######################## | |
DEVICE_APPS=( | |
monitorcontrol | |
scroll-reverser | |
logitech-g-hub | |
logitech-camera-settings | |
#logitech-options | |
) | |
######################## | |
# Apps from App Store | |
######################## | |
MASAPPS=( | |
## Apps | |
1352778147 # Bitwarden | |
#1166066070 # Bumpr | |
#1444383602 # Goodnotes 5 | |
#1233368267 # Linea Link | |
#441258766 # Magnet | |
1464122853 # Nextdns | |
445189367 # Popclip | |
1607635845 # Velja | |
#497799835 # Xcode | |
889428659 # xScope | |
) | |
######################## | |
# Fonts | |
######################## | |
FONTS=( | |
font-monoid | |
font-source-code-pro | |
font-menlo-for-powerline | |
font-fira-code | |
) | |
######################## | |
# You can enable and disable some sections of this script here. | |
# Do note that some are dependant on the others for proper installation. | |
######################## | |
# Install Xcode Command Line Tools. | |
install_command_line_tools | |
# Install Rosetta 2 on Apple Silicon Macs to run x86 apps. | |
install_rosetta2 | |
# Install Ohmyzsh shell prompt | |
install_ohmyzsh | |
# Install Homebrew | |
install_homebrew | |
# Tap various Repositories for additional tools and casks. These are required for some of the following steps. | |
#brew_tap_repositories | |
# Install apps from App Store | |
install_mac_appstore_apps | |
# Install Tools | |
install_tools | |
# Install apps | |
install_apps | |
# Install Device apps | |
install_device_apps | |
# Install Fonts | |
install_fonts |
Git setup
$ ssh-keygen -t rsa -C "varun@yellina.io"
copy ssh key to github.com
$ ssh-add ~/.ssh/id_rsa
copy ssh key to clipboard, add it to your ssh keys on github and bitbucket.
$ pbcopy < ~/.ssh/id_rsa.pub
test connection
$ ssh -T git@github.com
set git config values
$ git config --global user.name "Varun Yellina"
$ git config --global user.email "varun@yellina.io"
$ git config --global github.user varunyellina
$ git config --global github.token your_token_here
$ git config --global core.editor "subl -w"
$ git config --global color.ui true
Node
Node and npm can be installed with homebrew. Node now comes with npm.
$ brew install node
Fix permissions to allow installation without sudo.
$ sudo chown -R `whoami` /usr/local/lib/node_modules
$ sudo chown -R `whoami` ~/.npm
Install grunt and bower
$ npm install -g grunt-cli
$ npm install -g bower
Nginx
Install nginx
$ brew install nginx
Next change nginx port to default http port 80
$ nano /usr/local/etc/nginx/nginx.conf
from
server {
listen 8080;
to
server {
listen 80;
Now let’s get it running
$ sudo cp -v /usr/local/opt/nginx/*.plist /Library/LaunchDaemons/
$ sudo chown root:wheel /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
$ sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
DNSMasq
$ brew install dnsmasq
$ mkdir -p /usr/local/etc/
$ echo "address=/dev/127.0.0.1" >> /usr/local/etc/dnsmasq.conf
$ echo "listen-address=127.0.0.1" >> /usr/local/etc/dnsmasq.conf
$ sudo cp -fv /usr/local/opt/dnsmasq/*.plist /Library/LaunchDaemons
$ sudo launchctl load -w "/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist"
$ sudo -s
$ sudo mkdir -p /etc/resolver
$ sudo echo 'nameserver 127.0.0.1' > /etc/resolver/dev
$ dscacheutil -flushcache
Dynamic virtual hosts
Now that we have installed dnsmasq
to resolve domains ending with .dev
to point to 127.0.0.1
, let’s configure nginx to dynamically configure virtual hosts.
I configured my nginx to use /Users/varun/Sites
folder as webroot.
Now let us say I have my websites in this order
~/Sites
~/Sites/portfolio
~/Sites/survey
~/Sites/portal
We have to create a separate folder for all our sites.
$ mkdir -p /usr/local/etc/nginx/sites-available/
$ mkdir -p /usr/local/etc/nginx/sites-enabled/
Since that is done, we have to tell nginx about the locations. Edit the nginx.conf and include the follwing line in the http {} section
include /usr/local/etc/nginx/sites-enabled/*;
Now, let’s put in a default config. I’ve a gist which we’ll make some changes to.
$ curl -L https://gist.githubusercontent.com/varunyellina/43bd692cd9eb66076332/raw/default | sed -e "s/varunyellina/$USER/" > /usr/local/etc/nginx/sites-available/default
Next, we’ll put in a config that’ll resolve all .dev domains to the respective folders in /Users/yourusername/Sites folder.
$ curl -L https://gist.githubusercontent.com/varunyellina/44440f889479cb8d8628/raw/localsite | sed -e "s/varunyellina/$USER/" > /usr/local/etc/nginx/sites-available/localsite
We now enable the config by using a symlink.
$ ln -s /usr/local/etc/nginx/sites-available/localsite /usr/local/etc/nginx/sites-enabled/localsite
Now just restart your nginx service, and you are good to go.
$ sudo nginx -s stop
$ sudo nginx
Accessing your local website is automatic now.
~/Sites | -- | localhost |
~/Sites/portfolio | -- | portfolio.dev |
~/Sites/survey | -- | survey.dev |
~/Sites/portal | -- | portal.dev |
MariaDB
brew install mariadb Install databases
$ unset TMPDIR
$ mysql_install_db --user=`whoami` --basedir="$(brew --prefix mariadb)" --datadir=/usr/local/var/mysql --tmpdir=/tmp
Now start mysql server
$ mysql.server start
Change root password and remove test databases. The default password is either root or there is no password, just hit return.
$ /usr/local/opt/mariadb/bin/mysql_secure_installation
Start mariadb on boot
$ ln -sfv /usr/local/opt/mariadb/*.plist ~/Library/LaunchAgents
PHP
$ brew upgrade && \
$ brew tap homebrew/dupes && \
$ brew tap homebrew/versions && \
$ brew tap homebrew/homebrew-php && \
$ brew install freetype jpeg libpng gd zlib && \
$ brew install --with-fpm --with-mysql php56
$ ln -sfv /usr/local/opt/php56/*.plist ~/Library/LaunchAgents
$ mkdir -p /usr/local/etc/nginx/conf.d/
Add php-fpm configuration to the file at /usr/local/etc/nginx/conf.d/php-fpm
1
2
3
4
5
6
7
8
9
10
11
12
location ~ \.php$ {
try_files $uri $uri/ /index.php?$args ;
index index.html index.htm index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_intercept_errors on;
include fastcgi_params;
}
Load php-fpm
$ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.php56.plist