Skip to content

Instantly share code, notes, and snippets.

Last active November 26, 2023 23:00
Star You must be signed in to star a gist
What would you like to do?
X11 in docker on macOS

To forward X11 from inside a docker container to a host running macOS

  1. Install XQuartz:
  2. Launch XQuartz. Under the XQuartz menu, select Preferences
  3. Go to the security tab and ensure "Allow connections from network clients" is checked.
  4. Run xhost + ${hostname} to allow connections to the macOS host *
  5. Setup a HOSTNAME env var export HOSTNAME=`hostname`*
  6. Add the following to your docker-compose:
  - /tmp/.X11-unix:/tmp/.X11-unix

* It should be noted that steps 4 and 5 can be automated to run everytime XQuartz starts, but that's outside of the scope of this gist

Copy link

Thanks a lot Sir !
It works fine...

Copy link

it worked for me as well, but after restarting Quartz after step 3

Copy link

loadaverage commented Mar 27, 2018

Seems that ${hostname} is not correct, should it be ${HOSTNAME} or $(hostname)?
Anyway, I have troubles while trying binding X11 to UNIX socket, network connections works fine.
But it's not so comfortable for me.
UPDATE: nevermind, UNIX sockets are not supported yet
So, xhost or socat (UNIX socket->localhost port) is the only way to go.

Copy link

Works well!

Copy link

For my MacOS docker run to display X11, I need to set up docker run with "-e DISPLAY=host.docker.internal:0" and then it works!

Copy link

vmayoral commented Oct 29, 2019

+1 to -e DISPLAY=host.docker.internal:0 from @DrSnowbird, it seems that after the last Docker security updates, that form works and previous ones do not anymore.

Copy link

xeonqq commented Dec 24, 2019

Instead of step 4, I have to do the following:

IP=$(ifconfig en1 | grep inet | awk '$1=="inet" {print $2}')
/usr/X11/bin/xhost +
/usr/X11/bin/xhost + "$IP"

and +1 also to DrSnowbird

Copy link

Thanks for this, it really helped me out!

It seems things have moved a bit underneath all this since 2017, so I created an updated version.

Copy link

@xeonqq the first line you have allows ANY IP to access your X11 display not just the IP you added on the next line.

Copy link

I created a small example for running firefox inside a docker container here. If this fires up firefox on your mac, you are good to go.

Copy link

dozzman commented Oct 4, 2020

Thanks for this, it really helped me out!

It seems things have moved a bit underneath all this since 2017, so I created an updated version.

For anyone arriving... this link contains the only correctly current version. Steps to follow...

It also helped me understand why the volume mount doesn't do anything and what's really going on.

In short: (with optional explanation)

  1. From the XQuartz preferences, in the security tab, make sure Allow connections from network clients is enabled. Restart XQuartz.

NB: After restarting XQuartz, you can run netstat -an | grep -F 6000 to find that XQuartz has opened port 6000. This is actually how your docker container will be communicating with XQuartz on the host. The volume mount is not (and cannot due to an ongoing issue -- more details in the original link) be used.

  1. In a terminal on the host, run xhost +localhost.

NB: This will allow network X11 connections from localhost only, which is fine. Also if XQuartz is not running, xhost will start it.

  1. Pass -e DISPLAY=host.docker.internal:0 to any docker image you want to forward X to the host.

NB: host.docker.internal is the DNS name which resolves to your host machine from within your docker container. This will get X within the container to connect to port 6000 on your host and communicate with XQuartz -- the volume mount is entirely unused. You can also set the env var directly in the container with bash/Dockerfile/etc.

  1. Run your application.

NB: If all of the above steps were completed successfully, an X window should open on your host which is forwarding from the container. Debugging steps can be checked from the link above.

Much thanks to @paul-krohn for putting together his README which clarified a lot.

Copy link

Step 4: I have no xhost on my system. Or do I have to run this in the docker container?

Copy link

