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

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.

Related

linux curl can't find docker webserver

I have been Googling this for 2 days and the only work around I have found is using --net=host vs. -p 8081:80 to connect to the web server. I have create a basic web server on a normal non web server RH 7 box. The expose port is 80. I compile and start the container and 2 web pages are copied in. In the container "curl http://localhost/index.html" writes out "The Web Server is Running". Out side curl times out with "curl: (7) Failed connect to localhost:80; Connection refused". All the post say it should work, but it doesn't.
The container was create as follows:
docker run -d -v /data/docker_webpage/unit_test/data:/var/www/html/unit_test/data -w /var/www/html/unit_test/data -p 8081:80 --name=d_webserver webserver
I have done docker inspect d_webserver and see the Gateway": "172.17.0.1" and "IPAddress": "172.17.0.2" are this. curl http://localhost:8081/index.html or curl http://172.17.02:8081/index.html all fail. Only if I use
docker run -d -v /data/docker_webpage/unit_test/data:/var/www/html/unit_test/data -w /var/www/html/unit_test/data --net=host --name=d_webserver webserver
does it work as expected. From all I have read, the -p 8081:80 should allow me to see the web page, but it just doesn't work. There are no firewall up, so that's not the problem. Does anyone know why 8081 is not allowing me to connect to the webserver? What step am I missing?
Also, I would like to use the chrome on my PC to do a http:xxx.xxx.xxx.xxx:8081/index.html to the Linux box vs. running the browser on Linux box. PC chrome says the Linux ip can't be reached. There is a gateway box required so that probably is the problem. Is there someway to fix the pc chrome so it can find the Linux docker web server via gateway box or must I start chrome on the Linux box all the time? Sort of defeats the point of making the docker webserver in the first place if people have to ssh into the box and start up a browser.
We are using local repositories because of security. These are the rpm I saved in rpms directory for install.
rpms $ ls
deltarpm-3.6-3.el7.x86_64.rpm
httpd-2.4.6-97.el7_9.4.x86_64.rpm
yum-utils-1.1.31-54.el7_8.noarch.rpm
Dockerfile:
# Using RHEL 7 base image and Apache Web server
# Version 1
# Pull the rhel image from the local registry
FROM rhel7_base:latest
USER root
MAINTAINER "Group"
# Copy X dependencies that are not available on the local repository to /home/
COPY rpms/*.rpm /home/
# Update image
# Install all the RPMs using yum. First add the pixie repo to grab the rest of the dependencies
# the subscription and signature checking will be turned off for install
RUN cd /home/ && \
yum-config-manager --add-repo http://xxx.xxx.xxx.xxx/repos/rhel7/yumreposd/redhat.repo && \
cat /etc/yum.repos.d/redhat.repo && \
yum update --disableplugin=subscription-manager --nogpgcheck -y && rm -rf /var/cache/yum && \
yum install --disableplugin=subscription-manager --nogpgcheck *.rpm -y && rm -rf /var/cache/yum && \
rm *.rpm
# Copy test web page directory into container at /var/www/html.
COPY unit_test/ /var/www/html/unit_test/
# Add default Web page and expose port for testing
RUN echo "The Web Server is Running" > /var/www/html/index.html
EXPOSE 80
# Start the service
CMD ["-D", "FOREGROUND"]
ENTRYPOINT ["/usr/sbin/httpd"]
I built it this way and then started it and I should have been able to connect on port 8081, but curl fails.
docker build -t="webserver" .
docker run -d -v /data/docker_webpage/unit_test/data:/var/www/html/unit_test/data -w /var/www/html/unit_test/data -p 8081:80 --name=d_webserver webserver
curl http://localhost/index.html (time out)
curl http://localhost:8081/index.html (time out)
curl http://172.17.0.2:8081/index.html (time out)
curl http://172.17.0.2/index.html (time out)

Not able to access admin console for an activemq instance running in a docker container

I have created dockerfile.
FROM ubuntu:latest
RUN apt-get update && apt-get -y upgrade
RUN apt-get -y install curl
RUN apt-get -y install default-jre
RUN curl -O http://archive.apache.org/dist/activemq/5.16.0/apache-activemq-5.16.0-bin.tar.gz
RUN mkdir -p /opt/apache/activemq
RUN tar xvzf apache-activemq-5.16.0-bin.tar.gz -C /opt/apache/activemq
WORKDIR /opt/apache/activemq/apache-activemq-5.16.0/bin
VOLUME /opt/apache/activemq/apache-activemq-5.16.0/conf
RUN echo './activemq start && tail -f /opt/apache/activemq/apache-activemq-5.16.0/data/activemq.log' > start.sh
# Admin interface
EXPOSE 8161
# Active MQ's default port (Listen port)
EXPOSE 61616
CMD ["/bin/bash", "./start.sh"]
I created a docker container like this
docker run --name activemq -p 8161:8161 -p 61616:61616 temp-activemq:5.16.0
I tried to run the admin console as follows
http:://localhost:8161/admin/
http://<IP of the Container>:8161/admin/
Neither of them works
Outside of the container, I installed activeMQ and tried to run admin console, it worked. Can anyone please help me with pointers on how can I get this sorted?
I fixed the above issue with
docker run --rm -d --network host --name activemq temp-activemq:5.16.0
But, I am still researching why the port forwarding is not working?
I had the same issue. In AMQ 5.16.0 they've updated the jetty.xml for the web UI to use 127.0.0.1 instead of 0.0.0.0!
I fixed it by updating the jetty.xml
update under "org.apache.activemq.web.WebConsolePort" in jetty.xml -->
property name="host" value="127.0.0.1"
to
property name="host" value="0.0.0.0"
You'll need to copy and overwrite this file in your docker image and it should work.

Docker Toolbox refused to connect on the browser - Tried different solutions - Windows 7

I have installed Docker Toolbox on Windows 7.
Everything has been installed correctly.
Now I try to build and run a DockerFile.
Dockerfile
FROM debian:9
RUN apt-get update -yq \
&& apt-get install curl gnupg -yq \
&& curl -sL https://deb.nodesource.com/setup_10.x | bash \
&& apt-get install nodejs -yq \
&& apt-get clean -y
ADD . /app/
WORKDIR /app
RUN npm install
VOLUME /app/logs
CMD npm run start
After successfully running the command line docker build -t test . and docker run -it -d -p 3306:3306 test, I try to access it via my browser by doing :
http://192.168.99.100:3306
which correspond to http://[docker-machine-ip]:port
But it refuses to connect.
After searching on the internet, I tried several solutions:
1. Use the container IP
docker inspect --format '{{ .NetworkSettings.IPAddress }}' [id]
http://[containerIP]:port
2. Add port forwarding on Oracle VM defaut machine
VirtualBox -> Machine settings -> Network -> Adapter 1 (NAT) -> Advanced, Port Forwarding
name : test
Host ip : 127.0.0.1
Host port : 3306
Guest port : 3306
I even tried by putting Guest IP to 192.168.99.100 and letting Host IP to empty.
3. Try different ports
I tried differents ports to see if it was not caused by a port already opened.
I even tried the option --publish-all (-P) but as a result, I don't have any ports showing on docker ps -a
docker run -it -d -P test
4. Deactivate the windows firewall
Both public and private.
None of those solutions worked for me and I don't know what to do next.
Any help ? I would appreciate. Thank you.

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

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

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

Resources