Skip to content

Instantly share code, notes, and snippets.

@cschiewek
Last active November 6, 2024 12:03
Show Gist options
  • Save cschiewek/246a244ba23da8b9f0e7b11a68bf3285 to your computer and use it in GitHub Desktop.
Save cschiewek/246a244ba23da8b9f0e7b11a68bf3285 to your computer and use it in GitHub Desktop.
X11 in docker on macOS

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

  1. Install XQuartz: https://www.xquartz.org/
  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:
  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

@stevenirby
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

@DrSnowbird
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.

@ScottFred
Copy link

This was great! Thanks for providing this GIST!

@saikrn112
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

@pstoll
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

@Mirey007
Copy link

Mirey007 commented Jul 4, 2023

MacBook Pro ventura 13.3

Need set DISPLAY variable with prefix mac
-e DISPLAY=docker.for.mac.host.internal:0

docker run -p 8282:80 -e DISPLAY=docker.for.mac.host.internal:0 my docker

@marcospgp
Copy link

For those arriving from google like me: 2024 Dockerfile and compose.yaml for MacOS host:

FROM ubuntu:latest

# Install X11 and sample x11 apps
RUN apt-get update && \
    apt-get install -y x11-apps

# Open xclock on startup
CMD ["xclock"]
services:
  gui-app:
    build: .
    environment:
      - DISPLAY=host.docker.internal:0
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix

Before docker compose up, install xquartz and do enable network connections on settings security tab.

@harunkurtdev
Copy link

harunkurtdev commented Jan 23, 2024

Heyoo brotherss,

You can find on the this link,

I find some solution.

apptainer/singularity#5524 (comment)

on the link output

Ekran Resmi 2024-01-24 02 06 19

@jamesjmchugh
Copy link

For those arriving from google like me: 2024 Dockerfile and compose.yaml for MacOS host:

FROM ubuntu:latest

# Install X11 and sample x11 apps
RUN apt-get update && \
    apt-get install -y x11-apps

# Open xclock on startup
CMD ["xclock"]
services:
  gui-app:
    build: .
    environment:
      - DISPLAY=host.docker.internal:0
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix

Before docker compose up, install xquartz and do enable network connections on settings security tab.

I just wanted to post and confirm this worked for me in February 2024 on an m2 macbook. Thank you!

@amura87516
Copy link

For those arriving from google like me: 2024 Dockerfile and compose.yaml for MacOS host:

FROM ubuntu:latest

# Install X11 and sample x11 apps
RUN apt-get update && \
    apt-get install -y x11-apps

# Open xclock on startup
CMD ["xclock"]
services:
  gui-app:
    build: .
    environment:
      - DISPLAY=host.docker.internal:0
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix

Before docker compose up, install xquartz and do enable network connections on settings security tab.

I just wanted to post and confirm this worked for me in February 2024 on an m2 macbook. Thank you!

Somehow it didn't work on my M2 MacOS :(

Error: Can't open display: host.docker.internal:0
Screenshot 2024-02-26 at 10 24 40 PM

Any suggestion?

@ldipenti
Copy link

There shouldn't be a need of using "DISPLAY=host.docker.internal:0" and mounting the "/tmp/.X11-unix" socket file. I was able to make this work with just the DISPLAY envvar and enabling network connections and disabling connections auth in XQuartz settings.
Nevertheless, I think the ideal would be to just use the "/tmp/.X11-unix" file instead of network connections. I'm not being able to make this work even though the file seems to be correctly mounted inside the container.

@Tigatok
Copy link

Tigatok commented Apr 5, 2024

@ldipenti FTR I had to include the host.docker.internal:0, in 2024. I'm on a MacBook Pro 2024 m3 version.

Here is a working Dockerfile and Dockercompose:

FROM openjdk:11

# Install necessary packages for X11 or for your app
RUN apt-get update && apt-get install -y \
    libxext6 \
    libxrender1 \
    libxtst6 \
    x11-apps

# Set the working directory
WORKDIR /app

# Copy the source code into the container
COPY src /app/src
COPY dist/lib /app/lib

# Compile the Java application
RUN javac -cp "/app/lib/*" -d /app/bin /app/src/*.java

# Set the DISPLAY environment variable for X11 forwarding
ENV DISPLAY host.docker.internal:0

# Run the compiled Java application
CMD ["java", "-cp", "/app/bin:/app/lib/*", "MainClass"]
version: '3'
services:
  java-app:
    build: .
    image: java-app
    container_name: java-app-container
    environment:
      - _JAVA_OPTIONS="-Dsun.java2d.xrender=false"

I added the _JAVA_OPTIONS stuff cause I was getting some weird color errors on my swing ui.

@NovoG93
Copy link

NovoG93 commented May 24, 2024

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

@saikrn112 did you manage to use gazebo/rviz2 or any other gtk based application with docker on your mac?
I am facing the same issues

@R1kk3r
Copy link

R1kk3r commented Jul 8, 2024

Lot of comments here, not always correct. Here is the TL;DR.

Volume?

  volumes:
  - /tmp/.X11-unix:/tmp/.X11-unix

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:

libGL error: failed to load driver: swrast

You can try to indirect rendering by setting the export LIBGL_ALWAYS_INDIRECT=1

X request error?

If you get the following error:

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  149 (GLX)
  Minor opcode of failed request:  24 (X_GLXCreateNewContext)
  Value in failed request:  0x0
  Serial number of failed request:  25
  Current serial number in output stream:  26

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 to ping 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 to DISPLAY=host.docker.internal:1, if it is 6005 you should set to DISPLAY=host.docker.internal:5.

@taylorchu
Copy link

taylorchu commented Sep 29, 2024

@idossha
Copy link

idossha commented Oct 21, 2024

I was stuck on this for a while. Eventually I realized there might be a problem with Xquartz. Indeed after downgrading as suggested by @R1kk3r and following these steps below everything worked fine.

defaults write org.macosforge.xquartz.X11 nolisten_tcp -bool false
export DISPLAY=localhost:0
xhost +localhost
xhost +$(hostname)

Hope that helps.

@devnoname120
Copy link

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