59

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
user3538553
  • 1,443
  • 3
  • 15
  • 21
  • You forgot the dot (for current dir) at the end of the command: "docker build -t chromium ." As newbies may get stuck on that, you maybe should correct that line. – Thomas Schütt Oct 28 '20 at 15:08

9 Answers9

76

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).

Greg
  • 6,571
  • 2
  • 27
  • 39
  • 1
    stopping the container, running `xhost +` on the host and starting the container again did it for me – GameScripting Jul 01 '15 at 19:40
  • 14
    Or it seems you can do `xhost +local:docker` to be more restrictive. – Andy Smith Jan 06 '16 at 17:50
  • 1
    If you do xhost + you will essentially disable accesscontrol to your xwindowssystem. So use a more restrictive xhost for instance xhost +SI:localuser:root if root is the user running your docker daemon. This will only allow a local socket connection, and not internet or networkhosts to access your xwindows. – opentokix Jun 09 '16 at 11:32
  • 20
    Though attractive, *DON'T DO THAT*. See the comment above. That solution basically **ALLOWS ANYONE TO CONNECT TO YOUR MACHINE**. Prefer using the more restrictive http://stackoverflow.com/a/34586732/345845 only allowing a local connection – Baptiste Mathus Jun 24 '16 at 13:36
  • 4
    Actually don't do either of those. Instead add `--network=host` to `docker run` parameters. This will allow your container to use your host's network stack making `-e DISPLAY=$DISPLAY` work as intended by OP. – Konrad Botor Sep 21 '20 at 13:43
48

Try

xhost local:root

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

15

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
Alex Punnen
  • 5,287
  • 3
  • 59
  • 71
  • 3
    Can u please provide a tiny explanation about this command?. It would be much helpful. – Whoami Feb 07 '19 at 14:29
  • "The xclock program displays the time in analog or digital form. The time is continuously updated at a fre‐quency which may be specified by the user." part of the x11-apps package installed above – Ben Poon Mar 13 '20 at 02:20
  • This answer was useful! (esp the XAuthority volume mount section) @Whoami Done! – IcyFlame Sep 05 '20 at 11:37
7

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
Zane
  • 4,652
  • 1
  • 29
  • 26
4

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>)

Binita Bharati
  • 5,239
  • 1
  • 43
  • 24
1

I got it to work on a Windows host but not on my Linux Mint (Ubuntu) host. The reason was that I was using Docker Desktop on Linux, which uses a VM under the hood.

Solution: Shut down Docker Desktop and install Docker Engine. Other than that, also do as in the other answers.

Julia
  • 1,950
  • 1
  • 9
  • 22
0

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

0

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
ouflak
  • 2,458
  • 10
  • 44
  • 49
Matteo Toma
  • 562
  • 5
  • 12
  • (the script is for Windows's users, plus remember to flag "disable access control" when running xlaunch(VcXsrv) – Matteo Toma Nov 19 '21 at 15:52
0

I use this list of commands

#host operating system; bash_shell1

i. environment debian11 MX-21.3_x64 ahs 


i. become sudo 
sudo su
password


i. docker restart
service docker restart


i. download/pull image 
docker pull ubuntu:jammy







i. check #dockerip
sudo ip addr show docker0
#output: 172.17.0.1





i. check ps
docker ps
#output:  CONTAINER ID      IMAGE               COMMAND             CREATED             STATUS              PORTS






i. check images
docker images

#output:
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu        jammy     08d22c0ceb15   3 weeks ago     77.8MB
hello-world   latest    feb5d9fea6a5   18 months ago   13.3kB




i. CONNECT/DISCONNET xserver
# Disallow X server connection
xhost -local:*

# Allow X server connection
xhost +local:*



i. set up gui/display etc
service docker restart
sleep 2
DISPLAY=:0
xhost +








i. only create docker container

containername=custom_container_001

SOCK=/tmp/.X11-unix docker run --name $containername -d -it --rm --privileged --volume "$HOME/.Xauthority:/root/.Xauthority:ro" -p 8080:8080 --network=host -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK ubuntu:jammy



i. execute bash 
docker exec -it $containername bash; history -a





-----------------------------


#guest operating system; bash_shell1

i. now we are inside the ubuntu container, install mousepad or xclock and runn it

apt update -y

apt install mousepad -y
mousepad


apt install x11-apps -y
xclock


#try this command too
apt install xclock -y
xclock





-----------------------------
#host operating system; bash_shell2
docker ps


CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
8af08xxxcc64   ubuntu:jammy   "/bin/bash"   20 minutes ago   Up 20 minutes             custom_container_001

quine9997
  • 685
  • 7
  • 13