DEV Community

loading...

How do you manage your dotfiles across multiple and/or new developer machines?

Jonathan Carter
I build developer tools and services at Microsoft (currently Codespaces, Live Share, IntelliCode) and maintain some OSS projects (CodeTour, GistPad, CodeSwing, WikiLens)
・1 min read

Hey All! I’m curious to hear the gritty details about how you synchronize your dotfiles (e.g. .bash_profile, .gitconfig) between multiple dev machines (e.g. your desktop and laptop) and/or to help simplify setting up new machines (e.g. a shiny new MacBook 💻).

Do you store them in a public or private GitHub repo? DropBox? Somewhere else? Once cloned to the target machine, do you install the dotfiles...

  1. Manually (e.g. moving files around, running a series of commands)
  2. By running a custom shell script stored alongside your config files
  3. Using an automation tool, such as Ansible or Puppet
  4. Using a “dotfile manager” such as GNU Stow, Dotbot or Homesick

If you’ve already written a blog post about your setup, feel free to link it. Otherwise, I’d love to hear what has been working well for you, and any pro tips you can share. There are a ton of options here, and so I’m very interested to learn more about what folks are actually doing in practice 🙌

Discussion (35)

Collapse
avatarkaleb profile image
Kaleb M

I typically keep them all in the GitHub, luckily none of mine have any secrets or anything like that.

Collapse
lostintangent profile image
Jonathan Carter Author

After you clone the repo on to your machine, how to you install them (e.g. symlinking files, etc.)? Do you have something like an “install.sh” script in the repo that you run?

Collapse
avatarkaleb profile image
Kaleb M

That would be clutch! I typically just copy and paste if there are any updates, many changes outside of the base set ups are specific to the laptop for work vs personal !

Thread Thread
jmervine profile image
Joshua Mervine • Edited

Here’s my very personalize Makefile for installing which perhaps could be adapted.

github.com/jmervine/zshrc/blob/mas...

Which, when looking over just now for the first in quite a while, needs some clean up.

Thread Thread
easyaspython profile image
Dane Hillard

Hmmmm I like this enough that I might do it too. Right now I'm symlinking everything in a bash script which works well, but the uninstall would have to be manual at the moment. I like that make would kind of supervise all of that.

Collapse
easyaspython profile image
Dane Hillard

That's exactly what I do!

Thread Thread
lostintangent profile image
Jonathan Carter Author

Great, thanks for confirming 👍

Collapse
coreyja profile image
Corey Alexander

I put all my dotfiles that I want to share in a public repo that I host on Github

GitHub logo coreyja / dotfiles

My dotfile Repo

Coreyja's dotfiles

Screenshot of my shell prompt

Installation

Warning: If you want to give these dotfiles a try, you should first fork this repository, review the code, and remove things you don’t want or need. Don’t blindly use my settings unless you know what that entails. Use at your own risk!

Using Git and the bootstrap script

You can clone the repository wherever you want. (I like to keep it in ~/Projects/dotfiles, with ~/dotfiles as a symlink.) The bootstrapper script will pull in the latest version and copy the files to your home folder.

git clone https://github.com/mathiasbynens/dotfiles.git && cd dotfiles && source bootstrap.sh

To update, cd into your local dotfiles repository and then:

source bootstrap.sh

Alternatively, to update while avoiding the confirmation prompt:

set -- -f; source bootstrap.sh

Git-free install

To install these dotfiles without Git:

cd; curl -#L https://github.com/mathiasbynens/dotfiles/tarball/master | tar -xzv --strip-components 1 --exclude={README.md,bootstrap.sh,.osx,LICENSE-MIT.txt}

To update later on, just run…

I do something that I think is somewhat unconventional but I really like it! And that is keep my actual home directory under version control. To accomplish this my .gitignore starts with * so that it ignores everything. Then I go in an specifically include files like !file.txt.

This means I don't have to deal with any symlinks or scripts when I pull updates. I also can edit the actual 'live' files and then commit those same files, which makes sharing between machines painless! I've written a few blog posts about my dotfiles!

