Running Chromium inside Docker - Gtk: cannot open display: :0
Asked Answered
B

9

60

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
Bicycle answered 8/2, 2015 at 10:33 Comment(1)
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.Bruyn
L
77

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

Landgraviate answered 8/2, 2015 at 14:56 Comment(5)
stopping the container, running xhost + on the host and starting the container again did it for meLadoga
Or it seems you can do xhost +local:docker to be more restrictive.Emmett
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.Dwelt
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 https://mcmap.net/q/325540/-running-chromium-inside-docker-gtk-cannot-open-display-0 only allowing a local connectionThedrick
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.Lavone
F
49

Try

xhost local:root

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

Fortin answered 4/1, 2016 at 7:48 Comment(1)
Worked on Archlinux, think you, i can go full docker now!Fourdimensional
C
17

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
Cherubini answered 19/7, 2018 at 6:43 Comment(4)
Can u please provide a tiny explanation about this command?. It would be much helpful.Hamid
"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 aboveFuniculate
This answer was useful! (esp the XAuthority volume mount section) @Hamid Done!Seat
Why wouldn't you want to include most/all of the args after --priveleged in the Dockerfile itself?Farlie
M
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
Muscadine answered 19/7, 2021 at 1:51 Comment(0)
E
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>)

Elastance answered 21/9, 2020 at 13:38 Comment(1)
--network host is all I needed, when crawling through all the Internet.Royce
L
3

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.

Leninist answered 20/12, 2022 at 17:54 Comment(0)
P
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

Playroom answered 27/1, 2021 at 11:38 Comment(0)
H
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
Hollyanne answered 19/11, 2021 at 15:51 Comment(1)
(the script is for Windows's users, plus remember to flag "disable access control" when running xlaunch(VcXsrv)Hollyanne
S
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

Scot answered 31/3, 2023 at 7:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.