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.
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.
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.
Log in to your Digital Ocean account and select “Create Droplet”.
Set the droplet hostname to any name you’d like.
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.
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.
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.
Once you have reviewed all of your choices, click “Create Droplet”.
Your droplet will now be configured.
Once your droplet has been created you will be brought to the droplet details page. Please take note of your
- 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-ADDRESSthat you noted before).
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
USER_NAMEwith the username of your choice).
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
sshdfrom 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_NAMEwith the username that you chose earlier).
Next, we need to
chownthat directory that we just created so that the
USER_NAMEcan 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
sshdfrom allowing any user to authenticate with a password. Open
/etc/ssh/sshd_configwith your editor of choice and change
Note: once you have saved this change, execute
restart ssh to reload the
- Now we can add this new user to the
sudoersfile. This will allow this user to execute the
sudocommand. 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.)
- Log out of your SSH session and log in again, but this time use your new
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
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.
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:
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 firstname.lastname@example.org:thoughtbot/dotfiles.git
dotfilesdirectory and execute
env RCRC=$HOME/dotfiles/rcrc rcup
You can customize and override further using the
.localconvention explained here.
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.
- 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
- It has taken me deeper into working in a Linux environment which is relatively new for me.
- 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.
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):