Skip to content

Instantly share code, notes, and snippets.

@paul-krohn
Last active October 8, 2024 13:32
Show Gist options
  • Save paul-krohn/e45f96181b1cf5e536325d1bdee6c949 to your computer and use it in GitHub Desktop.
Save paul-krohn/e45f96181b1cf5e536325d1bdee6c949 to your computer and use it in GitHub Desktop.
Docker X11 macOS

Preamble

There is a longstanding issue/missing feature/bug with sockets on Docker on macOS; it may never work; you'll need to use a network connection between Docker containers and X11 on macOS for the foreseeable future.

I started from this gist and made some adjustments:

  • the volume mappings aren't relevant/used, due to the socket issue above.
  • this method only allows X11 connections from your Mac, not the entire local network, which would include everyone on the café/airport WiFi.
  • updated to include using the host.docker.internal name for the the container host, instead.
  • you have to restart XQuartz after the config change.

Assumptions

  • you have a docker image with x11-apps (or the equivalent for not-ubuntu) installed
  • you have XQuartz installed (ie from Homebrew, brew cask install xquartz) and your PATH updated to include /opt/X11/bin and/or /usr/X11/bin.

Set up XQuartz

  1. Launch XQuartz. Under the XQuartz menu, select Preferences
  2. Go to the security tab and ensure "Allow connections from network clients" is checked.
  3. Restart XQuartz.

Every time you want to run an X11 program

  1. Make sure X11 is accepting connections from your host with xhost +$(hostname).local (if your Mac's name is So-and-So's Computer, you will need to do some fancy quoting and escaping).
  2. Set your DISPLAY environment variable to :0, eg export DISPLAY=:0.
  3. Test it from your Mac with xeyes.
  4. It works? Cool, one step fancier, from a container: docker run --rm -e DISPLAY=host.docker.internal:0 -it some-container-name xeyes
@zeldin
Copy link

zeldin commented Aug 19, 2022

Instead of xhost +localhost, you can use xauth for even better security.
First, you need to copy the magic cookie for :0 so that it is used also with the magic host.docker.internal address (192.168.65.2):

xauth add $(xauth list $DISPLAY | awk '{$1="192.168.65.2:0"; print}')

Then, add -v ~/.Xauthority:/tmp/.Xauthority -e XAUTHORITY=/tmp/.Xauthority to the Docker command line. Now it should work without xhost.

@arvganesh
Copy link

arvganesh commented Mar 14, 2023

Tested on MBP with an M1 Pro, OS X 12.5. Everything still works.

Details:

  • Used xhost + localhost in the XQuartz terminal.
  • Used -e DISPLAY=host.docker.internal:0 when running the container

I was trying to run a gymnasium environment which needed to use indirect GLX from within the container, so I had to run this command in my terminal on OS X: defaults write org.xquartz.X11 enable_iglx -bool true.

@rizvanovic
Copy link

M1 Pro macOS Monterey 12.3, works here too. Simply adding "-e DISPLAY=host.docker.internal:0" to runArgs fixed it.

Mounting the volume like you would on a linux machine - "--volume=/tmp/.X11-unix:/tmp/.X11-unix", with a containerEnv for the display - worked on my macOS machine for a couple months. Stopped working for some reason but this way works.

Appreciate the thread and gist.

@fabianem
Copy link

fabianem commented Nov 17, 2023

Instead of xhost +localhost, you can use xauth for even better security. First, you need to copy the magic cookie for :0 so that it is used also with the magic host.docker.internal address (192.168.65.2):

xauth add $(xauth list $DISPLAY | awk '{$1="192.168.65.2:0"; print}')

Then, add -v ~/.Xauthority:/tmp/.Xauthority -e XAUTHORITY=/tmp/.Xauthority to the Docker command line. Now it should work without xhost.

Unfortunately, this is not working for me.
How can I get it to work without using xhost + localhost every time?

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