Linux Fu: Raspberry Pi Desktop Headless

It seems to me there are two camps when it comes to the Raspberry Pi. Some people use them as little PCs or even laptops with a keyboard and screen connected. But many of us use them as cheap Linux servers. I’m in the latter camp. I have probably had an HDMI plug in a Pi only two or three times if you don’t count my media streaming boxes. You can even set them up headless as long as you have an Ethernet cable or are willing to edit the SD card before you boot the machine for the first time.

However, with the Raspberry Pi 4, I wanted to get to a desktop without fishing up a spare monitor. I’ll show you two ways to get a full graphical KDE desktop running with nothing more than a network connection.

The same principle applies to most other desktop environments, but I am using KDE and Ubuntu on the Pi, even though something lighter would probably perform better. But before we get there, let’s talk about how X11 has had a big identity crisis over the years.

The Plan

There are many ways to remotely access X programs, many of which are rarely used today. However, for this purpose, we are going to use SSH tunneling along with some special tricks to get the entire desktop running. It is easy to just run a single X program over SSH, and you’ve probably done that often. If so, you can skip to the next section.

If you haven’t done SSH tunneling before, don’t worry; it is easy. When you start ssh to the Pi, just include the -X or -Y option. You can also configure that in the ssh config file (ForwardX11 yes or ForwardX11Trusted yes) so you don’t have to type it in all the time. The SSH programs also have to be configured to allow that, but that’s usually the default behavior.

Consider this command.

ssh -X me@mypi.local konsole &

That would run konsole on your Pi, but the screen appears on your main machine. That’s fine, but it isn’t the entire desktop experience. Plus, some programs really expect support from other services that a desktop environment like KDE starts. So the trick is how to start the desktop?

The Tunneling Desktop

If you want to start a modern version of KDE, you can run startplasma-x11. The obvious thing to do is to try that over an SSH connection with X forwarding. That won’t work, though. Your screen is already managed by something else — maybe even KDE.

The trick is to create a new X server just for the Raspberry Pi. While you could start a new server, it is easier to create a fake server that lives in a window on your main server’s screen. There are two ways to do this: Xnest and Xephyr. Xnest is very old and creates a simple server with very few features. It depends on the host X server for most functions. Xephyr is more modern. It provides lots of modern features no matter what the host server provides. It basically uses the host server as a frame buffer.

Of course, this all assumes you have the KDE desktop installed on the Pi. A simple apt install for kubuntu-desktop will take care of that if you haven’t done it already.

Using XNest

The trick to XNest is that it creates a new server that just happens to draw on the original server — they are nested. There are a lot of options, but usually, it is sufficient to just run the program with a new (unused) display number.

Xnest :11

Notice the first X is uppercase. You might want to set the size:

Xnest --geometry 800x600 :11

You could run this on your local machine or from the Pi. As long as you have X tunneling set on your SSH connection, it won’t matter. But there’s still a problem.

Try running:

DISPLAY=:11 startplasma-x11

Most likely, it will start a few things and will appear to work. But at some point, you’ll get a fatal error and nothing will happen. The problem revolves around trying to render on the remote GPU. This may not be a problem with some lightweight desktops, but KDE stops.

The trick is you need to set one environment variable to tell Qt not to try to do hardware rendering:

QMLSCENE_DEVICE=softwarecontext startplasma-x11

That does the trick and now you can have a full KDE desktop running on the Pi and showing on your main monitor! You aren’t going to want to watch videos on it or play games, but otherwise it is perfectly serviceable.

I wrapped it all up in a script:

#!/bin/bash
Xnest -geometry 3840x2050 :2 &
export QMLSCENE_DEVICE=softwarecontext
DISPLAY=:2 startplasma-x11 &

Or a bit fancier:

#!/bin/bash
X="${1:-1024}"
Y="${2:-768}"
S="${3:2}"
Xnest -geometry ${X}x${Y} :$S &
export QMLSCENE_DEVICE=softwarecontext 
DISPLAY=:$S startplasma-x11 &

Using Xephyr

Xephyr isn’t usually installed and you may have to look for what package it is on your operating system. For Ubuntu, the package is xserver-xephyr. For some reason, running it on the Pi just caused the program to stall and do nothing — at least on my setup. However, in theory, you should be able to use it as a replacement for Xnest.

What I did instead was created the server on my local machine and then asked the Pi to use it. So:

 
Xephyr :1 -screen 1200x720 -resizeable &
DISPLAY=:1 ssh -X ubuntu@192.168.1.39 "QMLSCENE_DEVICE=softwarecontext startplasma-x11" &

This works, but it is very slow. Xephyr does a lot of work on its own, so the Xnest solution is faster.

The X That Was

When X11 started, it had a grand plan. From your login screen you should be able to log into any computer you had access to. Then, you should be able to run programs on your screen from any computer, not just the one you were using as your main computer. This still works, sort of. However, most Linux distributions aren’t really set up to take full advantage of it.

