All articles
2 min read

Setting Up VNC Server on Raspberry Pi: A Comprehensive Guide

Install TightVNC on a Raspberry Pi running Ubuntu, configure a GNOME desktop session, run VNC as a systemd service, and connect securely over an SSH tunnel.

VNC gives you a graphical desktop on a headless Raspberry Pi, accessible from any device with a VNC client. This guide installs TightVNC on Ubuntu Server, configures a GNOME session, and sets it up as a service that starts at boot.

Step 1: Install a Desktop Environment

If your Pi is running Ubuntu Server (no desktop), install GNOME:

sudo apt update
sudo apt install ubuntu-gnome-desktop gnome-panel gnome-settings-daemon \
    metacity nautilus gnome-terminal -y

Enable the display manager:

sudo systemctl enable gdm
sudo systemctl start gdm

Step 2: Install TightVNC Server

sudo apt install tightvncserver -y

Step 3: Set a VNC Password

Run the VNC server once to create the password and configuration files:

vncserver :1

You'll be prompted to:

  1. Set a VNC password (used when clients connect)
  2. Set a view-only password (optional)

Kill the temporary session:

vncserver -kill :1

Step 4: Configure the VNC Session

Edit the startup file to use GNOME:

nano ~/.vnc/xstartup

Replace the contents with:

#!/bin/bash
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

xsetroot -solid grey
vncconfig -iconic &

gnome-panel &
gnome-settings-daemon &
metacity --replace &
nautilus &

Make it executable:

chmod +x ~/.vnc/xstartup

Step 5: Set the Screen Resolution

Test with a specific resolution:

vncserver :1 -geometry 1440x900 -depth 24

Step 6: Run VNC as a systemd Service

Create a service file so VNC starts at boot:

sudo nano /etc/systemd/system/vncserver@.service
[Unit]
Description=TightVNC remote desktop server on display :%i
After=network.target

[Service]
Type=forking
User=ubuntu
ExecStart=/usr/bin/vncserver :%i -geometry 1440x900 -depth 24
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

Replace User=ubuntu with your actual username.

Enable and start the service for display :1:

sudo systemctl daemon-reload
sudo systemctl enable vncserver@1
sudo systemctl start vncserver@1
sudo systemctl status vncserver@1

Step 7: Connecting from a Client

You'll need a VNC client — RealVNC Viewer works on Windows, macOS, and mobile.

Connect to <your-pi-ip>:1 or <your-pi-ip>:5901 (VNC uses port 5900 + display number).

Connecting Securely via SSH Tunnel

VNC traffic is not encrypted by default. For remote access over the internet, tunnel it through SSH:

# On your local machine — create an SSH tunnel
ssh -L 5901:localhost:5901 ubuntu@<your-pi-ip>

Then point your VNC client to localhost:1 instead of the Pi's IP. All traffic is encrypted by SSH.

Headless Setup: Fake Display Driver

If your Pi has no physical display attached, the desktop session may not start correctly. Install the dummy video driver:

sudo apt install xserver-xorg-video-dummy -y

Create /etc/X11/xorg.conf:

Section "Device"
    Identifier  "Configured Video Device"
    Driver      "dummy"
EndSection

Section "Monitor"
    Identifier  "Configured Monitor"
    HorizSync   31.5-48.5
    VertRefresh 50-70
EndSection

Section "Screen"
    Identifier  "Default Screen"
    Monitor     "Configured Monitor"
    Device      "Configured Video Device"
    DefaultDepth 24
    SubSection "Display"
        Depth 24
        Modes "1440x900"
    EndSubSection
EndSection

This creates a virtual display so the desktop session can run without physical hardware.

Conclusion

TightVNC with a GNOME session gives you a full graphical interface on any headless Raspberry Pi. Run it as a systemd service so it survives reboots, and always access it over an SSH tunnel when connecting from outside your local network.