Xt error: Can't open display, if using default DISPLAY - macos

Overview
I'm attempting to get XQuartz to work on OSX so I can do X11 forwarding via Docker. I'm following the instructions here. I believe my question may be answered by just the first part, but just in case (to avoid the XY problem), I've provided the second part as well.
Installation
I've installed it via homebrew, via brew cask install xquartz. Then I open -a XQuartz to start it.
Local xterms
Testing it out, if I try to open an xterm, it does not work:
MacBook-Pro:opencv-gui csaftoiu$ xterm
xterm: Xt error: Can't open display: /private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0
The pseudo-file exists, though:
MacBook-Pro:opencv-gui csaftoiu$ echo $DISPLAY
/private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0
MacBook-Pro:opencv-gui csaftoiu$ ls -alh $DISPLAY
srw-rw-rw- 1 csaftoiu wheel 0B May 6 21:12 /private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0
I can open an xterm via XQuartz. Then:
bash-3.2$ echo $DISPLAY
:0
This value works from a regular OSX too:
$ DISPLAY=:0 xterm
# opens xterm, waits for it to finish
$
The following do not work though, not sure why based on the answer here:
xterm: Xt error: Can't open display: localhost:0
MacBook-Pro:opencv-gui csaftoiu$ DISPLAY=127.0.0.1:0 xterm
xterm: Xt error: Can't open display: 127.0.0.1:0
MacBook-Pro:opencv-gui csaftoiu$ DISPLAY=`ipconfig getifaddr en0`:0 xterm
xterm: Xt error: Can't open display: 192.168.1.15:0
Note that xinit does work for some reason:
$ xinit
xinit: XFree86_VT property unexpectedly has 0 items instead of 1
# opens xterm, waits for it to finish
xinit: connection to X server lost
waiting for X server to shut down
Question 1: What is XQuartz actually listening on?
Docker Forwarding with socat
In any case, moving on, this socat command does not work:
MacBook-Pro:opencv-gui csaftoiu$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
Running that, from another window I do:
MacBook-Pro:opencv-gui csaftoiu$ docker run --rm -it -e DISPLAY=`ipconfig getifaddr en0`:0 ubuntu:14.04 bash
root#912eec31b8cb:/# apt-get update && apt-get install xterm
... such install, wow ...
root#912eec31b8cb:/# xterm
Warning: This program is an suid-root program or is being run by the root user.
The full text of the error or warning message cannot be safely formatted
in this environment. You may get a more descriptive message by running the
program as a non-root user or by removing the suid bit on the executable.
xterm: Xt error: Can't open display: %s
root#912eec31b8cb:/# echo $DISPLAY
192.168.1.15:0
From the socat window I get:
2016/06/14 21:08:15 socat[24289] E connect(5, LEN=68 AF=1 "/private/tmp/com.apple.launchd.3wncZULdXC/org.macosforge.xquartz:0", 68): Connection refused
I can't use the DISPLAY variable that works, either:
MacBook-Pro:opencv-gui csaftoiu$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\":0\"
2016/06/14 21:09:43 socat[24309] E connect(5, LEN=4 AF=1 ":0", 4): No such file or directory
Now, this is not a UNIX-CLIENT IP. But, I don't know what DISPLAY=:0 is connecting to. It's certainly not port 6000 since that's the port it used to be listening on. If I change it to 6005, to forward to 6000, and make the Docker container DISPLAY be $(ipconfig getifaddr en0):5 instead, then the connection is of course refused:
$ socat TCP-LISTEN:6005,reuseaddr,fork TCP:localhost:6000
2016/06/14 21:20:32 socat[25379] E connect(8, LEN=16 AF=2 127.0.0.1:6000, 16): Connection refused
Question 2: How to proceed from here?

I hadn't restarted after re-installing XQuartz. I restarted, and now it works. :).

