Creating A Remote Development Machine

Justin Kenyon

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 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

  • Set the droplet hostname to any name you’d like. image

  • 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

  • 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

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 for more details. image

  • Once you have reviewed all of your choices, click “Create Droplet”. image

  • Your droplet will now be configured. image

  • Once your droplet has been created you will be brought to the droplet details page. Please take note of your IP ADDRESS. image

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

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

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

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

  • 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

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) a small script to setup my environment. We are going to use it here by typing:

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.

  • 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

  • From your home folder, clone the thoughtbot dotfiles repo by executing this command: git clone git@github.com:thoughtbot/dotfiles.git image

  • Next, cd into the dotfiles directory and execute env RCRC=$HOME/dotfiles/rcrc rcup image

  • You can customize and override further using the .local convention explained here.

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