Deploying Ubuntu Mate Desktop as a developer environment in AWS EC2

Written on April 29, 2016

TL;DR: If you don't want to find out the solution by running over 40 Ubuntu installations with several desktop environments on AWS, read on.

On a current project the idea came up to put Ubuntu Desktop developer environments into AWS EC2 instead of local installations (VMs) and RDP into it.

If you have a Windows background, you would expect to just spin up a server and have a UI...

But with Ubuntu things get a little *cough* bit more complicated.

In general, there are several options:

  • Install an Ubuntu or Debian Server and install an Ubuntu Desktop environment onto it, then connect via VNC to it
  • Install an Ubuntu or Debian Server and install an Ubuntu Desktop environment onto it, then connect via RDP to it
  • Create an AMI based on an existing AMI
  • Create an AMI from scratch

Another option that sounds appealing won't work: Create a Windows Server VM, activate Hyper-V, install VMware Workstation or VirtualBox and just run your Ubuntu Desktop inside it.
The first two options won't work because you can't have nested Hypervisors in AWS EC2 and VirtualBox would only allow 32bit OS installations because of this constraint.

So, back to the viable options: First, I tried to install Ubuntu Server 14.04 from the official AWS AMI, install the XFCE or GNOME-Desktop on it as well as vncserver.
While it works in general, the VNC performance and quality is not acceptable in 2016 (I expect true color and reasonable screen resolutions) - especially with GNOME or more complex desktop environments.
Besides that, XFCE feels like late 90th:

So, lets head over to the next option - the one I ended up with:

Install Ubuntu Server from the official AWS EC2 AMI, put Ubuntu Mate desktop on it and RDP into it.
What sounds like a straight forward plan, ended up as a *interesting* journey.

I've chosen (read: learned to choose) Mate, because it is one of the environments that looks pretty nice but doesn't require 3D acceleration enabled which you just don't have in cloud environments (at least not in the general compute instances).

If you're ok with XCFE, the folks at AWS have created a manual for that (on which this post partially is based on).

First, create a AWS EC2 instance of your choice, enable inbound Port 3389 (RDP) in its security group settings and SSH into it.

Enabling Port 3389:

After that, install the latest updates:

sudo apt-get udpate
sudo apt-get upgrade
sudo apt-get dist-ugprade

Next, enable password authentication for sshd:

sudo vim /etc/ssh/sshd_config

Find the line PasswordAuthentication no and change it to PasswordAuthentication yes

Save the sshd_config and restart sshd:

sudo /etc/init.d/ssh restart

Next, create a password for your default ubuntu user:

sudo -i
passwd ubuntu

Then, create a user which you want to be your Desktop user, I'll use awsgui here:

sudo useradd -m awsgui
sudo passwd awsgui
sudo usermod -aG admin awsgui
sudo usermod -aG sudo awsgui
su - awsgui

After that, install the Ubuntu Mate desktop and xrdp:

export DEBIAN_FRONTEND=noninteractive
sudo apt-add-repository ppa:ubuntu-mate-dev/ppa
sudo apt-add-repository ppa:ubuntu-mate-dev/trusty-mate
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install --no-install-recommends ubuntu-mate-core ubuntu-mate-desktop
sudo apt-get install mate-core mate-desktop-environment mate-notification-daemon
sudo apt-get install xrdp

Now, make Mate the default desktop environment for xrdp sessions (also for new users being created afterwards):

echo mate-session> ~/.xsession
sudo cp /home/awsgui/.xsession /etc/skel

Finally, we'll allow changing the host post port we can connect to (this allows reconnecting to an abandoned session):

sudo vim /etc/xrdp/xrdp.ini

Change port=-1 in the [xrdp1] section to port=ask-1.

With the changes done, restart xrdp:

sudo service xrdp restart

Now we're able to RDP into our AWS EC2 instance from Windows:

First, enter the public DNS entry (later on you'll assign an Elastic IP, of course) into the Windows Remote Desktop Client:

Next you should get the xrdp login screen were you enter your awsgui credentials and make sure sesman-Xvnc module is selected:

If everything went well, you should get this connection log:

After a second or two, you should also get the Ubuntu Mate desktop screen:

If you think we're done now: no.

Lets consider, we installed an EC2 instance with an SSD, that volume is mount to /mnt.

To make use of it, we need to chown it for the awsgui user - open a Terminal window by hitting <Ctrl><Alt><T> in the Mate environment. Then run:

sudo chown awsgui /mnt

Now, we can make use of /mnt.

Running software in the Mate environment

Here are some tips for running software in that environment.

Ubuntu Software Center

First of all, Ubuntu Software Center doesn't work due to some configuration errors I didn't get behind.
So if you have some nice .deb packages like Dropbox, just install them via Terminal:

sudo dpkg -i <package>.deb

Changing the timezone

If you want to change the timezone of your instance, you can't unlock and edit the setting in the UI.

Thus, you have to run sudo dpkg-reconfigure tzdata in Terminal and select the appropriate setting.

Dropbox

If you plan to install Dropbox, just download the .deb file and install it as described before.
You can start Dropbox using start dropbox -i to install the daemon.

After the installation you might see a weird or even no notification icon.
Just restart your EC2 instance and everything should be ok.

Restart / Shutdown via Mate

Speaking of restarting: You might notice that using the Mate logout / shutdown / restart feature won't end your RDP session. Just use sudo reboot or sudo shutdown now -h in Terminal.

Docker on /mnt

If you're running Docker and want to use the aforementioned volume /mnt (because otherwise it might eat up your small boot volume) for the images and volumes, just change your Docker config:

sudo vim /etc/default/docker

Add this line or change / extend your DOCKER_OPTS entry as follows:

DOCKER_OPTS="-g /mnt/.docker"

Before you restart your Docker service, make sure to create the folder:

mkdir /mnt/.docker

Now restart Docker by running sudo service docker restart.

docker pull node:4.2.3 should pull Node 4.2.3 and put it to /mnt/.docker:

Visual Studio Code

It just doesn't work in xrdp environments as of now - even with the latest Insider build installed.

I guess working with the environment will show some more caveats and if I get them solved, I'll keep the solutions posted.

I also would be happy if you share further tips in the comments.