The trick to how things were supposed to be is the DISPLAY variable. That sets where the X clients (programs) connect to an X server (your screen). You can set that to be remote. For example:

DISPLAY=mydesktop.local:0 konsole

In theory, that should have much the same effect, but that assumes your network is open on ports around 9000 and that your Xserver is open or there is a peer authentication scheme set up.

In fact, you can take many greeters (the program that you give your user name and password to) and reconfigure them to listen for network connections and create network connections to other machines, just like the X11 designers intended. But most distributions have that turned off and I’m not even sure if some of the newer greeters offer that option at all.

In modern usage the X11 system has turned into a quasi-display driver for your monitor, and that’s sad. X has so many capabilities that about 90% of the Linux world do not use. (Recalling that 88.35% of all statistics are made up on the spot.)

If you want to try setting it up the old way, have a look at xhost, xauth, and be prepared to change your X server start up to remove the flag that prevents it from listening to TCP sockets. It can be done. Of course, security over the network might not be what you want. Tunneling over SSH solves that in a single line, though.

The Solution

Even after all this work, I’m still just going to log into my Pi from the command line for most jobs. I might include X11 forwarding so I can run the odd program on my desktop. However, for the times you really want to work with the entire desktop, the Xnest solution works well enough. Xephyr was slow. I’m not sure if it would have been faster if it had run on the Pi, but that never worked for me. I suspect it is some interaction with the NVidia display drivers, but I didn’t track it down.

Meanwhile, if you do try this, consider making the window as large as you can and parking it on a virtual desktop. This is a neat solution since you can flip desktops to access the Pi or your regular computer. Add another desktop with VirtualBox running Windows and you have the operating system trifecta. If you use Wayland, this may still work using Xwayland, but I haven’t tested it out.

If you really want to replace your desktop with a Pi, you might want to consider this trial. Or maybe you’d prefer a laptop.