This second one discusses some recent change to my dotfiles around Homebrew 2

Collapse
lostintangent profile image
Jonathan Carter Author • Edited

It definitely seems like many of the “dot file managers” are simply working around the fact that folks don’t want to make their home directory a Git repo. Have you run into any downsides with this solution? It certainly seems really simple.

Collapse
coreyja profile image
Corey Alexander

Not any huge ones, but there are definitely some interesting side effects.

One if that I am always in a git repo now basically, so my bash indicator of if I'm in a git branch is slightly less meaningful
Two some tools (ex: ripgrep) use your .gitignore file as a generic ignore file when searching, so this needs to be worked around. I accomplish this my using something like rg --no-ignore --glob "!.git/*". I find I don't actually run into this too often, as usually I am running rg from within a different project directory, where it's local .gitignore is used so this isn't an issue.

Besides that everything works as expected! I've been doing it for a few years now and really enjoy the setup!

Collapse
bonfacekilz profile image
the_savage • Edited

I store everything in an org file which I can choose to encrypt using the :crypt: tag. This file can live anywhere(GitHub, Dropbox, drive, etc etc). The dotfiles are stored in source blocks from which I'll tangle to the relevant place in the file system. This approach works really well if you are a heavy emacsen user.

Collapse
lostintangent profile image
Jonathan Carter Author

As a non-Emacs user (apologies!), I’m not too familiar with org files. Any pointers that could help me understand this solution a bit better? I’m really intrigued 🤗

Collapse
lostintangent profile image
Jonathan Carter Author • Edited

For those that are interested, I found an old HackerNews thread, and Reddit Survey that have a ton of valuable perspectives. This article also provides a really nice explanation of the general practice that many people seem to be taking: store dotfiles in GitHub, and then install them via a simple script that symlinks files and runs any additional init logic.

Also, I’m porting some helpful links that folks have shared on Twitter:

  1. Managing Dotfiles with Stow
  2. Managing your dotfiles
  3. Dotfiles Home Configuration
Collapse
jmervine profile image
Joshua Mervine

I manage mine, as I’m sure many do, via a Github repo — as well as my vimrc. They both include make based installers for easy installation, as well as (very old) Dockerfiles for quick mucking container.

The dotfiles repo loads a .localrc to include things I don’t wish to share. Mostly very work specific aliases and functions.

Admittedly, I don’t push nearly often enough, nor do I clean up the files within with any kind of diligence.

Collapse
lostintangent profile image
Jonathan Carter Author

Very cool! I really like the “.localrc” idea. That seems like a great solution for keeping a public dotfiles repo for most of your settings, while being able to keep some things private 👍

Collapse
lucasqueiroz profile image
Lucas Queiroz

I currently store them in a secret gist, but I'm creating an install command, and storing it in a secret GitHub repo. It will basically download everything I need and setup all the files to keep my aliases, ZSH themes, Spotify theme (using Spicetify), etc

Collapse
lostintangent profile image
Jonathan Carter Author

Out of curiosity: why are you using a secret Gist? Are you storing secrets in there, that you wouldn’t want others to see?

Also, have you considered using a “dot file manager” such as YADM or Homeshick, as opposed to scripting your own solution?

Collapse
lucasqueiroz profile image
Lucas Queiroz

I don't have any secrets within the files, not sure why I keep it private... Better safe than sorry I guess?

I didn't know they existed, actually! I discovered with your post. I might still finish my own as it will also install all the softwares I need and apply themes/plugins (For example, it would download VSCode and apply my themes and plugins). I might consider using the dot file managers for the dot files and keeping my "install script" just for the things it can't do.

Collapse
cookrdan profile image
Dan

Just wanted to say thank you for the discussion topic. I am storing mine in Dropbox at the moment and I’m very new to bash and using dotfiles and etc. I have read many of the things here and I will try to refactor. I have been using bash’s source to include scripts (functions) and settings from a folder in Dropbox. I simply didn’t know of other ways and it’s great to see them now.

After reading several things here I may create a git repo and then I will likely just create symlinks for what I need (as well as a script to generate those symlinks on a fresh install).

