A remote development environment is an environment/server hosted externally (i.e. not on your local machine) that you connect to remotely to perform your development work on.
Image Source: Visual Studio Code / Microsoft
The way this is achieved is via a SSH Tunnel. But you can secure this a step further by requiring proof of identity via an SSO Identity Provider (like Google, Github, Facebook, Active Directory, etc) by using Cloudflare Access and Cloudflare Tunnel.
There are numerous benefits to using a remote environment to perform your development on. Here's just a few:
- You can switch machines without losing your work. Since your work is not on your local machine, that means that you can switch from your desktop to your laptop and not lose anything.
- You can develop your application/system on an environment that closer replicates the environment that your product will be deployed to.
- There's less of a security risk if your local machine is lost/stolen. Your code/files aren't on there.
- Colleagues and other developers can also connect to your remote development environment to help debug or perform any other necessary work.
By the end of this tutorial, you will have:
- A DigitalOcean droplet setup with your development stack
- Visual Studio Code setup locally with the Remote-SSH extension
- The cloudflared daemon installed both on your remote and local machines
- An SSH config on your local machine to easily connect to your remote machine using Cloudflare Tunnel and Cloudflare Access
- A generated SSH Key
- You will need to upload your public key to DigitalOcean
- You will need your private key in order to SSH into your Droplet initially
- A DigitalOcean account
- New users can use the link above to get a $100 credit valid for 60 days when you add a payment method to your account
- A Cloudflare account with a domain added
- This domain will be used by you to connect to the remote machine
- A Cloudflare for Teams account already setup
- A free plan is available
- A SSO Integration already setup within Cloudflare for Teams
- In this tutorial I'm using a GSuite integration to verify my identity
- Visual Studio Code installed on your local machine
You will create an access policy for your selected domain.
Cloudflare Tunnel is a service which provides a secure connection between the nearest Cloudflare datacenter and your remote machine, without opening public ports. This tunnel is how you will connect to your remote machine securely. Previously this was a part of Cloudflare's paid Argo service, but as of April 2021 has been made free of charge.
From your Cloudflare dashboard, select the domain (or zone) that you have chosen to use for this tutorial.
You need to create an access policy. This policy will determine who has access to your Droplet.
Click on the access tab on your domain's Cloudflare dashboard. Scroll down to Access Policies and hit Create Access Policy.
Give an application name, and the subdomain that you will use to connect to your Droplet (decide this now, you'll need it again later in this tutorial). For session duration, decide how long a session should be valid for.
You need at least 1 policy. Create one by giving it a name. Then add an include-rule. For this tutorial, I decided on "emails ending in" and the domain of my GSuite account.
Once you're done, hit save. Now that your Cloudflare settings are configured, it's time to create your remote machine.
You will create a Droplet on DigitalOcean with a new user, your preferred tools/programs, and the
To begin, visit this link to access the Droplet creation page.
For this tutorial, you will use Ubuntu 20.04 as your operating system.
For the Droplet plan select the configuration that you think you will need for your development work. From personal experience, the Regular Intel, 4GB / 2 CPUs plan works great on a stack with Java 11, Apache Maven, Git, and Docker.
Next, select your preferred datacenter. Typically, the datacenter closest to you is the best option to minimize latency.
For additional options, enable IPv6 and User data. Monitoring is optional but recommended if you wish to view stats about your Droplet online.
A text field will appear after selecting the user data checkbox. This is where you will paste a script to be executed when the server initially boots for the first time.
Below is a script that I have provided for you to use. It creates a new user, optionally installs some packages, and installs
cloudflared. There is a variable for the name of the user to create.
Back to the Droplet creation panel - For authentication select SSH Key and upload your public SSH key if you don't already have a key uploaded.
The remaining options are optional. I recommend changing the hostname to something you recognize, such as the domain name that you plan on using for that Droplet.
Once finished configuring your options, press Create Droplet. You've just created your remote machine! The next step is to configure it and ensure it is secure.
You will configure the
cloudflared daemon and setup the SSH tunnel on your Droplet.
On the DigitalOcean panel, navigate to your newly-created Droplet. Copy the public IPv4 address listed.
You are going to have to SSH into your Droplet with the username that you configured in the script provided. To do this, on your local shell run
ssh <your configured username>@<copied IP address> -i <path to your private SSH key>.
An example might look like
ssh sammy@XXX.XXX.XXX.XXX -i ~/.ssh/id_rsa.
Before proceeding, ensure that
cloudflared is up-to-date. Run
sudo cloudflared update.
Next, you need to authenticate
cloudflared with your desired zone (domain).
cloudflared login. It should output a link, which you can then copy to your web browser and load.
On the website, it is important that you select the zone that you will be using to connect to the Droplet with. Click Authorize. You can close that website once done.
Return back to your SSH session. You now need to move the newly-downloaded certificate to
/etc/cloudflared/cert.pm. Do this by running
sudo mv /home/sammy/.cloudflared/cert.pem /etc/cloudflared/cert.pem, replacing
sammy with your configured username.
Now is the time to create the tunnel.
Do this by running
cloudflared tunnel create NAME, replacing
NAME with a label for your tunnel. An id should then be printed out after running the command. Make note of it.
Next, you need to create a configuration file telling
cloudflared what to do when it runs.
Modify and copy the provided config file below. Replace
XXX with the id of your created tunnel, and
YOUR.DOMAIN.HERE with the hostname that you wish to use to connect to your Droplet. The apex domain must match the one you selected when authenticating
To create the DNS record for your configured domain name, run
cloudflared tunnel route dns <id> <subdomain> where
id is the id of the tunnel, and
subdomain is the subdomain you selected in your config file. You can verify on your Cloudflare DNS page that a CNAME record was created.
cloudflared daemon is now fully configured. It's time to start it! It's best to run the daemon as a service.
sudo cloudflared service install and
sudo service cloudflared start.
To verify that there were no errors in the service starting, run
sudo service cloudflared status. You should see the tunnel being started with some connections being made. Those connections are to nearby Cloudflare datacenters.
With your remote machine configured, it's now time to configure your local machine so it is able to connect to your Droplet over this secure tunnel.
You will configure your local machine to use the Cloudflare Tunnel when SSHing into your Droplet, and install the Remote-SSH extension in Visual Studio Code to be able to modify files on your Droplet seamlessly.
You do not need to authenticate the daemon on your local machine (i.e. do not run the login command).
Now, you need to update your local SSH config to make use of
cloudflared for your Droplet. The daemon has a feature which will generate most of this config for you.
cloudflared access ssh-config --hostname YOUR.DOMAIN.HERE, replacing the variable with your domain that you put in your config on your Droplet.
Determine where your local SSH config is. On Mac, it's located at
It should print something out like this to add to your SSH config:
Host YOUR.DOMAIN.HERE ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
Note, the path in your proxy command may be different depending on your operating system. That's why its important to use what the program gave to you after running the command.
Append the printed text to your local SSH config using your preferred text editor. Add an additional line under the Host labeled
User with your Droplet's username (see below for an example). This makes it easier for Visual Studio Code.
Host YOUR.DOMAIN.HERE ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h User sammy
Try connecting to your Droplet using this updated SSH config. Run
ssh YOUR.DOMAIN.HERE. If all goes well, your browser should open prompting you to select an identity provider, you login, and authorize the request. Once authorized, your local terminal will SSH into your Droplet and you can close the opened webpage.
Now it's time to setup your local Visual Studio Code IDE. Open VS Code and install the Remote-SSH extension.
Once installed, by default the extension should show remote targets from your local SSH config file. You can select your newly-added target to connect to it.
You can also use the
opensshremotes.openEmptyWindow VS Code command to select a remote target.
After authentication (or if your session is still valid from your test), VS Code will connect to your Droplet and automatically install the VS Code Server (first boot only).
From here, you can install extensions onto your Droplet, create directories/files, and even open a terminal in VS Code.
Remote development environments are a great way to work. They allow you to develop and test your product in an environment closer to production, permits switching machines, and allows multiple people access to the environment. Using Cloudflare Access and Cloudflare Tunnel, this access can be granted or denied based on authentication through SSO providers, providing a clean way to authenticate and authorize users.