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.
Digital Ocean is a developer focused cloud provider and is easy to use with lots of great documentation that is easily searchable via google.
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/
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:
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.123Once you are in the droplet, check and make sure docker is installed.
docker --versionIf you get a response similar to
Docker version 19.03.5, build 633a0eayou know your are good to go.
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 -yThese 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 localhostoutput
Add nginx output hereNow 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
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:nextdocker run is the command to launch the docker container.-d is the flag that tells docker to run as a daemonA daemon is a process that runs in the background of the computer.
-p maps the host port to the docker vm port --name sets the value of the name of the container, it must be unique-v creates a docker volume and maps to a container directory in this case the /home/project directorytheiaide/theia:next the image and version on dockerhubThink about what urls you want to use to map to these ports:
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 -yThis 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.
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 -yNow lets generate certs for example.com
systemctl stop nginx
certbot certonly --standalone -d example.com -d *.example.com
systemctl start nginxWe 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.
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 -tThen you may want to reload nginx if the message says everything is ok.
systemctl reload nginxif 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.
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
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.