Collapse
atyborska93 profile image
Angelika Tyborska

I keep my dotfiles in a Github repository, alongside with a list of things to set up manually. There is a script I copied from somebody's dotfiles repo that does the symlinks. If I update a dotfile on one machine, I just pull from the other. I also have a .bash_profile_priv file that I load from .bash_profile but do not commit, so that I can set there env variables and such that only make sense for one machine or are secrets.

I also keep an install script that installs various packages and apps via brew, and detailed instructions how to configure manually the system and certain apps to my liking.

Spending time on this repo paid off big time. I have re-installed the system more than 5 times now using this repo and I can't imagine not having it. I don't have to think much during the process, I just follow my list :).

Collapse
rpoirier profile image
Reese Poirier

Ohhhh, symlinks 🤦‍♀️ Of course!
Thanks for sharing. I also use github to manage my dotfiles and I've been thinking about how I wanted to manage syncing them without making my home folder a git repo. I was halfway through setting up some bash scripts with rsync, but symlinks are so much less effort and will work better.

Collapse
anortef profile image
Adrián Norte

I feel ashamed to say that I only care about my ohmyzsh dir and .zshrc file and store them on Dropbox (because of native Linux app) and symlink them whenever I start a new computer in order to have the same plugins and config across my laptops and workstations.

But I'm gonna check those solutions because that seems neat.

Collapse
nickjj profile image
Nick Janetakis • Edited

I just keep a dotfiles repo on GitHub and sync it / set it up with Ansible. It's nice because the same Ansible role works in WSL on Windows and a native Linux box.

Collapse
lostintangent profile image
Jonathan Carter Author

Is the Ansible role code in the same dotfiles repo? That way you can clone it and run Ansible on it?

Collapse
nickjj profile image
Nick Janetakis • Edited

Nope, right now that specific Ansible role isn't open source since it has very personalized information in it specific to my development environment but if it were to be released, it would be in its own separate repo as a dedicated dotfiles Ansible role.

Then you would configure the role to set up your dotfiles. At some point I may refactor it all to be a general role, but it's not a super high priority at the moment. It mainly just clones my dotfiles repo and sets up symlinks.

Currently I have that functionality along with some other things all smashed together in a custom role, which happens to do other things besides dotfiles but is related to setting up a new WSL / Linux development environment.

Collapse
brokkr profile image
Mads

A slight twist on the tried-and-true git-plus-symlinks: On the machines where I su to root, I wanted the same setup as for my normal user. I figured symlinking to the normal user's files was a bad idea and the other way around, I dunno, running git as root also seemed like a bad idea.

So I created a passwordless dotfile user who owns the files. Only root can switch to the user and the user itself has zero privileges. It's a bit more cumbersome (especially when making changes) but it has worked really well.

Collapse
geewiz profile image
Jochen Lillich

Hi Jonathan, here's my blog post on How I manage my dotfiles across hundreds of servers using git and rcm. Thanks for inspiring it!

Collapse
lostintangent profile image
Jonathan Carter Author

Thanks so much!

Collapse
davefollett profile image
Dave Follett • Edited

There is some good stuff in here, I've not tried any yet though.

Collapse
lostintangent profile image
Jonathan Carter Author

Ah nice! Thanks so much for sharing this. I searched past #discuss posts and totally missed this 🤗

Collapse
davefollett profile image
Dave Follett

No problem, I've got it permanently on my reading list so I can refer back to it. Post back here if you find an option that works well. I haven't had a chance to try any yet.

Collapse
jorinvo profile image
jorin

As mentioned by many others, it's pretty handy to simply store everything in a Git repo. It's easy to keep track of changes and it's easy to share things with your machines and also with others.
I also wrote about my setup to make it easy to keep my machines up to date and setup new ones.

Collapse
samrocksc profile image
Sam Clark

Hey there! As most folks are saying I'm the same way, I have a Github repo :)

It makes life a lot easier to just do incremental changes, and i've actually rolled back some stuff i didn't like before.

Collapse
dmfay profile image
Dian Fay

I use dotbot with mine.