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:
- Set a VNC password (used when clients connect)
- 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.