DEV Community

Cover image for Running remote GUI apps with the infinite power of the cloud.
Tom Harvey for InRange

Posted on

Running remote GUI apps with the infinite power of the cloud.

Remote development environments allow us to shift our computing needs to the infinite processing and high bandwidth offered by the cloud. It creates a shared, collaborative space that's close to our production environment. The growing toolchain around them is an exciting part of a new developer experience. But I'd never used it with a GUI app until now.

The below takes about 10-15minutes, and you get a remote, powerful desktop environment ready to run whatever Linux GUI tool you need; scientific research, 3D modelling, or just renting a faster computer for a while.

QGIS is a tool to help load, analyse and visualise geospatial data. But they don't have a build for my M1-based Mac; plus, I want to load a lot of data into it.

GeoSpatial layers

I'd turn to VSCode remote development or a SageMaker Studio Notebook for command line or scripting work. For a GUI app, I need to add a desktop environment to Ubuntu and access that through VNC.

Start with an Ubuntu 22.04 EC2 instance.

I've used CDK to spin this up, but go with the console, the AWS CLI, or whatever is comfortable for you.

instance = ec2.Instance(self, "DevInstance",
    instance_type=ec2.InstanceType('t3.micro'),
    machine_image=ec2.MachineImage.generic_linux(
        {'eu-west-1': 'ami-0d75513e7706cf2d9'}
        # The above is Ubuntu22.04 in the Ireland region
        # If you use another region, you'll want to find
        # the AMI for your region
    ),
    block_devices=[
        ec2.BlockDevice(
        device_name="/dev/sda1",
        volume=ec2.BlockDeviceVolume.ebs(
        )
    ],
    vpc=ec2.Vpc.from_lookup(self, "VPC", is_default=True)
)
instance.role.add_managed_policy(
    policy=iam.ManagedPolicy.from_aws_managed_policy_name(
        "AmazonSSMManagedInstanceCore"
    )
)
CfnOutput(self, "InstancePublicIp",
    value=instance.instance_id,
)
Enter fullscreen mode Exit fullscreen mode

Gain CLI access to the EC2 instance.

I'm using AWS's SSM Session Manager, so I don't need to worry about ssh keys or opening ports.

aws ssm start-session --target $AWS_INSTANCE_ID
Enter fullscreen mode Exit fullscreen mode

Install a desktop environment and a VNC server.

I'm using Tiger VNC and securing it with a password. Do this as the ubuntu user

sudo su
su ubuntu

sudo apt update

sudo apt install -y \
    xfce4 xfce4-goodies \
    tigervnc-standalone-server tigervnc-common tigervnc-tools

Enter fullscreen mode Exit fullscreen mode

You'll now need to do a "first run" of the vnc server to do some initial configuration - like setting a password:

vncserver
Enter fullscreen mode Exit fullscreen mode

This will prompt you to create a password and optionally create a "view only" password so that user can only view. I didn't set a view only, you probably don't need that either.

We can now continue with the setup of the VNC server:

cat > /home/ubuntu/.vnc/xstartup<< EOF
#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
/usr/bin/startxfce4
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
x-window-manager &
EOF

chmod u+x /home/ubuntu/.vnc/xstartup

echo ':1=ubuntu' | sudo tee -a /etc/tigervnc/vncserver.users

sudo systemctl start tigervncserver@:1.service
sudo systemctl enable tigervncserver@:1.service
Enter fullscreen mode Exit fullscreen mode

Allow access to port 5901 on the server.

I've used SSM Session Manager to create a tunnel. This way, localhost:5901 tunnels across to remote:5901; saving me from opening that port in AWS and making everything more secure.

aws ssm start-session --target  $AWS_INSTANCE_ID \
    --document-name AWS-StartPortForwardingSession \
    --parameters \
    '{"portNumber":["5901"], "localPortNumber":["5901"]}'
Enter fullscreen mode Exit fullscreen mode

Open a VNC client connection.

macOS comes with one! Or, download a VNC client for your machine

In the Mac's finder, use the "Go" menu, select "Connect to server" (or press command-K), and add the VNC connection path:

vnc://127.0.0.1:5901
Enter fullscreen mode Exit fullscreen mode

macOS VNC Connection

Now, I have the desktop environment of that Ubuntu server in a window on my local Mac. I can install QGIS on that server or whatever GUI app I want. That remote machine has an ultra-fast network connection and only needs to stream the (low bandwidth) screen activity down my network connection. I can keep costs down by using a small AWS instance, or if I need to load more data, I can have up to 24TB of RAM and hundreds of CPUs! My lowly laptop can really be a wolf in sheep's clothing.

Top comments (0)