diff --git a/bootstrap-Debian.sh b/bootstrap-Debian.sh
new file mode 100755
index 0000000..f166d96
--- /dev/null
+++ b/bootstrap-Debian.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+
+set -e
+
+show_usage() {
+  echo "usage: $0 [-h] [-y]"
+}
+
+show_help() {
+  show_usage
+  echo
+  echo "Bootstrap a Debian based distribution with:"
+  echo
+  echo "* update apt cache"
+  echo "* upgrade apt packages"
+  echo "* git - from apt"
+  echo "* python - from apt"
+  echo "* python-pip - from apt"
+  echo "* virtualenv - from pip"
+  echo "* SSH key - from ssh-keygen"
+  echo "* GitHub public key - with SSH key"
+  echo "* GitLab public key - with SSH key"
+  echo "* BitBucket Cloud public key - with SSH key"
+  echo "* Gogs Cloud public key - with SSH key"
+  echo "* conduit - configuration manager"
+  echo
+  echo "If any already exist they will not be reinstalled."
+  echo
+  echo "optional arguments:"
+  echo "        -h              show this help message and exit"
+  echo "        -y              assume yes when prompted"
+}
+
+yes=0
+
+while getopts 'hy' opt; do
+  case $opt in
+    h) show_help; exit 0 ;;
+    y) yes=1 ;;
+    *) show_usage; exit 1 ;;
+  esac
+done
+
+missing() {
+  which $1 &> /dev/null && return 1 || return 0
+}
+
+agree() {
+  local check=^[Nn]$
+  [ $yes -eq 1 ] && [[ ! "$2" =~ $check ]] && return 0
+  [[ "$2" =~ $check ]] && local default="[y/N]" || local default="[Y/n]"
+  read -p "$1 $default? " answer
+  case "$answer" in
+    y|Y|yes) return 0 ;;
+    n|N|no) return 1 ;;
+    '') [[ "$2" =~ $check ]] && return 1 || return 0 ;;
+    *) echo "invalid input: $answer" && return `agree "$1"` ;;
+  esac
+}
+
+apt_install() {
+  sudo apt-get install --yes --install-recommends $1 > /dev/null
+}
+
+pip_install() {
+  pip install --user $1 > /dev/null
+}
+
+export PATH=~/.local/bin:$PATH
+
+agree "Update apt cache" && sudo apt-get update > /dev/null
+agree "Upgrade apt packages" "N" && sudo apt-get upgrade > /dev/null
+
+missing git && agree "Install git" && apt_install git
+
+if missing pip; then
+  agree "Install python-pip" && apt_install python-pip
+  agree "Upgrade pip with pip" && sudo -H pip install --upgrade pip > /dev/null
+fi
+
+missing virtualenv && agree "Install virtualenv" && pip_install virtualenv
+
+if [ ! -f ~/.ssh/id_rsa ] && agree "Generate SSH key"; then
+  read -rp "SSH email: " email
+  [ ! -d ~/.ssh ] && mkdir -p ~/.ssh
+  ssh-keygen -t rsa -b 4096 -C "$email" -N "" -f ~/.ssh/id_rsa
+fi
+
+if ! missing virtualenv && agree "Set SSH keys on remote Git servers"; then
+  env=$(mktemp -d)
+  virtualenv $env > /dev/null
+  source $env/bin/activate
+  pip install git+https://code.infektor.net/config/bootstrap.git > /dev/null
+  python -c 'import bootstrap; bootstrap.set_ssh_keys()'
+  deactivate
+  rm -r $env
+fi
+
+missing conduit && agree "Install conduit" && \
+  pip_install git+ssh://git@github.com/kbenzie/conduit.git
+
+echo "To use installed pip packages update your PATH:"
+echo 'export PATH=~/.local/bin:$PATH'
+
+[ -f $0 ] && agree "Remove $0" "N" && rm $0 || exit 0