- Install XQuartz: https://www.xquartz.org/
- Launch XQuartz. Under the XQuartz menu, select Preferences
- Go to the security tab and ensure "Allow connections from network clients" is checked.
- Run
xhost + ${hostname}
to allow connections to the macOS host * - Setup a HOSTNAME env var
export HOSTNAME=`hostname`
* - Add the following to your docker-compose:
environment:
- DISPLAY=${HOSTNAME}:0
volumes:
- /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
Lot of comments here, not always correct. Here is the TL;DR.
Volume?
This is useless, Docker Desktop does not support Unix socket (exception made for a very specific SSH case). A very good reading to get all the details https://briefcase.readthedocs.io/en/stable/how-to/internal/x11passthrough.html
The only solution is to use the network via the
DISPLAY=host.docker.internal:0
.libGL error?
If you get the following error:
You can try to indirect rendering by setting the
export LIBGL_ALWAYS_INDIRECT=1
X request error?
If you get the following error:
The latest Quartz version are buggy. I downgraded to 2.7.8 and everything works fine.
X connection error?
If you get
Error: Can't open display: host.docker.internal:0
, try toping host.docker.internal
. If it works, then the network is up and running but somehow Quartz is not listening/accepting the connection. Otherwise, this is a docker network issue. In the former case, you need to make sure the settings in Quartz are configured properly "allow connection + disable authorisation". Make sure to add in xhost and also try to reboot (sometimes, running/killing quartz to many times makes it unable to listen correctly on the port).In addition, starting/stopping XQuartz multiple times, it might have changed the port number. Run the command
sudo lsof -i -P | grep LISTEN | grep :$PORT
and make sure you see x11.bin using port 6000. If it uses something else, for example 6001, it means you need to adapt the DISPLAY toDISPLAY=host.docker.internal:1
, if it is 6005 you should set toDISPLAY=host.docker.internal:5
.