Dockerized UI Apps in Docker for Desktop MacOS 2018+. Updated in in 2021.
Went through all the pain to get the simplest version possible that does not depend on checking port, ip, etc... Here it is.
Running version XQuartz 2.7.11 (xorg-server 1.18.4)
Docker version docker version 18.06.1-ce
Make sure to install XQuartz (Updated with 2021 change)
$ brew install socat
$ brew install --cask xquartz
Don't forget to close logout and log back in.
ATTENTION: At this point, make sure to reboot your host (MacOS for instance). The following error is related to when you don't: E connect(5, LEN=2 AF=1 "<anon>", 2): Invalid argument
$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
2021/04/04 17:28:58 socat[40606] E connect(5, LEN=2 AF=1 "<anon>", 2): Invalid argument
Instructions
You will need at 2 terminals open: one for the socat with the display and the other for running the UI container.
1. Close any 6000
On a new terminal, verify if there's anything running on port 6000
$ lsof -i TCP:6000
$
If there is anything, just kill the process
2. Close any 6000
Open a socket on that port and keep the terminal open
$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
3. Verify 6000 is open
In a new terminal, verify if it is opened
$ lsof -i TCP:6000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
socat 29298 marcellodesales 5u IPv4 0xe21e43ca9d99bf1d 0t0 TCP *:6000 (LISTEN)
4. Build and Run simple UI App
$ cat Dockerfile.eyes
FROM debian:latest
RUN apt-get update && apt-get install -y x11-apps
RUN rm -rf /tmp/* /usr/share/doc/* /usr/share/info/* /var/tmp/*
RUN useradd -ms /bin/bash user
ENV DISPLAY :0
USER user
ENTRYPOINT ["/bin/sh", "-c", "$0 \"$#\"", "xeyes"]
$ docker build -t eyes -f Dockerfile.eyes .
The magic happens using the variables from Docker. Just using the -e DISPLAY=docker.for.mac.host.internal:0 did the trick, as it it will point to the internal IP address and provide that to the docker image. The port forward will do its magic.
$ docker run -ti --rm -e DISPLAY=docker.for.mac.host.internal:0 eyes
I noticed that at this point XQuartz is opened on it own to the same port
$ lsof -i TCP:6000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
socat 29298 marcellodesales 5u IPv4 0xe21e43ca9d99bf1d 0t0 TCP *:6000 (LISTEN)
X11.bin 29462 marcellodesales 8u IPv6 0xe21e43ca7cdb1135 0t0 TCP *:6000 (LISTEN)
5. Profit and run more apps
$ docker run -e DISPLAY=docker.for.mac.host.internal:0 jess/tor-browser
$ docker run -e DISPLAY=docker.for.mac.host.internal:0 batmat/docker-eclipse

I needed to quit Terminal and then relaunch it in order to get it to work.

For OS X 10.6.3 and later, per XQuartz 2.7.11 instructions:
If this is your first time installing XQuartz, you may wish to logout and log back in. This will update your DISPLAY environment variable to point to XQuartz.app rather than X11.app. If you would prefer to keep using X11.app as your default server (you can still launch XQuartz.app manually), you’ll want to disable /Library/LaunchAgents/org.macosforge.xquartz.startx.plist using launchctl(1).
After installing XQuartz 2.7.11 on my macOS High Sierra, logging out of my Mac and logging in again was enough for this to work via my MacOS Terminal. However, you may avoid having to logout and log in by opening the XQuartz Terminal application (XQuartz > Applications > Terminal), and running your X application from there. For example:
and then
bash-3.2$ xclock &

This answer is possibly limited to MacOS/Monterey.
After running XQuartz and setting the Preferences/Security/"Allow connections from network clients" option, you must restart XQuartz. (It may be the case that after install, you must logoff/logon again, but I found that merely restarting XQuartz was sufficient.) Afterwards, when XQuartz is running again, you should see it listening on port 6000:
lsof -i TCP:6000
Before this restart step, only DISPLAY=:0 or the default file-based socket worked for me. After this step, I could then do
export DISPLAY=localhost:0
and xterm, xhost, etc worked fine.
To use with docker, I used:
xhost +localhost
DISPLAY=docker.for.mac.host.internal:0
docker run -e DISPLAY=$DISPLAY -v /tmp/X11-unix:/tmp/.X11-unix

I used this code will help you in macos Big sur
https://apple.stackexchange.com/questions/411619/how-to-make-dia-which-uses-x11-xquartz-work
export DISPLAY=:0 # Fixes the "cannot open display".
export LANG="en_US.UTF-8" # Fixes the annoying Xterm window opening.
exec "$CWD/dia-bin" --integrated

Related

How to connect and use the camera in a docker container on MacOS with Docker Desktop [duplicate]

I'm not sure that this is even possible, but is there a way to access my camera inside docker container? I'm not using external camera but built-in in my mac.
I'm not sure that the flag volume (-v) is the best practice to do so.
According to the github of jfrazelle, docker engineer who wrote many Dockerfile and docker run for many graphical app such as chromium, skype, spotify, and so on, the flag and argument you should use is --device /dev/video0.
For quick test(tested on ubuntu), below code should give supported frame resolution of cameras:-
docker run --rm -it --entrypoint /bin/bash --device /dev/video0 jrottenberg/ffmpeg
ffmpeg -f video4linux2 -list_formats all -i /dev/video0
You can try to forward your webcam device using -v flag
Something like
sudo docker run -d -p 55555:22 --privileged -v /dev/video0:/dev/video0 testimage
To list all devices attached to USB use lsusb ; to list all devices attached to PCI use lspci
On MacOS, it can be a bit tricky:
Install legacy docker virtualization engine for Docker Desktop on Mac (which uses Oracle Virtual Box)
Install Virtual Box
Install Virtual Box Extension pack
Install Docker Toolbox (reading this is strongly recommended & backuping your /usr/local/bin/docker* before is also recommended)
Ensure that /usr/local/bin/docker and /usr/local/bin/docker-compose link to Docker Desktop binaries (/Applications/Docker.app/Contents/Resources), and not Docker Toolbox
Test everything is still working: docker ps -a and docker images should display what you already had in Docker Desktop, docker-machine ls should not raise an error
brew install socat
brew install xquartz
Setting: XQuartz Preferences > Security > check allow all (Allow connections from network clients)
defaults write org.macosforge.xquartz.X11 enable_iglx -bool true
IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
xhost + $IP
docker-machine create -d virtualbox --virtualbox-cpu-count=4 --virtualbox-memory=4096 --virtualbox-disk-size=1000000 --virtualbox-boot2docker-url https://github.com/gzupark/boot2docker-webcam-mac/releases/download/18.06.1-ce-usb/boot2docker.iso default
docker-machine stop default
Open Virtual Box app & configure the VirtualBox VM that has just been created with docker-machine
Display > Video memory (max)
Display > Acceleration > Enable 3D acceleration (check)
Ports > USB > Enable USB controller (check) > USB 2.0 (select)
Shared folders > Add > Folder Path = / & Folder name = host-root
Reboot macOS
Open a terminal (T1), and type
open -a XQuartz
If it does not open another terminal, focus XQuartz app, and Applications > Terminal
Now a new terminal is opened (T2)
On T2: socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
if it complains about "Address already in use", check with lsof -i tcp:6000 that owning process is X11.bin, otherwise kill owning process and try running socat again (always on T2)
On T1 again
IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
xhost + $IP
docker-machine start default
eval $(docker-machine env default)
vboxmanage list webcams
Identify in the list your webcam (eg mine was .1)
vboxmanage controlvm default webcam attach .1
(You may need to open VirtualBox again, double click on your VM, which will open a view of your system, and then Devices > Webcam > <select your camera>)
You should now be able to access your camera in a container.
Test XQuartz with
docker run --rm -it -e DISPLAY=$IP:0 gns3/xeyes
Test camera with
docker run --rm -it -e DISPLAY=$IP:0 --device=/dev/video0:/dev/video0 -v /tmp/.X11-unix:/tmp/.X11-unix ubuntu
apt update && apt install -y streamer
streamer -f jpeg -o image.jpeg
Tip
Shutdown your greedy VM process with: VBoxManage controlvm thevm acpipowerbutton
Big thanks to:
https://github.com/GzuPark/boot2docker-webcam-mac
https://medium.com/#jijupax/connect-the-webcam-to-docker-on-mac-or-windows-51d894c44468
https://askubuntu.com/a/106773
https://apple.stackexchange.com/a/277029
Additional notes:
https://apple.stackexchange.com/a/277029
https://docs.docker.com/docker-for-mac/docker-toolbox/#docker-toolbox-and-docker-desktop-coexistence
https://docs.docker.com/docker-for-mac/docker-toolbox/

Running OpenModelica GUI from Docker causes "Could not connect to any X display" error

On Modelica Language Discord, someone posted the commands to get the OpenModelica GUI (OMEdit) running on Linux:
xhost +"local:docker#"
docker run -ti --rm --privileged --net=host -e "DISPLAY=$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix openmodelica/openmodelica:v1.14.1-gui OMEdit
and someone else posted the below command for macOS:
docker run -ti --rm --privileged --net=host -e DISPLAY=docker.for.mac.localhost:0 -v /tmp/.X11-unix:/tmp/.X11-unix openmodelica/openmodelica:v1.14.1-gui OMEdit
I have installed Docker using HomeBrew following the instructions here
docker --version
Docker version 19.03.8, build afacb8b
but when trying the command above I get the error message:
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
qt.qpa.screen: QXcbConnection: Could not connect to display docker.for.mac.localhost:0
Could not connect to any X display.
Things I have tried to solve the problem:
from here installed dbus brew install dbus
from here ran xhost +local:docker returning
non-network local connections being added to access control list
from here and here changed DISPLAY=unix$DISPLAY leading to slightly different error
qt.qpa.screen: QXcbConnection: Could not connect to display unix/private/tmp/com.apple.launchd.lO0ZFXT603/org.macosforge.xquartz:0
from here, I tried
IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
docker run .... -e DISPLAY=$(xhost + $(hostname) > /dev/null; echo $IP):0 ...
leading to
qt.qpa.screen: QXcbConnection: Could not connect to display 10.0.0.9:0
from here, I tried the open -a XQuartz, ... xhost + $ip, and DISPLAY=$ip:0
I would appreciate if you could help me know
How can I resolve the above issues and get the GUI running
breakdown down the above commands for me. some of them are explained here, but not the rest.
P.S. I don't want to install Docker Desktop as discussed here.
OK, I think I was able to solve the problem. I assume XQuartz and socat are installed
brew cask install xquartz
brew install socat
then from here, run
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
in one terminal. Open a new terminal and run
docker-machine env default
eval $(docker-machine env default)
IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
xhost + $IP
docker run -ti --rm --privileged --net=host -e DISPLAY=$IP:0 -v /tmp/.X11-unix:/tmp/.X11-unix openmodelica/openmodelica:v1.14.1-gui OMEdit
But still, I would appreciate it if someone could explain what these commands do and if there is a more clean and canonical way to do it.
P.S. Please consider that the docker-machine is deprecated software as of now. Please use it at your own risk. You need to follow these instructions to get it up and running.

I am unable to execute netcat command within docker bash terminal?

I am a beginner in docker . I have installed docker-ce in my ubuntu 18.04 machine using commandsudo apt install docker-ce
As part of a tutorial , I am trying to establish connection between containers by executing series of below commands.
Below command will turn on ports 1234/4321 to listen to traffic inside/outside of containers i'm going to use.
root#ghost-SVE9999CNS:/home/ghost# docker run --rm -ti -p 1234:1234 -p 4321:4321 --name echo-server ubuntu:18.04 bash
Now, I wanted to run netcat commands within docker bash terminal.
root#xxxyyyyzzzz12:/# nc -lp 1234 | nc -lp 4321
Once i inovke above command from my terminal.. Its giving errors "nc: command not found"
bash: nc: command not found
bash: nc: command not found
Later, I have done enough research and i never found any official docker solution for this problem.
Please could anyone help me out installing netcat within docker-ce.
I've tried commands like below.
apt-get install netstat
apt-get install nc
But, no luck.
nc is not installed by default on ubuntu:18.04 image, so you have to install it :
apt-get update && apt-get install -y netcat
apt-get update is necessary to first update list of packages (when the container is started, this list is empty). Once done, you can run nc -lp 1234 from the container.
To test all works as you expected, you can then :
run from a shell (on your host) something like telnet container_ip 1234 or telnet localhost 1234 (since ports have been forwarded)
type something
look at the container output to see what you typed in your host shell
It is not necessary to use ubuntu:18.04 to follow the tutorial, you can use ubuntu:14.04 for example, in which nc installed by default.
docker run --rm -ti -p 1234:1234 -p 4321:4321 --name echo-server ubuntu:14.04 bash

Boot2Docker searching for docker-bootstrap.sock which does not exist

I am currently trying to set up kubernetes on a multi-docker container on CoreOS stack for AWS. To do this I need to set up etcd for flannel and am currently using this guide but am having problems at the first stage where I am suggested to run
sudo sh -c 'docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null &'
The problem is the 1st command
docker -d -H unix:///var/run/docker-bootstrap.sock
from within boot2docker. There is no docker-bootstrap.sock file in this directory and this error is thrown:
FATA[0000] An error occurred trying to connect: Post https:///var/run/docker-bootstrap.sock/v1.18/containers/create: dial unix /var/run/docker-bootstrap.sock: no such file or directory
Clearly the unix socket did not connect to this nonexistent socket.
I will note this is a very similar problem to this ticket and other tickets regarding the FATA[0000] though none seem to have asked the question in the way I currently am.
I am not an expert in unix sockets, but I am assuming there should be a file where there is not. Where can I get this file to solve my issue, or what is the recommended steps to resolve this.
specs: running OSX Yosemite but calling all commands from boot2docker
Docker should create this file for you. Are you running this command on your OS X machine? or are you running it inside the boot2docker VM?
I think you need to:
boot2docker ssh
Then:
sudo sh -c 'docker -d -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap 2> /var/log/docker-bootstrap.log 1> /dev/null &'
You need to make sure that command runs on the Vagrant Linux box that boot2docker creates, not your OS X machine.
Hope that helps!

MacPorts / Terminal: `Unrecognized action "sudo"`

I'm trying to install Image Magick on MAMP. And I'm seriously out of my depth.
I've installed MacPorts, and opened the terminal. I've typed in sudo port -v selfupdate per the instructions on http://www.macports.org/install.php#pkg
But the response I get from the Terminal is Unrecognized action "sudo"
I've googled and googled, but can't find anything that makes a slab of sense.
Any clever people feeling generous?
You are running ports on interactive mode, and you are not in your system shell. The port program won't recognize sudo as one of its commands, and I am guessing you didn't run your port command with sudo so you won't be able to do much, try the following:
Click on your terminal.
Press command + Q (command is the key left of your space bar)
Open your terminal once again and do not run anything on else but the command suggested:
sudo port -v selfupdate
If you get the same thing, you are still or again in Macports interactive session, type CTRL + C, or type quit.

Resources