VSCode Online with AWS

by Suyog Sonwalkar

NOTE: This post is deprecated as VSCode Online added the ability to start a vscode server without a UI after rebranding to Visual Studio Codespaces. Github Codespaces would probably use something similar and would be a better overall experience than manually setting up an instance on AWS.

I’m writing this blog post using VSCode Online using a hosted environment on AWS.

This is pretty awesome as it lets me use VSCode from a webbrowser to connect to a VM running on my AWS account.

This post goes over how I set it up, what works, and how I believe that remote development like this is not just the future, but also a critial part of what Github (now owned by Microsoft) will offer in the future.

Why Remote Development

Setup

Step by Step

Systematic way of setting up an Ubuntu Environment with xfce4, Chrome, VSCode, Nodejs, and Jupyter for web based remote development from any device.

Getting an AWS Instance and setting up the right security group

Get an instance - I got a t3.medium with 2 VCPUs and 4GB RAM. I also attached a 32GB SSD Disk to the VM.

Make sure the Security Group is setup properly (inbound connections from these ports should be allowed):

Ports 8000-8001, 9000 for web development purposes 
Port 8888 for Jupyter
Port 22 for SSH
Port 5901 for VNC

Note that I usually limit the security group to only my IP since this is intended to be a development machine.

Getting gnome-desktop and VNC setup on Ubuntu 18.04 Server

TODO: Update to use gnome-desktop rather than xfce4 which has odd bugs that cause it to crash frequently & the VNC connection needs to be re-established / VSCode environment needs to be refreshed.

Note: Replace USER=suyogs with the username you want to setup. When you add your user, it will ask for a password that will be used for authentication.

USER=suyogs
sudo apt update && sudo apt install -y ubuntu-desktop tightvncserver gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal build-essential
sudo adduser $USER
sudo usermod -aG sudo $USER
su - $USER

As your $USER:

vncserver 
vncserver -kill :1
mv ~/.vnc/xstartup ~/.vnc/xstartup.bak
vim ~/.vnc/xstartup

Make some common directories for your user:

mkdir -p ~/Documents ~/Desktop ~/Downloads ~/Music ~/Pictures ~/Movies ~/Projects

In the ~/.vnc/xstartup file, add the following:

#!/bin/bash

export XKL_XMODMAP_DISABLE=1
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &

gnome-session &
gnome-panel &
gnome-settings-daemon &
metacity &
nautilus &
# gnome-terminal &

Then run this in your $USER’s shell:

sudo chmod +x ~/.vnc/xstartup
vncserver

At this point, you should be able to connect to VNC on your Ubuntu machine by using a VNC Client (see below for clients on Mac and iPhone) and connecting to vnc://YOUR_PUBLIC_IP:5901. The next step will setup VNC to be a systemctl service that will spawn on boot.

To figure out your public ip from the terminal, you can just use the following command:

curl ifconfig.co
sudo vim /etc/systemd/system/vncserver@.service

In the /etc/systemd/system/vncserver@.service file, add the following (NOTE: Be sure to replace YOUR_USER with the username from above manually):

[Unit]
Description=Start TightVNC server at startup
After=syslog.target network.target

[Service]
Type=forking
User=YOUR_USER
Group=YOUR_USER
WorkingDirectory=/home/YOUR_USER

PIDFile=/home/YOUR_USER/.vnc/%H:%i.pid
ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
ExecStart=/usr/bin/vncserver -depth 24 -geometry 1280x800 :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

Run the following to restart vnc:

vncserver -kill :1
sudo systemctl daemon-reload
sudo systemctl enable vncserver@1.service
sudo systemctl start vncserver@1
sudo systemctl status vncserver@1

You should now be able to reboot your machine and VNC will be setup on boot.

Getting Chrome and VSCode Installed

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
rm google-chrome-stable_current_amd64.deb 
wget -O code.deb https://go.microsoft.com/fwlink/?LinkID=760868
sudo dpkg -i code.deb 
rm code.deb 

Fix an issue around Code not booting in remote VNC/X sessions and install the VSOnline extension:

cd /usr/lib/x86_64-linux-gnu/
cp libxcb.so.1 libxcb.so.1.bak
sudo cp libxcb.so.1 libxcb.so.1.bak
sudo sed -i 's/BIG-REQUESTS/_IG-REQUESTS/' libxcb.so.1
cd ~
code --install-extension ms-vsonline.vsonline

At this point, you should be able to open up VNC, open VSCode and connect to your Azure account and VSOnline account. In addition, you want to Register your local environment so that it shows up at https://online.visualstudio.com

Getting NodeJS and Yarn

This will get NodeJS and Yarn and update /etc/sysctl.conf so you don’t run into file watcher errors from yarn or VSCode.

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
npm config set python python2.7
sudo vim /etc/sysctl.conf

Do the following change to sysctl to fix a common file watcher issue in yarn / vscode:

In the /etc/sysctl.conf File, add the following to the end of the file:

fs.inotify.max_user_watches=524288

Finally, run the following command:

sudo sysctl -p

Getting Jupyter

As your $USER, do the following:

cd Downloads/
wget https://repo.anaconda.com/archive/Anaconda3-2019.07-Linux-x86_64.sh
bash ./Anaconda3-2019.07-Linux-x86_64.sh

You’ll have to hit [Enter][Space], type yes to accept Anacondas license terms, [Enter] to confirm /home/$USER/anaconda3 is the right location to install to, yes again to run conda init & update your PATH, then relogin to your user’s shell session. If you run python --version, you should see Python 3.7+ now.

Now just run the following:

conda update --all --yes
jupyter notebook --ip=0.0.0.0

Jupyter will give a ?token=TOKEN url in the logs, you should be able to access your Jupyter instance at http://YOUR_PUBLIC_IP:8888?token=TOKEN and work with notebooks there.

Getting Postgres

Getting postgres setup for local database connections

sudo apt-get install -y postgresql

You should then be able to access a database locally using:

sudo -u postgres psql

VNC

On a Mac, you can use Screen Sharing which is built into Finder (Command+K in Finder) and connect with a vnc://YOUR_IP:5901 url.

On iPhone, use VNC Viewer, just remove the “vnc://” from the connection, so YOUR_IP:5901 should work.

Troubleshooting

Debugging / Troubleshooting VNC

I had the VNC server crash sometimes - to debug, I first checked if SSH was still working - it might be that the VNC server crashed (which is necessary for VSCode to connect to the remote environment). If SSH isn’t working, it might be that your VM crashed, check AWS’s console to see if there’s an issue / maybe reboot.

From an ssh session as your $USER, try the following:

sudo systemctl status vncserver@1.service
sudo systemctl restart vncserver@1.service

If there’s an error, try these to debug / figure out what the issue is:

vncserver -kill :1
sudo journalctl -xe

What needs a bit more work

The VSCode online client seems to get stuck in a “Reconnecting” state, where its easier to just refresh the page / go back to the environments page and click on your environment again.

Right now there’s some usability issues that could be resolved:

The future

References

#Experiments