Setting up a new (OS X) development machine: Part 3 - Dotfiles and custom SSH config

Posted on May 28, 2014 | By Matt Stauffer

Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

So far we've gotten our core files synced, our terminal beautiful and customized, and our global package managers installed and running many of our command-line and GUI apps. But we've left a littered heap of configuration files laying around and there's a lot more customization we haven't even touched.


What are Dotfiles?

If you're not familiar with the concept of dotfiles, check out Github's dotfiles page to learn more about them. Essentially, when someone says "dotfiles" they mean maintaining your command-line preferences in a Git repository (sort of like how I use Dropbox to manage my preference files for TextExpander, etc.) that you install on every computer.

The name dotfiles refers to the fact that most of the files that perform this sort of configuration start with a dot. The Zsh configuration file, for example, is .zshrc. The SSH configuration folder is .ssh. And on. So the concept of "dotfiles" just means "versioning your configuration files."

Your dotfiles will help you create powerful and consistent shell shortcuts and functions, settings for your editors, color coding and layouts for your shell, preferences and authentication for ssh and mysql and other protocols, and more.

I recently forked my old Bash dotfiles as a ZSH dotfiles project, but they're still a bit of a work in progress, so user beware.

NOTE: There are a lot of dotfiles floating around on the Internet. Zack Holman has a well-known collection, as do Paul Irish and Matthias Bynens (all three of these are very Internet-trustworthy, for what that's worth). Be careful installing dotfiles from a source you don't trust. Blindly running a dotfiles installer, or even just adding particular config files to your machine, can add some un-safe settings if you don't understand what you're doing.

Common dotfiles

  • .zhsrc, .bashrc, .bash_profile, .bash_prompt, etc: These are the configuration files for your shell. From here you can set up aliases (shortcuts), functions, environment variables, and even include other configuration files.
  • .curlrc, .gvimrc, .vimrc, .wgetrc, etc.: These are configuration files for particular command-line programs. You might be setting font information, default connection information, and more.
  • .gitattributes, .gitconfig: Global git configuration
  • .screenrc, .inputrc, .hushlogin: These are files configuring specific aspects of your connection to the shell and/or the terminal.

Installing dotfiles

Depending on the dotfiles repository you're using (or if you're just managing it on your own), there are many different options for configuring and managing your dotfiles' installation process.

Any dotfiles repo will expect you to clone the dotfiles repo to your local computer (I do mine at ~/.dotfiles) and then use any method to copy or link those files down into your root directory.

Paul Irish/Mathias Bynens' dotfiles (which mine are branched from) use a script that copies the dotfiles from your dotfiles repo. I actually think this isn't a great idea, because it makes making and syncing changes with the repo a pain. I much prefer Zack Holman's method, which symlinks the files instead, allowing you to git pull and watch your dotfiles instantly update.

You can also manually copy files from your dotfiles directory to your root, or you can use one of several dotfiles maintenance apps--I don't have any experience with them, but a friend whom I trust recommended rcm, so I'll probably be trying that out soon, too.

Tweaking your dotfiles after installation

No matter where you got your dotfiles from, they're not unchangeable rules. They're just suggestions. I suggest that if you get someone else's dotfiles repo, you start by reading through every file and understand what they're doing--and disabling anything you don't like.

If you want to make a change later, just go to your home directory and edit those files. If you want to save your changes, and you're working from someone else's repo, fork that repo and clone the forked version instead. That way you can make your changes, and (if you're symlinked, simply, and if you're not symlinked, with a wee bit of work) push your changes back up to your repo. Want to learn more? Check out Zack Holman's excellent post Dotfiles Are Meant to Be Forked.

Which to fork?

