How to Configure VNC Server on Ubuntu

Last reviewed: by
How to Configure VNC Server on Ubuntu

VNC lets you open a remote graphical desktop on an Ubuntu server. It is useful when you need a lightweight remote desktop for administration tools, IDEs, lab systems, or applications that need an X session.

The safest practical setup is to run TigerVNC with XFCE, bind the VNC server to localhost only, and connect through an SSH tunnel. This keeps the VNC port off the network while still letting you use a VNC viewer from your local machine.

This guide configures a VNC display for a normal Linux user, starts it manually for testing, then converts it into a systemd service so it can start after reboot. The package commands were validated on Ubuntu 25.04. The same package names are available on supported Ubuntu releases such as Ubuntu 22.04 and Ubuntu 24.04, but package versions may differ.

NOTE
In VNC, display :1 maps to TCP port 5901, display :2 maps to 5902, and so on. This guide uses display :1 and keeps it bound to 127.0.0.1 for SSH tunneling.

Quick Command Summary

Task Command
Install TigerVNC and XFCE sudo apt install tigervnc-standalone-server tigervnc-common dbus-x11 xfce4-session xfce4-panel xfce4-settings xfdesktop4 xfwm4 xfce4-terminal
Set VNC password vncpasswd
Start VNC display :1 vncserver -localhost yes -geometry 1280x800 -depth 24 :1
List VNC sessions vncserver -list
Stop VNC display :1 vncserver -kill :1
Check listening port `ss -ltnp
Create SSH tunnel ssh -L 5901:127.0.0.1:5901 user@server_ip
Enable systemd service sudo systemctl enable --now [email protected]
Check service status systemctl status [email protected] --no-pager

Prerequisites

You need:

  • An Ubuntu server or desktop system.
  • A non-root user for the VNC desktop.
  • SSH access to the server if you plan to use the secure tunnel method.
  • sudo privileges to install packages and create the systemd service.

If you are preparing a minimal Ubuntu server and need XFCE separately, see install XFCE desktop on Ubuntu. If you prefer RDP instead of VNC, compare this with install XRDP with XFCE4 on Ubuntu. For Red Hat based systems, see configure VNC server in RHEL 8.


1. Install TigerVNC and XFCE Packages

Update the package index:

bash
sudo apt update

Install TigerVNC, DBus support, and a minimal XFCE session:

bash
sudo apt install tigervnc-standalone-server tigervnc-common dbus-x11 xfce4-session xfce4-panel xfce4-settings xfdesktop4 xfwm4 xfce4-terminal

The command below was tested with apt simulation on Ubuntu 25.04 to validate package names and dependencies without changing the test host:

bash
apt install -s tigervnc-standalone-server tigervnc-common dbus-x11 xfce4-session xfce4-panel xfce4-settings xfdesktop4 xfwm4 xfce4-terminal

Tested output:

text
Installing:
  dbus-x11                    xfce4-panel     xfce4-terminal
  tigervnc-common             xfce4-session   xfdesktop4
  tigervnc-standalone-server  xfce4-settings  xfwm4

Installing dependencies:
  elementary-xfce-icon-theme  libtumbler-1-0t64         light-locker
  exo-utils                   libutempter0              light-locker-settings
  greybird-gtk-theme          libxfce4panel-2.0-4       lightdm
  libdbus-glib-1-2            libxfce4ui-2-0            lightdm-gtk-greeter
  libexo-2-0                  libxfce4ui-common         python3-psutil
  libexo-common               libxfce4util-bin          thunar-data
  libfile-readbackwards-perl  libxfce4util-common       tigervnc-tools
  libgarcon-1-0               libxfce4util7             tumbler
  libgarcon-common            libxfce4windowing-0-0     tumbler-common
  libgarcon-gtk3-1-0          libxfce4windowing-common  xfce4-helpers
  libgtk-layer-shell0         libxfconf-0-3             xfconf
  liblightdm-gobject-1-0      libxklavier16             xfdesktop4-data
  libthunarx-3-0              libxpresent1              xiccd

Summary:
  Upgrading: 0, Installing: 48, Removing: 0, Not Upgrading: 51

The package availability was also checked directly:

bash
apt-cache policy tigervnc-standalone-server tigervnc-common xfce4 dbus-x11

Tested output:

text
tigervnc-standalone-server:
  Installed: (none)
  Candidate: 1.14.1+dfsg-1
  Version table:
     1.14.1+dfsg-1 500
        500 http://archive.ubuntu.com/ubuntu plucky/universe amd64 Packages
tigervnc-common:
  Installed: (none)
  Candidate: 1.14.1+dfsg-1
  Version table:
     1.14.1+dfsg-1 500
        500 http://archive.ubuntu.com/ubuntu plucky/universe amd64 Packages
xfce4:
  Installed: (none)
  Candidate: 4.20
  Version table:
     4.20 500
        500 http://archive.ubuntu.com/ubuntu plucky/universe amd64 Packages
dbus-x11:
  Installed: (none)
  Candidate: 1.16.2-2ubuntu1
  Version table:
     1.16.2-2ubuntu1 500
        500 http://archive.ubuntu.com/ubuntu plucky/main amd64 Packages

If you want the full XFCE desktop and extra plugins, install xfce4 xfce4-goodies instead of the smaller XFCE package list. On a server, the smaller list is usually enough for a VNC desktop.


2. Use a Normal User for the VNC Session

Do not run your daily VNC desktop as root. Use an existing user or create a dedicated user. For a broader account setup guide, see create user in Linux and adduser command examples.

bash
sudo adduser vncuser

Switch to that user before creating the VNC password and startup file:

bash
su - vncuser

If you need to grant administrative access later, use sudo deliberately instead of running the entire graphical session as root. For sudo-user setup, see add user to sudo group in Linux.


3. Set the VNC Password

Run vncpasswd as the user who will own the VNC session:

bash
vncpasswd

You will be prompted for a password. TigerVNC stores the encrypted password under the user's ~/.vnc directory.

Example prompt:

text
Password:
Verify:
Would you like to enter a view-only password (y/n)? n

The view-only password is optional. Use it only when you want someone to observe the desktop without controlling it.


4. Configure the XFCE Startup File

Create the VNC startup script:

bash
mkdir -p ~/.vnc
nano ~/.vnc/xstartup

Add this content:

sh
#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec dbus-launch --exit-with-session startxfce4

Make it executable:

bash
chmod +x ~/.vnc/xstartup

The startup script syntax was validated with sh -n on the test host:

bash
sh -n /tmp/glc-vnc-test/xstartup
ls -l /tmp/glc-vnc-test/xstartup
cat /tmp/glc-vnc-test/xstartup

Tested output:

text
-rwxr-xr-x 1 root root 111 Jun  7 22:11 /tmp/glc-vnc-test/xstartup
#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec dbus-launch --exit-with-session startxfce4

dbus-launch comes from the dbus-x11 package. Without it, some desktop components may start with missing session-bus features.


5. Start the VNC Server Manually

Start display :1 and bind it to localhost only:

bash
vncserver -localhost yes -geometry 1280x800 -depth 24 :1

Important options:

Option Meaning
-localhost yes Listen only on 127.0.0.1, so clients must connect through SSH tunneling or locally
-geometry 1280x800 Set the virtual desktop resolution
-depth 24 Use 24-bit color depth
:1 Start VNC display 1, which maps to TCP port 5901

List running VNC sessions:

bash
vncserver -list

Stop the session when testing is complete:

bash
vncserver -kill :1

6. Check the Listening VNC Port

After starting display :1, check TCP port 5901:

bash
ss -ltnp | grep 5901

If the server was started with -localhost yes, the listener should be on 127.0.0.1:5901 or [::1]:5901, not 0.0.0.0:5901.

The test host did not have VNC running, but the listener check command was validated with active TCP listeners:

bash
ss -ltnp | grep LISTEN | head

Tested output:

text
LISTEN 0      4096      127.0.0.54:53         0.0.0.0:*    users:(("systemd-resolve",pid=362,fd=17))
LISTEN 0      128        127.0.0.1:6012       0.0.0.0:*    users:(("sshd-session",pid=13436,fd=9))
LISTEN 0      4096         0.0.0.0:22         0.0.0.0:*    users:(("sshd",pid=1606,fd=3),("systemd",pid=1,fd=505))
LISTEN 0      4096               *:1313             *:*    users:(("hugo",pid=87638,fd=4))

For remote access troubleshooting, see test SSH connection commands, test port connectivity in Linux, and check open ports in Linux.


7. Connect Through an SSH Tunnel

From your local computer, create an SSH tunnel to the Ubuntu server:

bash
ssh -L 5901:127.0.0.1:5901 vncuser@server_ip

Keep that SSH session open. Then open your VNC viewer on your local computer and connect to:

text
127.0.0.1:5901

This works because your local port 5901 is forwarded over SSH to 127.0.0.1:5901 on the Ubuntu server. For more tunneling patterns, see SSH port forwarding and SSH tunnel examples. If you connect often, simplify the client side with an SSH config file and key-based login from SSH key generation examples.


8. Create a systemd Service for VNC

A systemd service makes the VNC session easier to start, stop, and enable at boot. Create a template unit as root:

bash
sudo nano /etc/systemd/system/[email protected]

Add this content. Replace vncuser with your Linux username:

ini
[Unit]
Description=TigerVNC server for display :%i
After=network.target

[Service]
Type=forking
User=vncuser
Group=vncuser
WorkingDirectory=/home/vncuser

PIDFile=/home/vncuser/.vnc/%H:%i.pid
ExecStartPre=-/usr/bin/vncserver -kill :%i
ExecStart=/usr/bin/vncserver -localhost yes -geometry 1280x800 -depth 24 :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

Reload systemd and start display :1:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now [email protected]

Check the service:

bash
systemctl status [email protected] --no-pager

Stop or restart it when needed:

bash
sudo systemctl restart [email protected]
sudo systemctl stop [email protected]

For more systemd background, see systemd tutorial for beginners and systemctl service listing commands.


9. Check Firewall Rules

If you use -localhost yes and connect through SSH tunneling, you normally do not need to open port 5901 in UFW. You only need SSH access to the server.

Check UFW status:

bash
sudo ufw status verbose

Tested output:

text
Status: inactive

If UFW is active, allow SSH:

bash
sudo ufw allow OpenSSH

Avoid exposing VNC directly to the internet. If you intentionally run VNC without localhost-only binding on a trusted private network, restrict the source IP:

bash
sudo ufw allow from CLIENT_IP to any port 5901 proto tcp

That direct-port approach is less secure than SSH tunneling and should not be your default. If SSH is exposed to the network, consider hardening it with Fail2ban for SSH.


10. Troubleshooting Common VNC Problems

Problem What to check
VNC viewer cannot connect Confirm the SSH tunnel is still open and the viewer is connecting to 127.0.0.1:5901
Port 5901 is not listening Run vncserver -list, check systemctl status [email protected], and inspect ~/.vnc/*.log
VNC shows a blank or gray screen Check ~/.vnc/xstartup, confirm it is executable, and confirm XFCE packages are installed
Service fails after reboot Check username, home directory, PIDFile, and /usr/bin/vncserver path in the unit file. See VNC server service failed because a configured resource limit was exceeded for a related systemd failure pattern
Direct connection fails but SSH tunnel works VNC may be correctly bound to localhost only; use the tunnel method
Authentication fails Re-run vncpasswd as the VNC user

Check the VNC log files:

bash
ls -l ~/.vnc
cat ~/.vnc/*.log

Check service logs:

bash
journalctl -u [email protected] -n 50 --no-pager

For journald usage, see journalctl command examples.


Frequently Asked Questions

1. Which VNC server should I use on Ubuntu?

TigerVNC is a practical choice for Ubuntu servers because it provides a standalone VNC server, vncpasswd, and systemd-friendly service management.

2. Which desktop environment works well with VNC on Ubuntu?

XFCE is commonly used with VNC because it is lighter than a full GNOME desktop and works well inside a virtual VNC display.

3. Which port does VNC display :1 use?

VNC display :1 listens on TCP port 5901. Display :2 uses 5902, display :3 uses 5903, and so on.

4. Should I expose VNC port 5901 to the internet?

No. A safer setup is to start VNC with localhost-only binding and connect through an SSH tunnel. Open the VNC port directly only on a trusted network and only when you understand the risk.

5. How do I connect to an Ubuntu VNC server securely?

Run ssh -L 5901:127.0.0.1:5901 user@server from the client, then connect your VNC viewer to 127.0.0.1:5901.

6. How do I make the VNC server start after reboot?

Create a systemd template unit such as [email protected], reload systemd, then enable the display instance with systemctl enable --now [email protected].

Summary

To configure a VNC server on Ubuntu, install TigerVNC and XFCE, set a VNC password for a normal user, create ~/.vnc/xstartup, start vncserver on display :1, and connect through an SSH tunnel to 127.0.0.1:5901. For persistent sessions, create a [email protected] systemd template and enable [email protected].

For security, keep VNC bound to localhost and avoid exposing port 5901 directly to the internet.

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, …

  • Red Hat Certified System Administrator in Red Hat OpenStack
  • Certified Kubernetes Application Developer (CKAD)
  • Red Hat Certified Specialist in Ansible Automation
  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security