30 thoughts on “Linux Fu: Raspberry Pi Desktop Headless

  1. I used to have an old low power fanless PC on my workbench in my garage that booted right to xdm, and connected to my main Desktop in my office. It was basically an always connected remote graphical dumb terminal. The only problem was that I never figured out how to make sound work as easily.

    I quit using this when my workbench got to cluttered to work at and I needed the PC for another project. I always intended to set this up again.

    It seemed like the “New Linux” people are bound and determined we won’t have this kind of ubiquitous remote access capability with the changeover to Wayland. By moving remote access to the compositor we will only get remote access if we choose one of a few big desktop environments that have the resources to implement it. I prefer a lightweight tiling window manager.

    1. “we will only get remote access if we choose one of a few big desktop environments”

      my goodness how quickly people forget that X windows has always been an optional add-on, it’s not required.

      It is most certainly possible to run and maintain a unix system without firing up any “desktop environment”

      If you prefer a lightweight windowing system you should try screen. Works great on even the most minimal system.

      1. I’ll browse HaD through lynx. Sounds fun.

        I can write OpenSCAD files from the commandline too. Who needs to actually preview their work? I’m sure I’m so good that whatever shape I picture in my head I can type out OpenSCAD code to perfectly create it without having to render.

        I think Slic3r had options to run from the commandline. I’m sure not actually seeing a render of how the part lies on the bed will not be a problem.

        Maybe instead of KiCAD I can draw schematics and PCBs in ASCII art?

        Next time I look up a datasheet for a part maybe I’ll try reading the raw PDF code.

        Can I build Gimp with AALib the next time I want to touch up a photo?

        Yah, whatever dude. The commandline is powerful and still very relevant today but it is not a 100% replacement for a graphical environment.

        1. I kinda wanna see that though… AAlib version of Gimp LOL

          There was the old SVGAlib for direct graphics on PC but that’s gotta be unworky on Pi, or through terminal sessions.

    2. If you bothered to read the Wayland FAQ before spewing your own false opinions you would see:

      “t is also possible to put a remoting protocol into a wayland compositor, either a standalone remoting compositor or as a part of a full desktop compositor. This will let us forward native Wayland applications. The standalone compositor could let you log into a server and run an application back on your desktop. Building the forwarding into the desktop compositor could let you export or share a window on the fly with a remote wayland compositor, for example, a friend’s desktop. ”

      which is exactly the opposite of your rant: the future of wayland is an actual functional remote desktop and not the broken mess of X11.

      1. And for those of us who are not Wayland developers a compositor is….

        Took a while to find this….

        Basically the Wayland term for Window or Desktop manager. No, not exactly the same thing but that’s the closest analogy for someone coming from X.

        So.. you only get remote access if you chose a window or desktop manager, sorry, compositor that supports it. Each one has to go through the trouble themselves. So remote access will only be an option for the big ones that have enough extra programming hours available to write that unfortunately underappreciated feature.

        Meaning you will only have remote access if you chose one of the big desktop environments.

        Which is exactly what I wrote.

        1. Wayland and X are pretty much identical in this respect. Except Wayland being new is less ubiquitous, and not everybody knows how to use it. Or understands the terminology.
          Do we need to move away from X? Perhaps not (though in this case I would say we do), either way like systemd its the current direction. If you don’t like it don’t use it, roll your own distro from scratch and see how quickly it seems easier to let the Canononical, Debian and Redhats (etc) of the world do that for you while you just learn about the one new thing!

        2. Correct. Wayland is Protocoland. You need something? Create a new protocol! And then fight with the rest so everyone uses yours… or everyone supports many protocols to do the similar things. Or just have a special feature nobody else has, uncompatible of course.

          Sounds like political games to control FOSS. Because as you say, not everyone will have the resources to keep up (web browsers and their “standards”? Canonical’s Mir?). FOSS dream takes another hit: “fork it” sounds nice, until you realize the project complexity makes it impossible (Foldi-One thinks different). Many projects of late sound like job creation plans, and business plans above that, by reinventing instead of finishing the hard parts. Complexity adds job security and recurrent support contracts to that plan. The FOSS licences are just a left over from the past, or PR theatre.

          Meanwhile, KeithP, of X11 fame, still has ideas about improving it. Someone hit him with the NIH-wand.

          1. I wouldn’t say I think different at all, impossible might be over exaggerated, but its certainly beyond the time and skills of many users. When it comes to ‘reinventing instead of…’ sometimes its much more efficient to throw out the 20+ years of baggage and start again taking forward the concept but on a new framework. If you could get the world of computer hardware and user expectations to stand still for a while making the old stuff perfect becomes more possible. But there is a reason some processors get dropped from kernel support and 32bit looks to be rapidly on the way out – the world keeps moving on!

            With something like Wayland or Systemd that brings many detractors you can keep an older distro going with essential patches. Or roll your own without it. The wonders of FOSS is you can if you like use any combination of bits you like if you want to put in the work. And many separate projects with special features eventually converge to do it all, as good ideas are good ideas.

    1. Yes, and it’s fairly easy to turn it on even when running fully headless. Just add the wpa_supplicant.conf (if necessary) and ssh files to the boot partition of your SD card, then SSH in and use raspi-config to enable VNC.

      I was kind of hoping that the article would give some kind of motivation for doing things the hard way. If the result is better than VNC, I’d be happy to give it a shot.

      1. The result probably is better than VNC for some situations – over a slow network link the way VNC works will make it more usable. However over LAN this method should feel much more responsive, probably even over halfway reasonable wifi connections.

      2. Yeah, over LAN this should be pretty zippy, despite being the “old” way to do it;

        It’s like at work there’s some server in the datacenter that is headless and you need to run Firefox *from there* as if you were a caveman who walked all the way to the DC with a crash cart or whatever in this contrived example.

        Anyway this example is from work a long time ago.

        Also, hi fren! My best Camillo!

    2. It is what I use… If I have the full PI OS installed. Most times have just the way smaller server version installed, so SSH is ‘the’ interface. Simple matter to write the empy ‘ssh’ file to \boot before installing card in the PI for SSH access. Once booted, use nmap to find it and then SSH to it and setup a static IP.

  2. i don’t use a raspberry pi but i have a headless PC (well, its head is in a dark corner of my basement with no seat), and i wanted to run intensive X apps on it (browser, some 3D stuff like stellarium and STL viewer), because my laptop is so light. leaving something like slack or twitter loaded all the time on a browser running locally would literally reduce my battery life by 30%.

    the solution in this article isn’t so great, imo, because Xnest has to die/restart every time you re-connect to it. plus, X11 is actually a really slow remote interface because so many of its operations effectively block until they get a response code. so i use xvfb + x11vnc with vncviewer. the xvfb keeps running even if there’s no head attached, and vnc is actually decently fast over the network (i’m not sure if RDP/rdesktop would be better). it’s got downsides, for example i’ve got it configured to use jpeg compression which leaves artifacts. but i love it.

    so i’ve got chrome+xvfb+x11vnc running under docker so that the huge web of dependencies triggered every time you upgrade your web browser don’t break anything else (realistically, chroot would probably be a better idea and more secure). and i’ve got a separate xvfb+x11vnc i typically leave running for applications that run directly on my host pc. it has been a big improvement.

    1. This. X2Go is a great way to do X forwarding. Besides handling the X-Server in a server, it also uses the NoMachine NX libraries to reduce latency. https://www.nomachine.com/

      I use X2Go to access one of my home computers from the internet over a secure shell connection. It works much better than simple X forwarding (which can also be done through an SSH tunnel) and worlds better than VNC.

      In my local network, I sometimes use X2Go installed on a remote PC tunneled over SSH to a machine where I don’t have X2Go installed. That gives me a remote desktop in a locally resizable window – without installing X2Go locally. The normal X forwarding through SSH is fast enough in the LAN for that to work.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.