After talking up Zach Holman's dotfiles so much, I hope you'll consider checking them out. But--they weren't around when I really started digging into dotfiles, so I have my own, somewhat less modern set of dotfiles. I did update them a bit this week, but they're still based on copying instead of symlinking, etc. Check both out (Zack's | Mine) and pick those which you think are best. FYI, my next free weekend will be trying out Zack's, so mine might be on their way to the graveyard soon.


SSH config file

Another set of configurations that I don't want available through the public repo is my SSH config, where I store shortcuts, SSH usernames and URLs, and more. But, I do want it to sync across my devices. So I set it up in my Dropbox folder and then symlink that file into my ssh folder. For example:

$ touch ~/Dropbox/.ssh-config
$ ln -s ~/Dropbox/.ssh-config ~/.ssh/config

Now we have an ssh config file that lives in our dropbox directory and will be synced across all of our machines every time we make a change -- without relying on putting our SSH information publicly on Github.

Here's a snippet of what an SSH config file might look like:

# My Awesome Web Site
Host awesome
    User me_duh

# My Other Awesome Web Site
Host other
    User me_still

Now, I can just type the following and I'll be instantly SSH'ed in (after typing the password, if I haven't set up SSH key authentication):

$ ssh awesome

Done. No more remembering ip addresses, fumbling with command line switches for multiple SSH IDs, or even remembering your ssh usernames. There are many more features you can manage via your SSH config file, if you want--ports, tunneling, and more. Check out the ssh_config docs for more information.

SSH keygen

If you're not familiar with SSH Key authentication, you might be confused at how you could possibly authenticate with those web sites above without a password. Well, you could type your password every time. But there's a much faster way, if you're willing to do some leg work up front.

I don't have the space here to give a full intro, but here's a quick Github Guide to generating an SSH Key on your new machine. Or, if you're a pro:

$ ssh-keygen -t rsa -C ''
  [ follow prompts ]
$ pbcopy < ~/.ssh/

Now you have the public version of the key copied to your clipboard, ready to add to Github, Forge, or even upload to your remote site. Again, there's not enough space to do a full intro here to remote SSH key authentication, but here's the short walkthrough to the super-hacky version if you're already familiar:

$ pbcopy < ~/.ssh/
$ ssh
  [ type password ]
$ cd ~/.ssh
$ vim authorized_keys
  [ paste your key at the end of the file]
  [ save file and quit ]

If you're not familiar with it, though, please don't just follow the above instructions. They're very hacky, and assume you know what to do if they files and folders aren't there, you know how to use Vim/emacs/pico, and a lot more. If you're new to that world, I suggest you check out other tutorials online to get a better grasp on that. I've never found a tutorial I'm 100% satisfied with, but here are a few: (Slicehost nixCraft TutsPlus)

There's a utility named ssh-copy-id that aims to simplify this process, but I've had mixed results with it. You can also do it with scp, but you need to know what you're doing so you don't potentially overwrite someone else's keys. Are you a guru on this? Hit me up on Twitter and I'll update this section with any tips you have to offer.

NOTE: If you're using Forge, you don't have to follow this step about authorized_keys. Just pbcopy your and paste it into the SSH keys box in Forge. That's it!


I could write an entire blog series about all of the things that my and Zack's dotfiles do. Coloring your grep output, boosting your ls commands, adding plugins to vim, optimizing your curl and wget, adding convenient functions and methods for your day-to-day work in the terminal... But I'll leave that to you, dear reader, to explore and discover when you read the dotfiles before you install them. Right? Right.

My hope is, even if I haven't explained every piece of every dotfile, you'll come away from this blog post feeling excited and ready to try out versioning your dotfiles and maybe learning a bit from others'.

Do you have any tips about dotfiles or SSH config that I missed here? Do you think I should add another blog post to this series, or add to the existing posts? Hit me up on Twitter and let me know. Thanks, and I hope you've enjoyed! Check out my next (and, for now, final) post showing a stripped-down walkthrough my of my install process, without explanations.

Comments? I'm @stauffermatt on Twitter

Tags: development  •  dotfiles  •  osx  •  ssh