Skip to content

Instantly share code, notes, and snippets.

@ailequal
Forked from sorny/x11_forwarding_macos_docker.md
Last active January 23, 2024 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ailequal/2a371a829585c863582c1cecf7639821 to your computer and use it in GitHub Desktop.
Save ailequal/2a371a829585c863582c1cecf7639821 to your computer and use it in GitHub Desktop.
X11 forwarding with macOS and Docker

X11 forwarding on macOS and docker

A quick guide on how to setup X11 forwarding on macOS when using docker containers requiring a DISPLAY.

This guide was tested on:

  • macOS Catalina 10.15.4
  • docker desktop 2.2.0.5 (43884) - stable release
  • XQuartz 2.7.11 (xorg-server 1.18.4)

Step-By-Step Guide

  1. Install XQuartz via brew

    $ brew cask install xquartz

  2. Logout and login of your Mac to activate XQuartz as default X11 server

  3. Start XQuartz

    $ open -a XQuartz

  4. Go to Security Settings and ensure that "Allow connections from network clients" is on

    alt XQuartz Security Stettings

  5. Restart your Mac and start XQuartz again`

    $ open -a XQuartz

  6. Check if XQuartz is setup and running correctly

    $ ps aux | grep Xquartz

  7. Ensure that XQuartz is running similar to this: /opt/X11/bin/Xquartz :0 -listen tcp

    :0 means the display is running on display port 0 Important is that its not saying –nolisten tcp which would block any X11 forwarding to the X11 display.

  8. Allow X11 forwarding via xhost

    $ xhost +

    This allows any client to connect. If you have security concerns you can append an IP address for a whitelist mechanism. You will always have to run xhost + after a restart of X11 as this is not a persistent setting.

  9. Time to test X11 forwarding

    Pull the following docker container, set the DISPLAY env and run it...

    $ docker pull sshipway/xclock
    $ ip=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
    $ docker run -e DISPLAY=$ip:0 sshipway/xclock
    

Success, good old XClock should be displayed on your screen :)

alt XClock

  1. Bonus for easier setup

    Set the two following lines inside your ".zshrc" file.

    # connect to X11 through IP display
    export IP=$(ipconfig getifaddr en0)
    export DISPLAY=$IP:0
    

    Then inside the "docker-compose.yml" set the interested image with the following option: network_mode: host.

  2. Bonus (yet again)

    You could avoid setting the DISPLAY variable from the host machine, by setting it inside the docker-compose.yml:

    environment:
      - DISPLAY=host.docker.internal:0
    

Conclusion

Your Mac is now an unsecured remote X11 server on the network, be aware of this! Stop XQuartz and X11 if you don't need it.

If you want a Docker container or actually any unix client to use your Mac as X11 server, simply set the DISPLAY env variable to your ip-address and display-port. For Docker containers, you can pass the DISPLAY variable via -e DISPLAY=ip:display-port or enter the container and set the DISPLAY env accordingly.

FAQs

Error: Can't open display: <ip>:0 → what to do?

Ensure you ran xhost + If error is still present, ensure XQuartz is allowing network connections. If cli-arg –nolisten tcp is set it wont allow any outside connections...

Error: No protocol specified. → what to do?

When you login through some kind of a display manager, a MIT-MAGIC-COOKIE-1 authentication cookie is created and written to your hosts ~/.Xauthority file. That file is read by X11 clients and the cookies available there are used to authenticate the connections. Thanks to @LevZaplatin for pointing out a workaround: Map your hosts ~/.Xauthority file into your docker container via -v ~/.Xauthority:/root/.Xauthority Applied to the XClock sample above:

$ docker run -v ~/.Xauthority:/root/.Xauthority -e DISPLAY=$ip:0 sshipway/xclock 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment