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

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

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

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

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

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

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

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.

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

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

Related

Cannot Connect to DISPLAY from docker container

I am following a basic tutorial in which we run abiword (some gui) from a docker container. For some reason, the container cannot find my display.
I am running on Ubuntu 20.04, on a x86_64 machine.
My Dockerfile:
FROM ubuntu
RUN apt update && apt install -y abiword
CMD abiword
My build command:
docker build -t abiword .
Before my run command, I add docker to my authorized xhosts:
mylinux#mylinux:$ xhost +local:docker
non-network local connections being added to access control list
mylinux#mylinux:$ xhost
access control enabled, only authorized clients can connect
LOCAL:
SI:localuser:lu20
I also tried xhost + to disable access control altogether, but no luck.
Run commands I've tried:
docker run -e DISPLAY=$(hostname -I | awk '{print $1}')$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix abiword
docker run -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix abiword
docker run -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix abiword
The volume I'm mounting does exist:
mylinux#mylinux:$ ls /tmp/.X11-unix/
X0 X1
In all cases, I get the same output:
** (abiword:7): WARNING **: 13:46:51.920: clutter failed 0, get a life.
No DISPLAY: this may not be what you want.
Any help is appreciated.

Can't run docker container in different user

I have 2 users on my ubuntu: personal and work. I created a docker image to run firefox in a container. To make things simple I added an alias in my .bash_aliases file to run it by typing "firefox" in terminal like so:
docker run --rm -d --name firefox \
-v $XDG_RUNTIME_DIR/pulse:$XDG_RUNTIME_DIR/pulse \
-e PULSE_SERVER=$XDG_RUNTIME_DIR/pulse/native \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=$DISPLAY \
--network host \
shallowduck/firefox:1.0
The problem is that firefox does not launch when I'm logged in as "work" user, only "personal".
When I run the command I get container id as output in terminal but nothing launches.
When I run docker ps, the container isn't there.
When I run docker ps -a, there is no trace that the container exited with an error or whatever.
Both users are part of the docker group.
I'm not sure what I'm missing. Any ideas would be appreciated.
I fixed this by running this command in terminal:
xhost +
This adds host names on the list of machines that can connect to X server. I forgot I had to run this command for each user.

GUI application via Docker - X11 - "Unable to init server"

I'm trying to run Firefox in a Debian docker image but can't connect to the X11 server.
I'm using the method described here, but changed the base image to the latest Debian. I also changed the user creation method.
Dockerfile
FROM debian:latest
RUN apt-get update && apt-get install -y firefox-esr
RUN useradd --shell /bin/bash --create-home developer && \
usermod -aG sudo developer
USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox
Building the container
docker build -t firefox .
Command to start the container
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
ERROR
Unable to init server: Could not connect: Connection refused
Error: cannot open display: :0
Operating system
OpenSUSE Leap 15.2
Context
I'm doing the above to understand how to run a GUI app via docker. The aim is to run the latest version of FreeCAD (v19), which is currently broken on OpenSUSE.
docker run --rm \
--net=host \
--env="DISPLAY" \
--volume="$HOME/.Xauthority:/home/developer/.Xauthority:rw" \
firefox
This should work with your Dockerfile!
Couple of points
.Xauthority file also needs to be shared as it holds the cookies and auth sessions for the X server. Hence it has to be read/write too.
If you dont want to do --net=host then you can listen on a TCP port bound to unix socket and forward that to the container.

How to run tmux inside a docker container?

I have some docker container running on a P2 instance.
In the past I run tmux in the P2 instance a run a docker container inside.
Afterwards I used
docker exec -it
to get into the running docker container.
I would like to avoid the above and be able to run tmux inside an existing container. hitting
tmux new -s <some name>
Doesn't do anything.
I assume that you want to connect to a docker container running remotely via tmux. In order to do this, you will have to run an ssh server within the container and attach to the tmux session using ssh. For example:
Create the container image with ssh and tmux installed. The Dockerfile might look like this:
FROM ubuntu:latest
RUN apt-get update && \
apt install -y tmux && \
apt install -y openssh-server && \
service ssh start && \
tmux new -s mysesh
EXPOSE 22/tcp
Run the container, and port forward the ssh port:
docker run -it -d -p 8654:22 <image name>
Attach to the tmux session:
ssh user#<hostname> -p 8654 -t "tmux a -t mysesh"
Note: tmux sessions are user specific, so ensure that the user exists in the container, and that the tmux session is started as the user within the container.
If tmux is already running in the container, it's as simple as docker attach container_name. (Docs.)
tmux might not be available in docker image, you can install it once you're attached to the docker container.
sudo apt install tmux
Then you should be able to execute
tmux new -s <some name>
Tried this on a P3 machine worked fine.
Reference: https://linuxize.com/post/getting-started-with-tmux/

