Accessing a full Ubuntu graphical desktop environment via a simple web browser on Port 80 sounds impossible?
Not anymore.
In this post, we’ll walk through everything we needed to achieve exactly that – step-by-step, clean, and reliable.

You’ll also get a complete cheat sheet of all Linux commands used!


Introduction

Normally, setting up remote desktop access involves installing VNC and connecting through a VNC client.
But what if you want to access your server’s GUI directly via a browser like Safari or Chrome – and on the default HTTP Port 80?

We tackled this by combining:

  • TightVNC

  • noVNC

  • Websockify

  • Nginx

And finally, we ensured everything autostarts after reboot.


1. Basic Environment Preparation

We worked on an Ubuntu Server running in Google Cloud Platform (GCP), but these steps apply to almost any Linux server.

First, update the system:

bash
sudo apt update

Make sure tightvncserver, xfce4, novnc, and websockify are installed:

bash
sudo apt install -y tightvncserver xfce4 xfce4-goodies novnc websockify nginx

2. Setting Up the VNC Server

Install and configure TightVNC:

bash
vncserver :1

On first start, you will set a VNC password.
The desktop will be available on port 5901.

Important:
If you see a grey screen when connecting later, it’s because the VNC server isn’t starting a desktop session.

To fix it, edit the startup script:

bash
nano ~/.vnc/xstartup

Replace its contents with:

bash
#!/bin/bash
xrdb $HOME/.Xresources
startxfce4 &

Make it executable:

bash
chmod +x ~/.vnc/xstartup

Restart the VNC server:

bash
vncserver -kill :1
vncserver :1

3. Setting Up noVNC + Websockify

Now, we make VNC accessible via a browser.

Run websockify manually to map VNC to HTTP:

bash
websockify --web=/usr/share/novnc/ 6080 localhost:5901

You can now access your server’s GUI in the browser by visiting:

arduino
http://[YOUR-SERVER-IP]:6080/vnc.html

Note:
Websockify must stay running, otherwise browser access breaks.
We’ll fix that later by running it as a background service.


4. Reverse Proxy via Nginx to Port 80

We don’t want users to enter :6080.
We want everything to be accessible directly over Port 80.

Edit your nginx default site:

bash
sudo nano /etc/nginx/sites-available/default

Replace it with:

nginx
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;

location / {
proxy_pass http://localhost:6080/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_set_header Host $host;
proxy_read_timeout 61s;
}
}

Reload nginx:

bash
sudo systemctl reload nginx

✅ Now, your desktop is accessible at:

arduino
http://[YOUR-SERVER-IP]/vnc.html

on plain HTTP Port 80!


5. Make Websockify Run Automatically (systemd Service)

To avoid manually starting websockify each time, we make it a service.

Create a systemd unit:

bash
sudo nano /etc/systemd/system/websockify.service

Insert:

ini
[Unit]
Description=Websockify Service for noVNC
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/websockify –web=/usr/share/novnc/ 6080 localhost:5901
Restart=always
User=root
Group=root

[Install]
WantedBy=multi-user.target

Reload systemd:

bash
sudo systemctl daemon-reload

Start and enable the service:

bash
sudo systemctl start websockify
sudo systemctl enable websockify

✅ Websockify now starts automatically after every reboot!


6. Bonus: Make VNC Server Auto-Start on Boot

Also, you might want your VNC session to come up automatically.

Create another systemd service:

bash
sudo nano /etc/systemd/system/vncserver.service

Insert:

ini
[Unit]
Description=Start VNC Server at boot
After=syslog.target network.target
[Service]
Type=forking
User=ab
Group=ab
WorkingDirectory=/home/ab

PIDFile=/home/ab/.vnc/$(hostname):1.pid
ExecStart=/usr/bin/vncserver :1 -geometry 1280x1024 -depth 24
ExecStop=/usr/bin/vncserver -kill :1

Restart=on-failure

[Install]
WantedBy=multi-user.target

Reload and activate:

bash
sudo systemctl daemon-reload
sudo systemctl start vncserver
sudo systemctl enable vncserver

✅ Now, both your VNC server and your web interface come up fully automatically at system boot!


7. Full Command Cheat Sheet

 

Purpose Command
Update system sudo apt update
Install packages sudo apt install -y tightvncserver xfce4 xfce4-goodies novnc websockify nginx
Start VNC Server vncserver :1
Kill VNC Server vncserver -kill :1
Edit VNC startup file nano ~/.vnc/xstartup
Make xstartup executable chmod +x ~/.vnc/xstartup
Start websockify manually websockify --web=/usr/share/novnc/ 6080 localhost:5901
Edit nginx config sudo nano /etc/nginx/sites-available/default
Reload nginx sudo systemctl reload nginx
Create systemd service for websockify sudo nano /etc/systemd/system/websockify.service
Enable and start websockify service sudo systemctl start websockify && sudo systemctl enable websockify
Create systemd service for vncserver sudo nano /etc/systemd/system/vncserver.service
Enable and start vncserver service sudo systemctl start vncserver && sudo systemctl enable vncserver

Conclusion

With this setup, you now have a full Linux graphical desktop environment accessible through any modern web browser over port 80.

✅ No Docker needed.
✅ No special clients required.
✅ Persistent across reboots.

This solution is not only practical for personal servers but is also a great showcase project for DevOps portfolios!


Credits

Thanks to the deep learning and troubleshooting across our session, this guide has been built from real-world experience solving actual challenges step-by-step.