---
title: Creating A Remote Development Machine
teaser: Spin up a remote development machine that you can access anywhere over SSH.
tags: web,linux,rails,ruby,tools
author: Justin Kenyon
published_on: 2015-02-10
---

Recently we worked for a client that needed to block external IPs. We had
a lot of back-and-forth asking to whitelist the various IPs we might be
connecting from, so to make that easier I kicked off an experiment I'd been
thinking about for a while.

## Working hypothesis

Using a remote machine, located on a hosted platform that one can access from
anywhere, a developer can develop with Ruby on Rails (and other languages) from
anywhere with an Internet connection and SSH.

## Platform

You can use any Linux platform, hosted or otherwise, that allows you full root
access (ideally) to accomplish this (even a RaspberryPi!). I chose [Digital Ocean](http://digitalocean.com)
because of the low cost of entry for a single droplet with Ubuntu 14.04
pre-installed.

## Creating a droplet

- Log in to your Digital Ocean account and select "Create Droplet".
  ![image](https://images.thoughtbot.com/remote-dev-machine/choose-create-droplet.png)

- Set the droplet hostname to any name you'd like.
  ![image](https://images.thoughtbot.com/remote-dev-machine/droplet-hostname.png)

- Choose the size of your droplet. For this experiment I chose the $10/mo
  option, but this can be accomplished on anything from their $5/mo option and up.
  ![image](https://images.thoughtbot.com/remote-dev-machine/droplet-size.png)

- Choose a region for your droplet. It is usually best to select the location
  closest to where you are working most of the time to avoid any latency
  problems.
  ![image](https://images.thoughtbot.com/remote-dev-machine/droplet-region-available-settings.png)

*Note: none of the "Available Settings" (shown above) are needed for this experiment.*

- Choose an SSH key to install on to your droplet. This is the most secure way
  to access your droplet and is highly recommended over password only
  protection. See [their documentation](https://cloud.digitalocean.com/droplets/4028760)
  for more details.
  ![image](https://images.thoughtbot.com/remote-dev-machine/droplet-ssh-keys.png)

- Once you have reviewed all of your choices, click "Create Droplet".
  ![image](https://images.thoughtbot.com/remote-dev-machine/create-droplet.png)

- Your droplet will now be configured.
  ![image](https://images.thoughtbot.com/remote-dev-machine/creating-droplet-progress.png)

- Once your droplet has been created you will be brought to the droplet details
  page. Please take note of your `IP ADDRESS`.
  ![image](https://images.thoughtbot.com/remote-dev-machine/droplet-dev-machine.png)

## Initial user setup

- First, you will need to connect to your droplet via SSH. For now, just open
  up your terminal app and type: `ssh
root@<IP-ADDRESS-OF-DROPLET>` (substituting the `IP-ADDRESS` that you noted before).
![image](https://images.thoughtbot.com/remote-dev-machine/ssh-root-initial.png)

*Note: you will need to respond with 'yes' to allow your droplet's IP address to
be added to the list of known hosts on your machine.*

- Before doing any kind of configuration on the droplet, let's first create a
  user that you can use other than `root`. Type in `adduser USER_NAME`
  (substituting `USER_NAME` with the username of your choice).
  ![image](https://images.thoughtbot.com/remote-dev-machine/ssh-new-user.png)

*Note: you will also need to provide a new password for this user, and any
details that you wish to add.*

- Now that we have created a new user, let's make sure that we lock down `sshd`
  from allowing that user to connect with a password and continue to use the
  same SSH key to connect. First we will copy the key from the root user to the
  newly created user. Type: `mkdir /home/USER_NAME/.ssh && cat
  ~/.ssh/authorized_keys >> /home/USER_NAME/.ssh/authorized_keys`
  (remember to substitute `USER_NAME` with the username that you chose earlier).

- Next, we need to `chown` that directory that we just created so that the
  `USER_NAME` can write to it later. Execute this command: `chown -R
  USER_NAME:USER_NAME /home/USER_NAME/.ssh`

- Since we now have the SSH key authorized for the new user, let's lock down
  `sshd` from allowing any user to authenticate with a password. Open
  `/etc/ssh/sshd_config` with your editor of choice and change
  `#PasswordAuthentication yes` to `PasswordAuthentication no`.
  ![image](https://images.thoughtbot.com/remote-dev-machine/disallow-ssh-password.gif)

*Note: once you have saved this change, execute `restart ssh` to reload the
configuration.*

- Now we can add this new user to the `sudoers` file. This will allow this user
  to execute the `sudo` command. Replicate the line `root ALL=(ALL:ALL) ALL`,
  replacing root with your new username, and save the file. (If you're in vim,
  you'll need to save with `:w!` since the file is readonly.)
  ![image](https://images.thoughtbot.com/remote-dev-machine/sudoers-edit.gif)

- Log out of your SSH session and log in again, but this time use your new
  username: `ssh USER_NAME@<IP-ADDRESS-OF-DROPLET>`
  ![image](https://images.thoughtbot.com/remote-dev-machine/ssh-devuser-initial.png)

## Initial development environment setup

There are a few ways that you can go about setting up your environment. I
created (with the help of an older thoughtbot laptop
[script](https://github.com/thoughtbot/laptop/blob/39768b19959f74724ed0c0ea92e5b2f6f78e45c1/linux))
a small script to setup my environment. We are going to use it here by typing:

```bash
bash <(wget -qO- https://raw.githubusercontent.com/kenyonj/init/master/init.sh)
2>&1 | tee ~/init.log
```

*Note: you will need to enter your password to install `aptitude` as well as
changing your default shell to `zsh`.*

This process will take about 10-15 minutes depending on the speed of the machine
you are executing it on. It will need to be customized for other environments
other than Ubuntu 14.04 on DigitalOcean, but works great there.

## Personalizing your environment

Once our environment contains all of our Ruby on Rails development tools, we can
start customizing it.

For this, I like to start out with [thoughtbot/dotfiles](http://github.com/thoughtbot/dotfiles).

- First, make sure that you are starting in your home folder by typing: `cd`.

  (Note: before completing the next step you will need to [add your new user's
  SSH key to your GitHub account](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/)

- From your home folder, clone the thoughtbot dotfiles repo by executing this
  command: `git clone git@github.com:thoughtbot/dotfiles.git`
  ![image](https://images.thoughtbot.com/remote-dev-machine/github-clone-dotfiles.png)

- Next, `cd` into the `dotfiles` directory and execute `env
  RCRC=$HOME/dotfiles/rcrc rcup`
  ![image](https://images.thoughtbot.com/remote-dev-machine/rcup-initial.gif)

- You can customize and override further using the `.local` convention
  explained [here](https://thoughtbot.com/blog/manage-team-and-personal-dotfiles-together-with-rcm).

## Finishing up

Now that you have completed the above steps you should have a fully working
environment on a remote server that you can access anywhere with an Internet
connection and a terminal.

Make sure to close out your current session and reconnect so that all of your
new dotfiles are sourced and you are using `zsh` as your default shell.

### Wins

- I am not reliant on my laptop's state (I can reboot or update my laptop without
  worrying about my development environment).
- I am not tied to a single machine or its capabilities (I see this working very
  well from a chromebook).
- I can share my rails development server very easily with fellow devs
  (`http://<IP-ADDRESS-OF-DROPLET>:3000`).
- It has taken me deeper into working in a Linux environment which is relatively
  new for me.

### Losses

- There is a little bit of lag compared to a local terminal session. It is really
  nothing serious, and you will notice what I am referring to if you follow the
  above guide, or work in an SSH session often.
- I have yet to enable clipboard sharing from my machine to the remote session
  through SSH.
- You always need an Internet connection to have this work.

## Overall thoughts

This is something that I am going to continue to experiment with over the next
month or so. Some of the negative issues I have come across have not been severe
enough for me to halt the experiment which I feel is very promising.

Here is a screen shot of my dev environment running completely inside Chrome
(using the Secure Shell chrome extension):

![image](https://images.thoughtbot.com/remote-dev-machine/final-environment.png)