Run Omnet++ inside docker with x11 forwarding on windows. SSH not working

Cannot ssh into container running on Windows hostmachine
For a university project i build a docker image containing Omnet++ to provide a consistent development environment.
The Image uses phusions's Baseimage and sets up x11 forwarding via SSH like rogaha did in his docker-desktop image.
The image works perfectly fine on a Linux Host System. But on Windows and OS X i was unable to ssh on the container from the host machine.
I reckon this is due to the different implementation of Docker on Windows and OS X. As explained in this Article by Microsoft Docker uses a NAT Network for Containers as a default to Separate the Networks from Host and Containers.
My problem is i don't know how to reach the running container via ssh.
I already tried the following:
Change the Container Network to a transparent Network as described in the Microsoft Article. The following error occurs both in Windows and OS X:
docker network create -d transparent MyTransparentNetwork
Error response from daemon: legacy plugin: plugin not found
On Windows run Docker in Virtualbox instead of Hyper-V
Explicitly expose port 22 like this:
docker run -p 52022:22 containerName
ssh -p 52022 root#ContainerIP
Dockerfile
FROM phusion/baseimage:latest
MAINTAINER Robin Finkbeiner
LABEL Description="Docker image for Nesting Stupro University of Stuttgart containing full omnet 5.1.1"
# Install dependencies
RUN apt-get update && apt-get install -y \
xpra\
rox-filer\
openssh-server\
pwgen\
xserver-xephyr\
xdm\
fluxbox\
sudo\
git \
xvfb\
wget \
build-essential \
gcc \
g++\
bison \
flex \
perl \
qt5-default\
tcl-dev \
tk-dev \
libxml2-dev \
zlib1g-dev \
default-jre \
doxygen \
graphviz \
libwebkitgtk-3.0-0 \
libqt4-opengl-dev \
openscenegraph-plugin-osgearth \
libosgearth-dev\
openmpi-bin\
libopenmpi-dev
# Set the env variable DEBIAN_FRONTEND to noninteractive
ENV DEBIAN_FRONTEND noninteractive
#Enabling SSH -- from phusion baseimage documentation
RUN rm -f /etc/service/sshd/down
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
# have to do that yourself. You may also comment out this instruction; the
# init system will auto-generate one during boot.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
# Copied command from https://github.com/rogaha/docker-desktop/blob/master/Dockerfile
# Configuring xdm to allow connections from any IP address and ssh to allow X11 Forwarding.
RUN sed -i 's/DisplayManager.requestPort/!DisplayManager.requestPort/g' /etc/X11/xdm/xdm-config
RUN sed -i '/#any host/c\*' /etc/X11/xdm/Xaccess
RUN ln -s /usr/bin/Xorg
RUN echo X11Forwarding yes >> /etc/ssh/ssh_config
# OMnet++ 5.1.1
# Create working directory
RUN mkdir -p /usr/omnetpp
WORKDIR /usr/omnetpp
# Fetch Omnet++ source
RUN wget https:******omnetpp-5.1.1-src-linux.tgz
RUN tar -xf omnetpp-5.1.1-src-linux.tgz
# Path
ENV PATH $PATH:/usr/omnetpp/omnetpp-5.1.1/bin
# Configure and compile
RUN cd omnetpp-5.1.1 && \
xvfb-run ./configure && \
make
# Cleanup
RUN apt-get clean && \
rm -rf /var/lib/apt && \
rm /usr/omnetpp/omnetpp-5.1.1-src-linux.tgz
Solution that worked for me
First of all the linked Microsoft Article is only valid for windows container.
This Article explains very well how docker networks work.
To simplify the explanation i drew a simple example.Simple ssh into docker network.
To be able to reach a container in bridged networks one is required to expose the necessary ports explicitly.
Expose Port
docker run -p 22 {$imageName}
Find Port mapping on host machine
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2ec2bd2b53b renderfehler/omnet_ide_baseimage "/sbin/my_init" 17 hours ago Up 17 hours 0.0.0.0:32773->22/tcp tender_newton
ssh onto container using mapped port
ssh -p 32772 root#0.0.0.0

Resources