Headless VNC server

This post describes a setup of a lightweight Xorg VNC session running as a specific user, which is started at boot time. This is a convenient way to display a GUI window in a VM or a container. This configuration is using TigerVNC as VNC server, and IceWM as a lightweight window manager.

TigerVNC can be run in the foreground, which simplifies the systemd service file. Install the TigerVNC server and start it manually once as your user (e.g. vncserver :1). This will ask for the password and store that in a file in the $XDG_CONFIG_HOME/.vnc/ directory.

TigerVNC config file

Create a configuration file in $XDG_CONFIG_HOME/.vnc/xstartup with the following content:

#!/bin/sh

xrdb $HOME/.Xresources
xsetroot -solid grey
# Fix to make GNOME work
export XKL_XMODMAP_DISABLE=1
icewm

This will start the IceWM as a lightweight window manager. You can of course replace it with any window manager you like.

systemd service file

Next, create a systemd service file, /etc/systemd/system/vncserver@.service:

[Unit]
Description=Remote desktop service (VNC)
After=syslog.target network-online.target

[Service]
Type=simple
Restart=always
User=joe

# Clean any existing files in /tmp/.X11-unix environment
ExecStartPre=-/usr/bin/vncserver -kill -clean :%i
ExecStart=/usr/bin/vncserver -geometry 3840x2160 --depth 16 -fg -autokill -localhost no :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

Enable the service file with systemctl enable vncserver@1.service and you should be able to connect after starting the service or after a system reboot.