xhost is part of XQuartz and on my system is at /opt/X11/bin/xhost. Do you for sure have /opt/X11/bin in your PATH?

Copy link

Yes somehow after restarting it was available. Maybe PATH lookup issues.

Copy link

DrSnowbird commented Jul 15, 2021

The latest version of "DrSnowbird/jdk-mvn-py3-x11" already automatically" set up everything for you.

The latest version will automatically do all the necessary X11 setup for you except "the installation of xquartz" (running the '' will automatically launch XQuartz).

So, you don't have do anything to run X11 on your host machine regardless macOS, Ubuntu, or CentOS (due to the automation inside It is just as simple as below since "" script automatically does everything for you.

  1. First, "git clone"
  2. then, "cd jdk-mvn-py3-x11"
  3. then, "./" . Then, you should see the "xeyes" X11 application showing up on your desktop.
  4. try, "./" using a new X-terminal, then run "firefox" from command line, you see will Firefox browser popping up on your Desktop.

That's it!

Important: You don't have to do anything setup including xhost, HOSTNAME, etc. It is all automatically done in ""

  • "" script that It has everything automation (auto-detect your host's OS) setup for you except that, in macOS, you need to have 'xquartz' installed as the only manual effort when running on macOS - not for other Linux (e.g., Ubuntu, or CentOS).

PS: if you are still having trouble, my recommendation is to use "noVNC" using your web HTML 5 browsers to run as your desktop. You can access your Docker Container's desktop using any HTML 5 web browser. Please see:

Copy link

stevenirby commented Feb 12, 2022

I couldn't get it working without running it this way. (on an M1 Mac)

docker run -it --env="DISPLAY=host.docker.internal:0" -v /tmp/.X11-unix:/tmp/.X11-unix:rw <image name>

This did NOT work.

-e DISPLAY=host.docker.internal:0

Copy link

DrSnowbird commented Feb 21, 2022

Most likely you need to install XQuartz first on Mac to allow X11 to work to display to your Desktop. However, with the licensing fee requirements to run Docker with Docker-Desktop on Mac, I myself am not using Docker/Docker-Desktop anymore. I am using 100% Linux (Ubuntu/CentOS and other variations) now for all my open-source projects. Hence, I can't help much further now on Mac. There are many blogs that provide alternative Docker solutions.

Copy link

This was great! Thanks for providing this GIST!

Copy link

Hey all,
I am getting these errors when I am running gazebo from docker. Can someone help here?
I am using intel i5 Mac and docker version 20.10.8, build 3967b7d

libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
ALSA lib confmisc.c:855:(parse_card) cannot find card '0'
ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_card_inum returned error: No such file or directory
ALSA lib confmisc.c:422:(snd_func_concat) error evaluating strings
ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1334:(snd_func_refer) error evaluating name
ALSA lib conf.c:5178:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5701:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM default
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': No such file or directory
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast

Copy link

pstoll commented Nov 25, 2022

Adding a note of encouragement and thanks - I got my display working because of the instructions here.

FYI my setup - M1 MacBook Pro. So I'm using Rancher Desktop with a VM setup/dockerd.

Both of these worked for me getting a (gtk-based) x application runing inside an xterm inside XQuartz. fwiw I'm compiling the latests emacs (29.0) which has GTK support.

## using the `hostname` for the xhost & display
export HOSTNAME=`hostname`                                                                                   
xhost +${HOSTNAME}                                                                                           
docker run  -ti -v /tmp/.X11-unix:/tmp/.X11-unix -e "DISPLAY=${HOSTNAME}:0" pstoll/emacs-cross emacs         

And also

## Using localhost for both xhost & display: 
xhost +localhost                                                                                             
docker run  -ti -v /tmp/.X11-unix:/tmp/.X11-unix -e "DISPLAY=host.docker.internal:0" pstoll/emacs-cross emacs

Copy link

Mirey007 commented Jul 4, 2023

MacBook Pro ventura 13.3

Need set DISPLAY variable with prefix mac

docker run -p 8282:80 -e my docker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment