{"id":15957,"date":"2026-08-25T19:16:00","date_gmt":"2026-08-25T17:16:00","guid":{"rendered":"https:\/\/monodes.com\/predaelli\/?p=15957"},"modified":"2026-08-25T11:18:59","modified_gmt":"2026-08-25T09:18:59","slug":"how-to-run-gui-applications-in-docker-x11-forwarding-and-vnc","status":"publish","type":"post","link":"https:\/\/monodes.com\/predaelli\/2026\/08\/25\/how-to-run-gui-applications-in-docker-x11-forwarding-and-vnc\/","title":{"rendered":"How to Run GUI Applications in Docker (X11 Forwarding and VNC)"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view\">How to Run GUI Applications in Docker (X11 Forwarding and VNC)<\/a><\/h2>\n\n\n\n<!--more-->\n\n\n\n<!--nextpage-->\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<h1 class=\"wp-block-heading\">How to Run GUI Applications in Docker (X11 Forwarding and VNC)<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Learn how to run graphical applications inside Docker containers using X11 forwarding, VNC servers, and browser-based solutions for cross-platform GUI access.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Running GUI applications in Docker enables isolated desktop environments, reproducible development setups, and testing across different platforms. There are several approaches depending on your host OS and requirements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">X11 Forwarding (Linux Host)<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#x11-forwarding-linux-host\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">X11 forwarding shares the host&#8217;s display server with the container, providing the best performance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Basic X11 Forwarding<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#basic-x11-forwarding\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\"># Allow container to connect to X server\n\nxhost +local:docker\n\n# Run GUI application\ndocker run -it --rm \\\n    -e DISPLAY=$DISPLAY \\\n    -v \/tmp\/.X11-unix:\/tmp\/.X11-unix \\\n    firefox<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Secure X11 Forwarding<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#secure-x11-forwarding\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\"># More secure: allow only your local user, then run the container as that user\nxhost +SI:localuser:$(id -un)\n\ndocker run -it --rm \\\n    -e DISPLAY=$DISPLAY \\\n    -v \/tmp\/.X11-unix:\/tmp\/.X11-unix \\\n    --user $(id -u):$(id -g) \\\n    firefox<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Docker Compose with X11<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#docker-compose-with-x11\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">services:\n  gui-app:\n    image: my-gui-app\n    environment:\n      - DISPLAY=${DISPLAY}\n    volumes:\n      - \/tmp\/.X11-unix:\/tmp\/.X11-unix:rw\n      - ${HOME}\/.Xauthority:\/root\/.Xauthority:ro\n    network_mode: host<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Custom Dockerfile for X11<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#custom-dockerfile-for-x11\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">FROM ubuntu:22.04\n\n# Install GUI dependencies\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    libx11-6 \\\n    libxext6 \\\n    libxrender1 \\\n    libxtst6 \\\n    libxi6 \\\n    libfreetype6 \\\n    fontconfig \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Install your application\nRUN apt-get update &amp;&amp; apt-get install -y firefox &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Run as non-root for security\nRUN useradd -m appuser\nUSER appuser\n\nCMD [&quot;firefox&quot;]<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">VNC Server in Container<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#vnc-server-in-container\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">VNC provides remote desktop access, works on any host OS, and offers better isolation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Basic VNC Setup<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#basic-vnc-setup\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">FROM ubuntu:22.04\n\nENV DEBIAN_FRONTEND=noninteractive\n\n# Install VNC server and desktop environment\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    tigervnc-standalone-server \\\n    tigervnc-common \\\n    dbus-x11 \\\n    xfce4 \\\n    xfce4-goodies \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Install your applications\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    firefox \\\n    gedit \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Create user\nRUN useradd -m -s \/bin\/bash vncuser &amp;&amp; \\\n    echo &quot;vncuser:password&quot; | chpasswd\n\nUSER vncuser\nWORKDIR \/home\/vncuser\n\n# VNC configuration\nRUN mkdir -p ~\/.vnc &amp;&amp; \\\n    echo &quot;password&quot; | vncpasswd -f &gt; ~\/.vnc\/passwd &amp;&amp; \\\n    chmod 600 ~\/.vnc\/passwd\n\n# VNC startup script\nRUN echo &#039;#!\/bin\/bash\\n\\\nstartxfce4 &amp;\\n\\\n&#039; &gt; ~\/.vnc\/xstartup &amp;&amp; chmod +x ~\/.vnc\/xstartup\n\nEXPOSE 5901\n\nCMD [&quot;vncserver&quot;, &quot;-localhost&quot;, &quot;no&quot;, &quot;-geometry&quot;, &quot;1920x1080&quot;, &quot;-depth&quot;, &quot;24&quot;, &quot;:1&quot;, &quot;-fg&quot;]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Docker Compose with VNC<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#docker-compose-with-vnc\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">services:\n  vnc-desktop:\n    build: .\n    ports:\n      - &quot;5901:5901&quot;\n    environment:\n      - VNC_PASSWORD=secret\n    volumes:\n      - vnc-home:\/home\/vncuser\n    shm_size: &#039;256mb&#039;\n\nvolumes:\n  vnc-home:<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Connect with any VNC client to <code class=\"\" data-line=\"\">localhost:5901<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">noVNC (Browser-Based VNC)<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#novnc-browser-based-vnc\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">noVNC provides VNC access through a web browser-no client installation needed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dockerfile with noVNC<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#dockerfile-with-novnc\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">FROM ubuntu:22.04\n\nENV DEBIAN_FRONTEND=noninteractive\n\n# Install desktop environment and VNC\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    tigervnc-standalone-server \\\n    novnc \\\n    websockify \\\n    xfce4 \\\n    xfce4-terminal \\\n    dbus-x11 \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Install applications\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    firefox \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Create user\nRUN useradd -m vncuser\nUSER vncuser\nWORKDIR \/home\/vncuser\n\n# Setup VNC\nRUN mkdir -p ~\/.vnc &amp;&amp; \\\n    echo &quot;password&quot; | vncpasswd -f &gt; ~\/.vnc\/passwd &amp;&amp; \\\n    chmod 600 ~\/.vnc\/passwd\n\nCOPY --chown=vncuser:vncuser startup.sh \/home\/vncuser\/\nRUN chmod +x \/home\/vncuser\/startup.sh\n\nEXPOSE 6080\n\nCMD [&quot;\/home\/vncuser\/startup.sh&quot;]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">startup.sh:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">#!\/bin\/bash\n\n# Start VNC server\nvncserver -localhost yes -geometry 1920x1080 -depth 24 :1\n\n# Start noVNC\n\/usr\/share\/novnc\/utils\/novnc_proxy \\\n    --vnc localhost:5901 \\\n    --listen 6080\n\n# Keep running\ntail -f \/dev\/null<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Docker Compose with noVNC<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#docker-compose-with-novnc\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">services:\n  desktop:\n    build: .\n    ports:\n      - &quot;6080:6080&quot;\n    environment:\n      - VNC_RESOLUTION=1920x1080\n    volumes:\n      - desktop-data:\/home\/vncuser\n    shm_size: &#039;512mb&#039;\n\nvolumes:\n  desktop-data:<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Access via browser at <code class=\"\" data-line=\"\">http:\/\/localhost:6080<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">X11 on macOS<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#x11-on-macos\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">macOS doesn&#8217;t have a native X11 server. Use XQuartz.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setup XQuartz<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#setup-xquartz\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\"># Install XQuartz\nbrew install --cask xquartz\n\n# Start XQuartz and enable network connections\n# XQuartz -&gt; Preferences -&gt; Security -&gt; &quot;Allow connections from network clients&quot;\n\n# Restart XQuartz, then:\nxhost +localhost\n\n# Run container\ndocker run -it --rm \\\n    -e DISPLAY=host.docker.internal:0 \\\n    -v \/tmp\/.X11-unix:\/tmp\/.X11-unix \\\n    firefox<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Docker Compose for macOS<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#docker-compose-for-macos\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">services:\n  gui-app:\n    image: my-gui-app\n    environment:\n      - DISPLAY=host.docker.internal:0\n    volumes:\n      - \/tmp\/.X11-unix:\/tmp\/.X11-unix<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">X11 on Windows (WSL2)<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#x11-on-windows-wsl2\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">With WSL2 and WSLg, X11 applications work natively.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">WSLg (Windows 11)<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#wslg-windows-11\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\"># WSLg provides automatic X11 support\ndocker run -it --rm \\\n    -e DISPLAY=$DISPLAY \\\n    -v \/tmp\/.X11-unix:\/tmp\/.X11-unix \\\n    -e WAYLAND_DISPLAY=$WAYLAND_DISPLAY \\\n    -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \\\n    -e PULSE_SERVER=$PULSE_SERVER \\\n    -v \/mnt\/wslg:\/mnt\/wslg \\\n    firefox<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Using VcXsrv (Windows 10)<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#using-vcxsrv-windows-10\"><\/a><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Install VcXsrv<\/li>\n\n\n\n<li>Start XLaunch with &#8220;Disable access control&#8221;<\/li>\n\n\n\n<li>Run container:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\"># Get Windows host IP\nexport DISPLAY=$(cat \/etc\/resolv.conf | grep nameserver | awk &#039;{print $2}&#039;):0\n\ndocker run -it --rm \\\n    -e DISPLAY=$DISPLAY \\\n    firefox<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Complete Desktop Environment<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#complete-desktop-environment\"><\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Full Ubuntu Desktop<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#full-ubuntu-desktop\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">FROM ubuntu:22.04\n\nENV DEBIAN_FRONTEND=noninteractive\n\n# Install full desktop\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    ubuntu-desktop \\\n    xfce4 \\\n    xfce4-goodies \\\n    dbus-x11 \\\n    tigervnc-standalone-server \\\n    novnc \\\n    websockify \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Clean up\nRUN apt-get clean\n\n# Create user\nRUN useradd -m -s \/bin\/bash -G sudo developer &amp;&amp; \\\n    echo &quot;developer:developer&quot; | chpasswd\n\nUSER developer\nWORKDIR \/home\/developer\n\n# VNC setup\nRUN mkdir -p ~\/.vnc &amp;&amp; \\\n    echo &quot;password&quot; | vncpasswd -f &gt; ~\/.vnc\/passwd &amp;&amp; \\\n    chmod 600 ~\/.vnc\/passwd &amp;&amp; \\\n    echo &#039;#!\/bin\/bash\\nstartxfce4 &amp;&#039; &gt; ~\/.vnc\/xstartup &amp;&amp; \\\n    chmod +x ~\/.vnc\/xstartup\n\nEXPOSE 5901 6080\n\nCOPY --chown=developer:developer entrypoint.sh \/home\/developer\/\nENTRYPOINT [&quot;\/home\/developer\/entrypoint.sh&quot;]<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">entrypoint.sh:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">#!\/bin\/bash\nset -e\n\n# Start VNC\nvncserver -localhost yes -geometry ${RESOLUTION:-1920x1080} :1\n\n# Start noVNC\n\/usr\/share\/novnc\/utils\/novnc_proxy --vnc localhost:5901 --listen 6080 &amp;\n\n# Keep container running\nexec tail -f \/dev\/null<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Development Environment with IDE<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#development-environment-with-ide\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">services:\n  dev-desktop:\n    build:\n      context: .\n      dockerfile: Dockerfile.dev\n    ports:\n      - &quot;6080:6080&quot;  # noVNC\n      - &quot;5901:5901&quot;  # VNC\n    volumes:\n      - .\/workspace:\/home\/developer\/workspace\n      - vscode-extensions:\/home\/developer\/.vscode\n    environment:\n      - RESOLUTION=1920x1080\n    shm_size: &#039;2gb&#039;\n\nvolumes:\n  vscode-extensions:<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dockerfile.dev:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">FROM ubuntu:22.04\n\nENV DEBIAN_FRONTEND=noninteractive\n\n# Desktop environment\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    xfce4 \\\n    xfce4-terminal \\\n    tigervnc-standalone-server \\\n    novnc \\\n    websockify \\\n    dbus-x11 \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Development tools\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    ca-certificates \\\n    curl \\\n    git \\\n    gnupg \\\n    sudo \\\n    build-essential \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Install VS Code\nRUN curl -fsSL https:\/\/packages.microsoft.com\/keys\/microsoft.asc | gpg --dearmor -o \/usr\/share\/keyrings\/microsoft.gpg &amp;&amp; \\\n    echo &quot;deb [signed-by=\/usr\/share\/keyrings\/microsoft.gpg] https:\/\/packages.microsoft.com\/repos\/code stable main&quot; &gt; \/etc\/apt\/sources.list.d\/vscode.list &amp;&amp; \\\n    apt-get update &amp;&amp; apt-get install -y code &amp;&amp; \\\n    rm -rf \/var\/lib\/apt\/lists\/*\n\n# Create developer user\nRUN useradd -m -s \/bin\/bash developer &amp;&amp; \\\n    echo &quot;developer ALL=(ALL) NOPASSWD:ALL&quot; &gt;&gt; \/etc\/sudoers\n\nUSER developer\nWORKDIR \/home\/developer\n\n# VNC configuration\nRUN mkdir -p ~\/.vnc &amp;&amp; \\\n    echo &quot;password&quot; | vncpasswd -f &gt; ~\/.vnc\/passwd &amp;&amp; \\\n    chmod 600 ~\/.vnc\/passwd &amp;&amp; \\\n    echo -e &#039;#!\/bin\/bash\\nstartxfce4 &amp;&#039; &gt; ~\/.vnc\/xstartup &amp;&amp; \\\n    chmod +x ~\/.vnc\/xstartup\n\nCOPY --chown=developer:developer entrypoint.sh \/home\/developer\/\nEXPOSE 5901 6080\nENTRYPOINT [&quot;\/home\/developer\/entrypoint.sh&quot;]<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Handling Audio<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#handling-audio\"><\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">PulseAudio Forwarding<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#pulseaudio-forwarding\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\"># On host, allow network audio\npactl load-module module-native-protocol-tcp auth-anonymous=1\n\n# Run container with audio\ndocker run -it --rm \\\n    -e DISPLAY=$DISPLAY \\\n    -v \/tmp\/.X11-unix:\/tmp\/.X11-unix \\\n    -e PULSE_SERVER=tcp:$(hostname -I | awk &#039;{print $1}&#039;):4713 \\\n    my-audio-app<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Docker Compose with Audio<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#docker-compose-with-audio\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">services:\n  multimedia:\n    image: my-multimedia-app\n    extra_hosts:\n      - &quot;host.docker.internal:host-gateway&quot;\n    environment:\n      - DISPLAY=${DISPLAY}\n      - PULSE_SERVER=tcp:host.docker.internal:4713\n    volumes:\n      - \/tmp\/.X11-unix:\/tmp\/.X11-unix\n      - ${HOME}\/.config\/pulse:\/root\/.config\/pulse:ro<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">GPU Acceleration for GUI<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#gpu-acceleration-for-gui\"><\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">OpenGL Support<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#opengl-support\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">docker run -it --rm \\\n    --gpus all \\\n    -e DISPLAY=$DISPLAY \\\n    -v \/tmp\/.X11-unix:\/tmp\/.X11-unix \\\n    -e NVIDIA_DRIVER_CAPABILITIES=all \\\n    nvidia\/opengl:1.2-glvnd-runtime-ubuntu22.04 \\\n    bash -lc &quot;apt-get update &amp;&amp; apt-get install -y mesa-utils &amp;&amp; glxgears&quot;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Dockerfile with GPU and GUI<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#dockerfile-with-gpu-and-gui\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">FROM nvidia\/opengl:1.2-glvnd-runtime-ubuntu22.04\n\nRUN apt-get update &amp;&amp; apt-get install -y \\\n    mesa-utils \\\n    libgl1-mesa-glx \\\n    &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# Your GPU-accelerated GUI application\nRUN apt-get update &amp;&amp; apt-get install -y blender &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\nCMD [&quot;blender&quot;]<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#troubleshooting\"><\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Common X11 Issues<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#common-x11-issues\"><\/a><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Error<\/th><th>Cause<\/th><th>Solution<\/th><\/tr><tr><td><code class=\"\" data-line=\"\">cannot open display<\/code><\/td><td>X server not accessible<\/td><td>Run <code class=\"\" data-line=\"\">xhost +local:docker<\/code><\/td><\/tr><tr><td><code class=\"\" data-line=\"\">No protocol specified<\/code><\/td><td>Xauthority issue<\/td><td>Mount <code class=\"\" data-line=\"\">~\/.Xauthority<\/code><\/td><\/tr><tr><td><code class=\"\" data-line=\"\">Xlib: extension missing<\/code><\/td><td>Missing GL libraries<\/td><td>Install mesa-utils<\/td><\/tr><tr><td><code class=\"\" data-line=\"\">Connection refused<\/code><\/td><td>Wrong DISPLAY<\/td><td>Check <code class=\"\" data-line=\"\">echo $DISPLAY<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">VNC Issues<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#vnc-issues\"><\/a><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Error<\/th><th>Cause<\/th><th>Solution<\/th><\/tr><tr><td>Black screen<\/td><td>Desktop not starting<\/td><td>Check xstartup script<\/td><\/tr><tr><td>Connection timeout<\/td><td>Port not exposed<\/td><td>Verify port mapping<\/td><\/tr><tr><td>Authentication failed<\/td><td>Wrong password<\/td><td>Reset VNC password<\/td><\/tr><tr><td>Slow performance<\/td><td>Low color depth<\/td><td>Use <code class=\"\" data-line=\"\">-depth 24<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Debug Commands<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#debug-commands\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\"># Check if X socket exists\nls -la \/tmp\/.X11-unix\/\n\n# Verify DISPLAY variable\necho $DISPLAY\n\n# Test X connection\nxdpyinfo\n\n# Check container logs for VNC\ndocker logs vnc-container<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Security Considerations<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#security-considerations\"><\/a><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Method<\/th><th>Security Level<\/th><th>Notes<\/th><\/tr><tr><td>X11 with xhost +local:<\/td><td>Low<\/td><td>Container can access host X server<\/td><\/tr><tr><td>X11 with Xauthority<\/td><td>Medium<\/td><td>Better isolation<\/td><\/tr><tr><td>VNC<\/td><td>High<\/td><td>Network accessible, use strong password<\/td><\/tr><tr><td>noVNC over HTTPS<\/td><td>High<\/td><td>Add TLS termination<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Secure noVNC with TLS<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#secure-novnc-with-tls\"><\/a><\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">Copy<code class=\"\" data-line=\"\">services:\n  desktop:\n    image: vnc-desktop\n    ports:\n      - &quot;6080:6080&quot;\n\n  nginx:\n    image: nginx:alpine\n    ports:\n      - &quot;443:443&quot;\n    volumes:\n      - .\/nginx.conf:\/etc\/nginx\/nginx.conf:ro\n      - .\/certs:\/etc\/nginx\/certs:ro\n    depends_on:\n      - desktop<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<a href=\"https:\/\/oneuptime.com\/blog\/post\/2026-01-16-docker-gui-apps-x11-vnc\/view#summary\"><\/a><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Method<\/th><th>Best For<\/th><th>Host OS<\/th><\/tr><tr><td>X11 Forwarding<\/td><td>Performance, Linux hosts<\/td><td>Linux<\/td><\/tr><tr><td>XQuartz + X11<\/td><td>macOS development<\/td><td>macOS<\/td><\/tr><tr><td>WSLg<\/td><td>Windows 11 native<\/td><td>Windows 11<\/td><\/tr><tr><td>VNC<\/td><td>Cross-platform, isolation<\/td><td>Any<\/td><\/tr><tr><td>noVNC<\/td><td>Browser access, no client<\/td><td>Any<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Choose X11 forwarding for best performance on Linux, VNC for cross-platform compatibility and better isolation, and noVNC for easy browser-based access without client installation. For production use cases, always secure VNC connections with strong passwords and TLS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/twitter.com\/intent\/tweet?text=%20How%20to%20Run%20GUI%20Applications%20in%20Docker%20(X11%20Forwarding%20and%20VNC)&amp;url=https%3A%2F%2Foneuptime.com%2Fblog%2Fpost%2F2026-01-16-docker-gui-apps-x11-vnc%2Fview\"><\/a><a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=https%3A%2F%2Foneuptime.com%2Fblog%2Fpost%2F2026-01-16-docker-gui-apps-x11-vnc%2Fview\"> <\/a><a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/news.ycombinator.com\/submitlink?u=https%3A%2F%2Foneuptime.com%2Fblog%2Fpost%2F2026-01-16-docker-gui-apps-x11-vnc%2Fview&amp;t=%20How%20to%20Run%20GUI%20Applications%20in%20Docker%20(X11%20Forwarding%20and%20VNC)\"><\/a><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignleft is-resized\"><img decoding=\"async\" src=\"https:\/\/avatars.githubusercontent.com\/nawazdhandala\" alt=\"Nawaz Dhandala\" style=\"width:80px;height:80px\"\/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Nawaz Dhandala  is building OneUptime with a passion for engineering reliable systems and improving observability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/nawazdhandala\" target=\"_blank\" rel=\"noopener\">GitHub<\/a><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p class=\"excerpt\">How to Run GUI Applications in Docker (X11 Forwarding and VNC)<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"https:\/\/monodes.com\/predaelli\/2026\/08\/25\/how-to-run-gui-applications-in-docker-x11-forwarding-and-vnc\/\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"link","meta":{"inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"federated","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false,"_members_access_role":[],"_members_access_error":""},"categories":[1],"tags":[],"class_list":["post-15957","post","type-post","status-publish","format-link","hentry","category-senza-categoria","post_format-post-format-link"],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6daft-49n","jetpack-related-posts":[{"id":15182,"url":"https:\/\/monodes.com\/predaelli\/2026\/02\/25\/remote-desktop-on-wayland-in-2026\/","url_meta":{"origin":15957,"position":0},"title":"Remote Desktop on Wayland in 2026","author":"Paolo Redaelli","date":"2026-02-25","format":false,"excerpt":"Remote Desktop on Wayland in 2025: What Changed for Linux Support Engineers | Stackademic Wayland is now the default across most modern Linux desktops, and that quietly breaks a lot of X11-era support playbooks. If your helpdesk still relies on \u201cglobal screen grabbers\u201d or legacy VNC expectations, you\u2019ll hit confusing\u2026","rel":"","context":"In &quot;Tricks&quot;","block_context":{"text":"Tricks","link":"https:\/\/monodes.com\/predaelli\/category\/documentations\/tricks\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1749,"url":"https:\/\/monodes.com\/predaelli\/2016\/09\/05\/owncloud-on-docker-in-10-steps\/","url_meta":{"origin":15957,"position":1},"title":"Owncloud on docker in 10 steps","author":"Paolo Redaelli","date":"2016-09-05","format":"link","excerpt":"Yea, there is a docker image: https:\/\/hub.docker.com\/r\/l3iggs\/owncloud\/ Literally, it is like 10 commands to get your firewall setup, let's encrypt setup and have an accessible HTTPS owncloud instance.... it is amazeballs - best of luck","rel":"","context":"In &quot;Software Libero&quot;","block_context":{"text":"Software Libero","link":"https:\/\/monodes.com\/predaelli\/category\/software\/software-libero\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1628,"url":"https:\/\/monodes.com\/predaelli\/2016\/06\/02\/flatpak-the-future-of-application-distribution\/","url_meta":{"origin":15957,"position":2},"title":"Flatpak &#8211; the future of application distribution","author":"Paolo Redaelli","date":"2016-06-02","format":"link","excerpt":"http:\/\/flatpak.org\/ I shall keep an eye on it. Sounds like docker like","rel":"","context":"In &quot;Senza categoria&quot;","block_context":{"text":"Senza categoria","link":"https:\/\/monodes.com\/predaelli\/category\/senza-categoria\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2358,"url":"https:\/\/monodes.com\/predaelli\/2017\/04\/14\/x2go-remote-desktop-faster-than-vnc\/","url_meta":{"origin":15957,"position":3},"title":"X2Go, remote desktop faster than VNC","author":"Paolo Redaelli","date":"2017-04-14","format":false,"excerpt":"Sometimes VNC feels too slow, expecially other slow links. Enters X2Go - everywhere@home! X2Go enables you to access a graphical desktop of a computer over a low bandwidth (or high bandwidth) connection.X2Go is a Remote Desktop solution, which some vendors vaguely call Remote Control. This is not to be confused\u2026","rel":"","context":"In &quot;Software&quot;","block_context":{"text":"Software","link":"https:\/\/monodes.com\/predaelli\/category\/software\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":12725,"url":"https:\/\/monodes.com\/predaelli\/2025\/02\/09\/nginx-proxy-manager\/","url_meta":{"origin":15957,"position":4},"title":"Nginx Proxy Manager","author":"Paolo Redaelli","date":"2025-02-09","format":"link","excerpt":"Nginx Proxy Manager comes as a pre-built docker image that enables you to easily forward to your websites running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt. \u00a0","rel":"","context":"In &quot;Senza categoria&quot;","block_context":{"text":"Senza categoria","link":"https:\/\/monodes.com\/predaelli\/category\/senza-categoria\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13954,"url":"https:\/\/monodes.com\/predaelli\/2026\/02\/16\/first-came-wine\/","url_meta":{"origin":15957,"position":5},"title":"First came Wine\u2026","author":"Paolo Redaelli","date":"2026-02-16","format":false,"excerpt":"First came Wine, i.e. Wine Is Not an Emulator, a free-as-in-freedom re-implementation of Windows API, allowing to run Windows application with various grade of effectiveness. Then came those: WinBoat Run Windows apps on \ud83d\udc27 Linux with \u2728 seamless integration, which uses WinApps Run Windows apps such as Microsoft Office\/Adobe in\u2026","rel":"","context":"In &quot;Wine&quot;","block_context":{"text":"Wine","link":"https:\/\/monodes.com\/predaelli\/category\/wine\/"},"img":{"alt_text":"","src":"https:\/\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2026\/02\/winboat_logo.svg","width":350,"height":200,"srcset":"https:\/\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2026\/02\/winboat_logo.svg 1x, https:\/\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2026\/02\/winboat_logo.svg 1.5x, https:\/\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2026\/02\/winboat_logo.svg 2x, https:\/\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2026\/02\/winboat_logo.svg 3x"},"classes":[]}],"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/15957","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/comments?post=15957"}],"version-history":[{"count":1,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/15957\/revisions"}],"predecessor-version":[{"id":15959,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/15957\/revisions\/15959"}],"wp:attachment":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/media?parent=15957"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/categories?post=15957"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/tags?post=15957"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}