Setup a dev box in the cloud with theia ide

Online sandboxes are great for experimenting but they only get you so far. In this article, I will walk through how I setup a dev box in the cloud for as little as 5 dollars per month using Digital Ocean, using Google Cloud, you could take advantage of their Free Tier which consists of one micro vm for no cost.

Theia is an open source ide that runs in the cloud via a browser. It is basically the vscode toolkit that loads in a browser window.

This tutorial is using Digital Ocean, but it should work fine for Google Cloud or Amazon Web Services or Azure.

Steps

Create an account with Digital Ocean

Digital Ocean is a developer focused cloud provider and is easy to use with lots of great documentation that is easily searchable via google.

https://digitalocean.com

Spin up a vitural machine using Digital Ocean running docker

Once you have a DO account, lets create a virtual machine, DO calls them droplets, I recommend the smallest droplet with docker already installed.

https://marketplace.digitalocean.com/apps/docker

Before you spin up your droplet you will need to be able to access your host via ssh, make sure you setup a public and private key pair on your device then provide your public key to digital ocean. For more guidance check out: https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/

Purchase a domain name - example.dev

Using any domain registrar (ie dnsimple.com) register a domain, then you will want to use Digital Ocean DNS to update your Name Servers to point to digital ocean DNS.

https://www.digitalocean.com/docs/networking/dns/

It important to create two a records in the dns settings:

Shell into you server

From this point on, we will need to work in the terminal and remote in to the server.

Open up a terminal and type the following:

Be sure to copy or write down your IP address of your new droplet.

ssh root@[ip address]

example

ssh root@123.123.123.123

Once you are in the droplet, check and make sure docker is installed.

docker --version

If you get a response similar to Docker version 19.03.5, build 633a0ea you know your are good to go.

Install nginx

nginx is a proxy that will handle your ssl and security to the docker container running the ide server. It is a fast and easy to use proxy for linux.

apt update -y
apt install nginx -y

These two lines updates the apt registry then installs the nginx debian package.

Once installed, nginx will start on port 80, so you should be able to curl to localhost and see the following:

curl localhost

output

Add nginx output here

Setup firewall

Now that you have nginx installed, we want to expose the port 80 and 443 to the public internet, we need to do this with the universal firewall or ufw. It is already installed on the droplet.

This command will install the full nginx app

ufw allow 'Nginx Full'

if you want to see all the available apps type: ufw app list

Now, that you have allowed nginx to be accessible via the public internet, you should be able to open your browser and type in the ip of this droplet and see the nginx welcome page.

TODO: add screenshot here

Spin up docker image for Theia

Using docker we want to run the theiaide/theia:next image, we want to expose port 3000 and port 5000 and port 35729.

Here is the docker command line to launch the Theia IDE server:

docker run -d \
-p 3000:3000 \
-p 5000:5000 \
-p 35729:35729 \
--name theia \
-v theia:/home/project:cached \
theiaide/theia:next

A daemon is a process that runs in the background of the computer.

Think about what urls you want to use to map to these ports:

Create user accounts (Optional)

IMPORTANT NOTE: this process is not super secure, if you want to implement something really secure, I recommend you check out nginx-jwt. https://github.com/auth0/nginx-jwt

To secure your ide, you may want to create some user accounts to be used by basic auth.

Install apache2-utils

apt install apache2-utils -y

This will install the command-line app htpasswd

Using this tool, we want to create a set of users that will have access to our dev environment.

command: htpasswd -c [file] [username]

htpasswd -c /etc/nginx/.htpasswd [username]

When executing, it will prompt you for a password and a confirm prompt, those must match. You can use https://passwordsgenerator.net/ to generate a password, that no one can remember.

Generate SSL Certificates

In order to create SSL certificates, I recommend using LetsEncrypt, they are free and they have built a great automated process to update your SSL certs remotely.

Install certbot

apt install certbot -y

Now lets generate certs for example.com

systemctl stop nginx
certbot certonly --standalone -d example.com -d *.example.com
systemctl start nginx

We are using the standalone process with certbot and we are stopping the nginx server so that certbot can communicate with LetsEncrypt to let them know that we own the server.

This will create a folder /etc/letsencrypt/live/example.com and it will have the following important files:

We will need both of those files in our nginx configuration.

Configure nginx

As of now, nginx is just showing a default web page, we want to create a couple of server blocks, these blocks will proxy to our docker instance.

In the /etc/nginx/sites-available/default file, we want to add the following code block at the beginning.

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

This is to setup the websockets that is used in the Theia ide.

Then we want to skip the first server block and define a server block below.

server {
  server_name dev.example.com; # your server url here
  listen 80;
  listen [::]:80;

  listen 443 ssl;
  listen [::]:443 ssl;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  include /etc/letsencrypt/options-ssl-nginx.conf;

  if ($scheme != "https") {
    return 301 https://$host$request_uri;
  }

  location / {
    proxy_pass http://localhost:3000;
    proxy_redirect off;

    # basic authentication
    auth_basic  "Private Propery";
    auth_basic_user_file  /etc/nginx/.htpasswd; 
  }

  # support websockets
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection $connection_upgrade;
}

exit and save your changes.

And we will need to add a file /etc/letsencrypt/options-ssl-nginx.conf

At this point you may want to test and make sure your configuration parses correctly.

nginx -t

Then you may want to reload nginx if the message says everything is ok.

systemctl reload nginx

if you do experience problems, look at the line number it is complaining about, for example if you are on an older version of ubuntu it may complain about TLSv1.3.

If everything is working correctly and your dns is pointing to your IP, you should be able to launch a browser at https://dev.example.com and see your theia ide after basic auth login. REMEMBER: substitue example.com with your url.

Adding a show port

While having a cloud ide is great, you may want a nice url to go to show your server work. To do this you may want to create a new server block in nginx that will proxy to port 5000 of localhost.

open /etc/nginx/sites-available/default and add the following to the bottom of the file

server {
  server_name show.example.com;

  listen 80;
  listen [::]:80;

  listen 443 ssl;
  listen [::]:443 ssl;

  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

  include /etc/letsencrypt/options-ssl-nginx.conf;

  if ($scheme != "https") {
    return 301 https://$host$request_uri;
  }

  location / {
    proxy_pass http://localhost:5000;
    proxy_redirect off;
  }
}

you will notice this looks very similar to the dev.example.com, but we removed auth and changed the localhost to port 5000

Summary

At this point, you should have a working online dev environment that uses port 5000 as a preview for your services.

When going through this process, I was able to get the dev environment to work with the ipad using localhost, but when I added nginx as a proxy it no longer worked with the ipad, it was getting an error. I will investigate in the future.

Here are my editor settings for the Theia IDE.

{
  "editor.fontSize": 16,
  "editor.tabSize": 2,
  "editor.cursorStyle": "underline-thin",
  "editor.hover.delay": 1000,
  "editor.lightbulb.enabled": false,
  "editor.matchBrackets": false,
  "editor.renderLineHighlight": "none",
  "editor.formatOnSave": true,
  "window.zoomLevel": 1,
  "editor.highlightActiveIndentGuide": false,
  "editor.hover.enabled": false,
  "editor.hover.sticky": false,
  "editor.renderIndentGuides": false,
  "editor.parameterHints.enabled": false,
  "editor.suggestOnTriggerCharacters": false,
  "editor.wordBasedSuggestions": false,
  "editor.quickSuggestions": false,
  "editor.occurrencesHighlight": false
}

I use these settings to try to reduce the auto popup hints that kind of annoy me.