2025年8月17日日曜日

Run a Full Linux Desktop in Docker

 

First Ray of Light: The Good Things and the Bad Things

After my failed custom image attempt, I found a promising XFCE-based Debian image on Docker Hub. I downloaded it in minutes and, with a few commands, launched it. When I opened the URL, I was greeted by a fully functional Linux desktop, running right in my browser. The pure geek joy of seeing a complete OS served from inside a Docker container was a feeling I won’t forget. It worked!

The usability was surprisingly decent. LibreOffice and GIMP worked fine, although there was a bit of a lag. I would estimate about 70% of native performance, but still very usable. Firefox launched, too, and I even tried YouTube. That's when I hit the first major hurdle: the colors were dull and washed out. A quick check confirmed my suspicion: the browser was using software rendering. My GPU was sitting idle.

There was another problem I noticed: Flatpak didn't work. Any attempt to install an app from Flatpak failed with errors, so I had to resort to Debian packages. Despite these limitations, seeing a complete Linux desktop running in my browser, served directly from Docker, was a massive win.

Tweaking and Learning

After a few minutes with XFCE, I decided to switch things up and try GNOME as my desktop environment. Big mistake! It took hours of troubleshooting and error-fixing to get it running, and when it finally launched, it was slow and resource-hungry. In the end, I swallowed my pride and reverted to XFCE, and told myself, XFCE may not be flashy, but it’s far more responsive. So let's lean towards practicality.

With my new focus on performance, I decided to revisit my first attempt: building a custom image from scratch. This time, I studied the Dockerfile of the pre-built image I had used previously. I wanted to understand exactly what was going on under the hood, and I wanted to see if I could improve the performance myself. I experimented with a few new configurations, specifically trying to use xrdp instead of the noVNC forwarding method, to see if a different protocol would offer a smoother experience. But I didn't see any difference with xrdp.

To replicate, create a file with the name "dockerfile", paste the code, and run it.

FROM ubuntu:jammy-20230425


RUN apt update && \
    DEBIAN_FRONTEND=noninteractive apt install -y \
        cinnamon locales sudo \
        tigervnc-standalone-server tigervnc-common \
        virtualgl mesa-utils mesa-vulkan-drivers \
        dbus-x11 xterm wget && \
    locale-gen en_US.UTF-8 && \
    update-locale LANG=en_US.UTF-8

# Create user
# Enter the below username and passoword in xrdp login screen
ARG USER=user
ARG PASS=1234
RUN useradd -m $USER -p $(openssl passwd $PASS) && \
    usermod -aG sudo $USER && \
    chsh -s /bin/bash $USER

# Environment for Cinnamon
RUN echo "#!/bin/sh\n\
export XDG_SESSION_DESKTOP=cinnamon\n\
export XDG_SESSION_TYPE=x11\n\
export XDG_CURRENT_DESKTOP=X-Cinnamon\n\
export LIBGL_ALWAYS_INDIRECT=0\n\
exec cinnamon-session" > /home/$USER/.xinitrc && \
    chown $USER:$USER /home/$USER/.xinitrc && chmod +x /home/$USER/.xinitrc

# Setup VNC password
RUN mkdir -p /home/$USER/.vnc && \
    echo $PASS | vncpasswd -f > /home/$USER/.vnc/passwd && \
    chmod 0600 /home/$USER/.vnc/passwd && \
    chown -R $USER:$USER /home/$USER/.vnc

# Start script
RUN echo "#!/bin/bash\n\
export DISPLAY=:1\n\
Xvnc :1 -geometry 1920x1080 -depth 24 -SecurityTypes VncAuth -rfbport 5901 -localhost no &\n\
sleep 2\n\
sudo -u $USER startx &\n\
tail -f /dev/null" > /start && chmod +x /start

EXPOSE 5901

CMD ["/start"]

