Running Chromium inside Docker - Gtk: cannot open display: :0

DockerX11Chromium

Docker Problem Overview


When I try to run chromium inside a docker container I see the following error: Gtk: cannot open display: :0

Dockerfile: (based on https://registry.hub.docker.com/u/jess/chromium/dockerfile)

FROM debian:jessie

# Install Chromium
RUN sed -i.bak 's/jessie main/jessie main contrib non-free/g' /etc/apt/sources.list && \
    apt-get update && apt-get install -y \
    chromium \
    chromium-l10n \
    libcanberra-gtk-module \
    libexif-dev \
    libpango1.0-0 \
    libv4l-0 \
    pepperflashplugin-nonfree \                                                                          
    --no-install-recommends && \
    mkdir -p /etc/chromium.d/

# Autorun x11vnc
CMD ["/usr/bin/chromium", "--no-sandbox", "--user-data-dir=/data"]

build and run:

docker build -t chromium
docker run -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --privileged chromium

and the error:

[1:1:0202/085603:ERROR:browser_main_loop.cc(164)] Running without the SUID sandbox! See https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more information on developing with the sandbox on.
No protocol specified
[1:1:0202/085603:ERROR:browser_main_loop.cc(210)] Gtk: cannot open display: :0

Docker Solutions


Solution 1 - Docker

i don't know much about chromium, but, I did work with X way back when :-) When you tell an X client to connect to :0, what you are saying is connect to port 6000 (or whatever your X server runs on) + 0, or port 6000 in this case. In fact, DISPLAY is IP:PORT (with the +6000 as mentioned above). The X server is running on your host, so, if you set:

DISPLAY=your_host_ip:0

that might work. However, X servers did not allow connections from just any old client, so, you will need to open up your X server. on your host, run

xhost +

before running the docker container. All of this is assuming you can run chromium on your host (that is, an X server exists on your host).

Solution 2 - Docker

Try

xhost local:root

This solve mine, I am on Debian Jessie. https://github.com/jfrazelle/dockerfiles/issues/4

Solution 3 - Docker

Adding as reference (see real answer from greg)

In your Linux host add

  xhost +"local:docker@"

In Docker image add

RUN apt-get update
RUN apt-get install -qqy x11-apps

and then run

sudo docker run \
	--rm \ # delete container when bash exits
	-it \ # connect TTY
	--privileged \
	--env DISPLAY=unix$DISPLAY \ # export DISPLAY env variable for X server
	-v $XAUTH:/root/.Xauthority \ # provide authority information to X server
	-v /tmp/.X11-unix:/tmp/.X11-unix \ # mount the X11 socket
	-v /home/alex/coding:/coding \
	alexcpn/nvidia-cuda-grpc:1.0 bash

Inside the container -check a sample command

xclock

Solution 4 - Docker

For Ubuntu 20.04, changing DISPLAY=:0 to DISPLAY=$DISPLAY fixed it for me, my local env had $DISPLAY set to :1:

docker run --rm -ti --net=host -e DISPLAY=$DISPLAY fr3nd/xeyes

Solution 5 - Docker

So, I also had a requirement to open a graphical application within my docker container. So, these are the steps that worked for my environment.(Docker version: 19.03.12 , Container OS: Ubuntu 18.04). Before running the container, make the host's X server accept connections from any client by running this command: xhost +. This is a very non-restrictive way to connect to the host's X server, and you can restrict as per the other answers given. Then, run the container with the --network=host option (E.g: docker run --network=host <my image name>). Once container is up, log in to its shell, and launch your app with DISPLAY=:0 (E.g: DISPLAY=:0 <my graphical app>)

Solution 6 - Docker

What is needed is an alias for your docker-hostname to the outer hostname. When using a DISPLAY starting with just a : it means localhost. Basically, your hostname inside docker needs to resolve via /etc/hosts to the same name as the outer host - because that is the name that is stored in .Xauthority

Solution 7 - Docker

I found this script to autoget ip of your pc:

FOR /F "tokens=4 delims= " %%i in ('route print ^| find " 0.0.0.0"') do set localIp=%%i

Create a bat file and put in this bat this:

FOR /F "tokens=4 delims= " %%i in ('route print ^| find " 0.0.0.0"') do set 
localIp=%%i
docker run -ti -v /tmp/.X11-unix -v /tmp/.docker.xauth -e 
XAUTHORITY=/tmp/.docker.xauth --net=host -e DISPLAY=%localIp%:0.0 your-container

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3538553View Question on Stackoverflow
Solution 1 - DockerGregView Answer on Stackoverflow
Solution 2 - DockerRANDRIAMILASOA StanislasView Answer on Stackoverflow
Solution 3 - DockerAlex PunnenView Answer on Stackoverflow
Solution 4 - DockerZaneView Answer on Stackoverflow
Solution 5 - DockerBinita BharatiView Answer on Stackoverflow
Solution 6 - DockerLars BerntzonView Answer on Stackoverflow
Solution 7 - DockerMatteo TomaView Answer on Stackoverflow