Painless dotfile management

Download, version, and publish dotfiles using IPNS on a private IPFS network

August 24, 2018IPFS, IPNS

I am now publishing my dotfiles [1] at

After explaining the simple and perhaps obvious benefits, this post details a unique approach to publishing using a private IPFS network [2], and IPNS.

Downloading dotfiles

$ wget

Setting up a remote server and wish you had your .vimrc? No problem.

Importing and exporting dotfiles

$ ~/.dotfiles/dfctl import # Import working dotfiles from .dotfiles
$ ~/.dotfiles/dfctl export # Export working dotfiles into .dotfiles

Use your computer like you normally would, and run ./dfctl import and ./dfctl export as needed. Keeping them all in one folder makes source control significantly easier.

Details in the source code.

Publishing dotfiles

$ declare -a public_files=("README" ".bashrc" ".flake8" ".taskrc"
    ".tmux.conf" ".vimrc" ".zshrc")
$ ipfs add -Qrw ${public_files[@]} | ipfs name publish --key=dotfiles;

The above code adds your dotfiles and represents them as an IPFS hash [3], and then publishes that hash by pointing a consistent IPNS name at it.

The Code Explained

First we use declare to define an array of public_files we want to publish.

Then we use ipfs add to collect the files into a folder and add that folder to IPFS. The flag -r means recursively add subfolders, and -w means to wrap all the files in a root directory [4] before adding it all to IPFS.-Q is for quiet which means to write only the final hash to output.

The we pipe the output has to ipns name publish --key=dotfile which, thanks to some handy DNS settings [5], points instantly to the latest version of the deployment.

IPNS propagation can take a long time across a large network [6], much like DNS propagation. The time to publish is proportional to the number of nodes in the network. Due to being hosted on private IPFS network of fewer than 10 nodes, publishing is relatively instantaneous.

Finally, this code presupposes a local key called dotfiles. To generate:

$ ipfs key gen dotfiles --type=rsa --size=2048;

Source Code

This lives at ~/.dotfiles/dfctl raw

#!/usr/bin/env bash

# Create an array of files
declare -a files=(".android" ".aws" ".bash_logout" ".bashrc" ".flake8"
  ".gitconfig" ".github_token" ".nano" ".profile" ".ssh" ".task" ".taskrc"
  ".tmux.conf" ".vim" ".vimrc" ".yarnrc" ".zprofile" ".zshrc")

process_files() {
  for FILE in "${files[@]}"; do
    if [[ "$1" == "export" ]]; then
      rm -rf ~/.dotfiles/"$FILE";
      cp -r ~/"$FILE" ~/.dotfiles/"$FILE"

    if [[ "$1" == "import" ]]; then
      cp -r ~/.dotfiles/"$FILE" ~/"$FILE"

  exit 0;

# Presupposes there's a local key name dotfiles
deploy_public_files() {
  declare -a public_files=("README" ".bashrc" ".flake8" ".taskrc"
    ".tmux.conf" ".vimrc" ".zshrc")
  ipfs add -Qrw ${public_files[@]} | ipfs name publish --key=dotfiles;
  exit 0;

# $1 Operation argument - should be import, export, or deploy
if [[ "$1" == "import" || "$1" == "export" ]]; then
    process_files $1;

if [[ "$1" == "deploy" ]]; then

# Default display usage

exit 1;


  1. GitHub’s portal for general dotfile community
  2. Fairly simple instructions from Protocol Labs on setting up how to make your IPFS node part of a private network
  3. IPFS - Simply Explained has a great introduction to the basics of IPFS, specifically what a hash is
  4. The page rendered at is IPFS’ default rendering of a wrapping directory
  5. The A record points at my private IPFS gateway via an NGINX rempote proxy. contains a TXT record pointing to my IPNS name. This technique is explained by IPFS author Juan Benet here
  6. The primary GitHub issue to track IPNS performance
TallyLabLike reading about IPFS and want to see it in action? Check out my and @skybondsor's work on TallyLab

Mark Robert Henderson

Mark Robert Henderson lives in coastal Massachusetts and works for the creators of OrbitDB.  The best way to reach him is via e-mail.

This website does not track you.