If all of this sounds like too much work, there’s good news. You don’t have to build your own image to get started or deal with errors. My research led me to two fantastic, ready-to-use solutions that offer a much more streamlined experience.

  • Webtop by LinuxServer.io: This is a great open-source option that provides a variety of Linux desktop flavors pre-packaged as Docker images. It uses noVNC to deliver the desktop straight to your browser, and the setup is straightforward.
  • Kasm Workspaces: This is another open-source option for personal use.

The good thing about these images is that they have everything pre-configured, especially Webtop. You simply pull the Docker image and run it. Once the container is running, you can access your Linux by entering the URL. I found the performance to be much better than anything I had tried previously, and, importantly, had audio pass-through, which I didn't find with Kasm images.

To run Webtop, open Windows CMD and paste this code

docker run -d ^
--name webtop-xfce ^
-e PUID=1000 ^
-e PGID=1000 ^
-e TZ=Etc/UTC ^
-p 3000:3000 ^
--shm-size=1gb ^
lscr.io/linuxserver/webtop:latest

Why Is It Difficult to Run Linux in Docker?

So, now that I have understood that running a full desktop environment inside a container and expecting it to behave like a normal desktop on Windows is possible but painful, fragile, and much more cumbersome than running a VM. The primary reasons for these are:

  • Containers are not isolated Operating Systems: Docker containers share the host kernel. This is what makes them lightweight and great for single services. Whereas desktop environments expect system services like (systemd, logind, udev, DBus) and device access to be available. Containers don’t provide that by default.
  • No built-in display servers: Linux GUIs need a compositor/display server (X11 or Wayland). A container does not provide one, so we have to do that ourselves.
  • GPU access: Containers don’t virtualize GPUs by default, so you must pass device nodes into the container. And on Windows, there’s an additional WSL layer to cross.



LangChain Launches Open SWE, an Open-Source Asynchronous Coding Agent

 LangChain has released Open SWE, a fully open-source, asynchronous coding agent designed to operate in the cloud and handle complex software development tasks. The company says Open SWE represents a shift away from real-time “copilot” assistants toward more autonomous, long-running agents that integrate directly with a developer’s existing workflows.


Unlike many coding assistants that focus on short interactions inside an IDE, Open SWE connects directly to GitHub repositories and works like another member of the engineering team. Developers can assign it tasks via GitHub Issues or a dedicated UI, after which it researches the codebase, generates a detailed plan, writes and tests code, reviews its work, and opens a pull request when complete.

The tool is designed for high-context, longer-term tasks. Every run occurs in a secure, isolated Daytona sandbox, allowing the agent to execute shell commands freely without risking the host environment. This architecture enables it to operate entirely in the cloud, handling multiple tasks in parallel without consuming local resources.

Open SWE also emphasizes human-in-the-loop controls. Developers can interrupt the agent mid-task, request changes, or provide new instructions without restarting. During the planning phase, users can accept, edit, or reject proposed strategies before execution begins. This flexibility extends to “double texting” — the ability to send new requests while the agent is already working, something most coding assistants can not do.

LangChain says Open SWE’s multi-agent architecture — Manager, Planner, Programmer and Reviewer — is key to producing higher-quality code. The Reviewer checks outputs for errors before any pull request is created, aiming to reduce broken builds and repeated review cycles.

langchain open swe architecture



The project is built on LangGraph and deployed via the LangGraph Platform, which the company says is optimized for long-running agents and offers persistence, scaling, and deployment flexibility.

Open SWE is available now on GitHub, with full documentation for developers who want to extend it, customize its prompts, or integrate it into internal systems. LangChain positions the project as both a production-ready assistant and a foundation for further community-driven innovation.

How to Use It

You can get started with the hosted version of Open SWE in minutes. All you need is an Anthropic API key.

  1. Visit swe.langchain.com.
  2. Connect your GitHub account and select the repositories you want Open SWE to access.
  3. Provide your Anthropic API key in settings.
  4. Start a new task and watch it go!