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.
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.
I have a small Spring Boot API running in docker. Shown below Is the command I used to up the container.
docker run -d --rm --name factorialorialContainer --memory=$2 --cpus=$3 -p 8080:8080 -e JAVA_OPTIONS="$(cat /Users/sulekahelmini/Documents/fyp/fyp_work/MLscripts/flags.txt)" suleka96/factorial:latest
Then I have a dockerized JMeter which I up using the below command
export volume_path=/Users/sulekahelmini/Documents/fyp/fyp_work/MLscripts/jmeter_resource && export jmeter_path=/jmeter && docker run --rm --name jmeterContainer --memory='512m' --cpus=2 -e JAVA_OPTS="-Xms512 -Xmx512" --volume ${volume_path}:${jmeter_path} egaillardon/jmeter --nongui -t factorial.jmx -l jmeter_results.jtl -q user.properties
but all the tests fail and requests are not getting sent to the API. This is how the CLI of JMeter looks
test config of request:
Protocol: htttp
Server: localhost
Port:8080
Method:GET
Path:/api/factorial
This is what the complete bash file looks like:
#!/bin/bash
cd /Users/sulekahelmini/Documents/fyp/fyp_work/demo/target && docker build . -t suleka96/factorial
docker run -d --rm --name factorialorialContainer --memory='512m' --cpus=2 -p 8080:8080 -e JAVA_OPTIONS="$(cat /Users/sulekahelmini/Documents/fyp/fyp_work/MLscripts/flags_base.txt)" suleka96/factorial:latest
sleep 15
#run test
export volume_path=/Users/sulekahelmini/Documents/fyp/fyp_work/MLscripts/jmeter_resource && export jmeter_path=/jmeter && docker run --rm --name jmeterContainer --memory='512m' --cpus=2 -e JAVA_OPTS="-Xms512 -Xmx512" --volume ${volume_path}:${jmeter_path} egaillardon/jmeter --nongui -t factorial.jmx -l jmeter_results.jtl -q user.properties
sleep 15
#jtl split
java -jar /Users/sulekahelmini/Documents/fyp/fyp_work/MLscripts/jtl-splitter-0.4.6-SNAPSHOT.jar -f /Users/sulekahelmini/Documents/fyp/fyp_work/MLscripts/jmeter_resource/jmeter_results.jtl -s -t 1;
docker stop factorialorialContainer
docker stop jmeterContainer
What am I doing wrong? How can I fix this?
You're doing wrong absolutely everything.
When it comes to Spring Boot even "small" API is not small at all, if you want something really small - consider i.e. Jersey
I fail to see why do you need containers at all, in your situation they don't add any value but only consume resources
You're running the application under test and the load generator at the same physical machine. Both can be very resource intensive when it comes to high load and you won't be able to tell for sure where is the bottleneck
If you still want to ignore previous 2 points and proceed: you're using localhost in JMeter container and there is nothing deployed on port 8080 in that container. You need to run the following command:
docker inspect factorialorialContainer
you will see a line which looks like:
"IPAddress": "xxx.xxx.xxx.xxx",
you will need to get this IP address from the docker inspect command output and replace the localhost with this IP address in the JMeter's HTTP Request sampler
References:
Docker Network
JMeter Distributed Testing with Docker
I'm trying to run an application from a Docker container which is supposed to open a GUI widow (a video stream in my case). The Docker container is run on a Raspberry Pi and I SSH into the Pi from my Mac and then I issue the Docker run command. I have one problem here:
When I run the whole thing as follows, it works flawlessly:
I run the command as:
docker run -it --net=host --device=/dev/vcsm --device=/dev/vchiq -e
DISPLAY -v /tmp/.X11-unix joesan/motion_detector bash
From the bash, that opens up after issuing the Docker run command, I install xauth
root#cctv:/raspi_motion_detection/project# apt-get install xauth
I then add the Xauth cookie using Xauth add
I then run my Python program which shows the GUI window with the video stream
So far so good. But, every time I don't want to be doing these steps all over again. So I wrote a small script to do this as below:
HOST=cctv
DISPLAY_NUMBER=$(echo $DISPLAY | cut -d. -f1 | cut -d: -f2)
echo $DISPLAY_NUMBER
# Extract auth cookie
AUTH_COOKIE=$(xauth list | grep "^$(hostname)/unix:${DISPLAY_NUMBER} " | awk '{print $3}')
# Add the xauth cookie to xauth
xauth add ${HOHOSTSTNAME}/unix:${DISPLAY_NUMBER} MIT-MAGIC-COOKIE-1 ${AUTH_COOKIE}
# Launch the container
docker run -it --net=host --device=/dev/vcsm --device=/dev/vchiq -e DISPLAY -v /tmp/.X11-unix joesan/motion_detector
But this time it fails with the error:
X11 connection rejected because of wrong authentication.
Unable to init server: Could not connect: Connection refused
I then tried to run the above script as a sudo user and I get the following:
xauth: file /root/.Xauthority does not exist
xauth: (argv):1: bad "add" command line
X11 connection rejected because of wrong authentication.
Unable to init server: Could not connect: Connection refused
Is there anything that I'm missing? Please help!
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