Skip to content

Full Linux Desktop with x11docker

Updated: at 02:22 PM (5 min read)

A few days ago, I posted a detailed guide on how I got Cursor running inside a container using jlesage/docker-baseimage-gui. And honestly? That setup worked. But “worked” and “worked well” are two entirely different things, and over the past few days, I kept running into issues that pushed me to look elsewhere.

finished-containerization-demo

I’m talking:

It was becoming messy real fast.

Table of contents

Open Table of contents

Why I Gave Up on Single App Containers

All I wanted was a clean setup to run Cursor with:

But what I ended up with was me hacking around every edge case, even though the whole point of containers is to keep things simple and reproducible.

Sure! Here’s a rephrased, cohesive version of your section in a smooth, natural tone — nothing important left out, just easier to read and more conversational:


Meet x11docker

When I first looked at x11docker, it felt like complete overkill. I mean, a full desktop environment? Just to run Cursor?

But here’s the thing: sometimes it’s better to go with something that’s simple, stable, and a bit heavier, rather than wrestling with a lighter setup that needs constant fixing and tweaking. After dealing with all the headaches in jlesage/docker-baseimage-gui, switching to x11docker felt like a breath of fresh air.

Turns out, x11docker isn’t just good, it’s perfect for running full Linux desktop environments inside containers. It’s clean, extendable, and doesn’t rely on clunky VNC or browser-based access. And the best part? It just works.

Why x11docker clicked for me

Here’s what makes x11docker such a solid choice:

If you’ve used docker-baseimage-gui before, you’ll feel the difference immediately. No hacks. No scripts. No weird workarounds. Just a fully working Linux desktop in a container, with zero drama.

My x11docker Setup

Here’s how I set it all up. I’m using podman here, but you can easily swap it with Docker, the commands are basically the same.

# xfce desktop with dev tools
FROM x11docker/xfce

RUN apt-get update && apt-get install -y \
  git curl apt-utils sudo gnupg

# install Node.js if required
RUN curl -sL https://deb.nodesource.com/setup_24.x | bash -
RUN apt-get install -y nodejs

Save that as Dockerfile, and build the image:

podman build -t x11docker-xfce:1 .

Running the Container

Here’s the command that works beautifully for me:

x11docker --desktop \
  --backend=podman \
  -I \
  --clipboard \
  --cap-default \
  --sudouser \
  --home \
  x11docker-xfce:1

Let’s break this down:

Persistent Storage

Thanks to the --home flag, everything inside your home directory sticks around between sessions. That means:

Clean. Predictable. No permission nightmares.

Installing Cursor

The only manual step I do each time is installing Cursor, which is no big deal.

  1. Download the .deb and place it inside the shared home folder.

  2. Inside XFCE, just run:

    sudo apt install -y ./Cursor.deb
    

It takes 5 seconds. And once done, Cursor launches perfectly in a full desktop session.

Compared to docker-baseimage-gui?

Featuredocker-baseimage-guix11docker
GUI BackendVNC in BrowserNative X11/Wayland (real desktop)
Input IssuesFrequent keyboard glitchesSmooth native input
Folder SharingMessy, permission issuesSimple with --home or --share
Requires Init Scripts?Yes, for sudo/shell/entrypoint hacksNope
Installing appsNeeds hacks + volume mountsJust apt install inside XFCE
Desktop EnvironmentNone (single-app focus)Full XFCE or LXQt (or any DE you want)
PerformanceLightweight, but VNC limitedSlightly heavier, but native UX

Final Thoughts

If docker-baseimage-gui was my first real taste of GUI containers, then x11docker was the upgrade I didn’t know I needed.

I’m now running:

I can focus on building, writing, coding, without debugging the container itself every 5 minutes.

If you’ve worked with my previous setup even for a couple of days, you’ll immediately appreciate the beauty of x11docker. It’s a bit heavier, sure, but you get your sanity back.