Add xserver into Docker container (the host is headless) - docker

I'm building a Docker container which have maven and some dependencies. Then it execute a script inside the container. It seems, one of that dependencies needs an Xserver to work. Nothing is shown on screen but it seems necessary and can't be avoided.
I got it working putting an ENV DISPLAY=x.x.x.x:0 on Dockerfile and it connects to the external Xserver and it works. But the point is to make a Docker self-sufficient container.
So I need to add a Xserver to my container adding in Dockerfile the necessary. And I want that Xserver only accessible by the Docker container itself and not externally.
The FROM of my Dockerfile is FROM ubuntu:15.04 and that is unchangeable because my Dockerfile have a lot of things depending of that specific version.
I've read some post about how to connect from docker container to Xserver of the Docker host machine, like this. But as I put in question's title, the Docker host is headless and doesn't have Xserver.
Which would be the minimum apt-get packages to install into the container to have a Xserver?
I guess in my Dockerfile will be needed the display environment var like ENV DISPLAY=:0. Is this correct?
Is anything else needed to be added in docker run command?
Thank you.

You can install and run a x11vnc inside your docker container. I'll show you how to make it running on a headless host and connect it remotely to run X applications(e.g. xterm).
Dockerfile:
FROM joprovost/docker-x11vnc
RUN mkdir ~/.vnc && touch ~/.vnc/passwd
RUN x11vnc -storepasswd "vncdocker" ~/.vnc/passwd
EXPOSE 5900
CMD ["/usr/bin/x11vnc", "-forever", "-usepw", "-create"]
And build a docker image named vnc:
docker build -t vnc .
Run a container and remember map port 5900 to host for remote connect(I'm using --net=host here):
docker run -d --name=vnc --net=host vnc
Now you have a running container with x11vnc inside, download a vnc client like realvnc and try to connect to <server_ip>:5900 from local, the password is vncdocker which is set in Dockerfile, you'll come to the remote X screen with an xterm open. If you execute env and will find the environment variable DISPLAY=:20
Let's go to the docker container and try to open another xterm:
docker exec -it vnc bash
Then execute the following command inside container:
DISPLAY=:20 xterm
A new xterm window will popup in your vnc client window. I guess that's the way you are going to run your application.
Note:
The base vnc image is based on ubuntu 14, but I guess the package is similar in ubuntu 16
Don't expose 5900 if you don't want remote connection
Hope this can help :-)

Related

How to connect to a docker container from host(windows machine)

i am literally new to Docker. I have a java application which I can execute by using javaws command as below.
javaws http://localhost:9088/rtccClient/rtcc.jnlp.
I have created docker container for this application in my window's machine using "ibmcom/websphere-liberty:latest" as base image. after starting the container I am executing the same command to run the application and it says "CouldNotLoadArgumentException[ Could not load file/URL specified: http://localhost:9088/rtccClient/rtcc.jnlp]".
Below is my docker file . please update what I am doing wrong.
**FROM ibmcom/websphere-liberty:latest
USER root
ADD ./rtcc.ear /opt/ibm/wlp/usr/servers/defaultServer/apps
ADD ./rtccClient.war /opt/ibm/wlp/usr/servers/defaultServer/apps
RUN yum -y install unixODBC
RUN yum -y install libaio
RUN mkdir -pv /basic
COPY ./basicinstaclient/oracle-instantclient19.8-basic-19.8.0.0.0- 1.x86_64.rpm /basic/
RUN rpm -i /basic/oracle-instantclient19.8-basic-19.8.0.0.0-1.x86_64.rpm
EXPOSE 9088
EXPOSE 9450**
when I inspect the docker container id the ip showed as "172.18.0.3" and port of the container was 9080. In jnlp file which I mention in the javaws command I am supposed to use the ip and port. do I need to put ip and port of the container?
so I used "javaws http://172.18.0.3:9080/rtccClient/rtcc.jnlp". still it didn't work. I even replaced with my windows machine IP. I even logged into container to execute javaws command. it says javaws not found. Please help
Try a command like this:
docker run -p 9080:9080 YOUR_IMAGE_NAME_HERE
then try the javaws http://localhost:9088/rtccClient/rtcc.jnlp again
the -p will map ports like this: host:docker from left to right map the host machine port to the docker internal port.
Here you can also find a nice docker FROM scratch workshop (shameless plug) : https://docker-from-scratch.ivonet.nl/
I tried as you said and this is what i am getting. CouldNotLoadArgumentException[ Could not load file/URL specified: http://localhost:9088/rtccClient/rtcc.jnlp]
More over you are mapping 9080:9080 in run command and using 9088 in javaws command. so how it will work?

Docker : How to run a Bokeh server inside Docker container and expose the output

I have a Bokeh python code that imports data from excel file and projects my supplier locations on Google maps. The excel file is stored on my local host in the folder C:\Python where the Python code is picking it from.This code works fine with I open command prompt and use the command "Bokeh serve --show Gmaps_Bokeh.py".
However, when I build the docker file to do that same and map the port 5006 to 2000 I cannot see anything in my browser.
I have created a Docker folder on my host that contains Gmaps_Bokeh.py , Sid.xls and Dockerfile and in my Dockerfile I am copying all the contents in /Python directory of container.
The docker terminal shows the following
$ docker run -p 5006:2000 sid
2019-11-03 20:38:43,329 Starting Bokeh server version 1.3.4 (running on
Tornado 6.0.3)
2019-11-03 20:38:43,334 Bokeh app running at:
http://localhost:5006/Gmaps_Bokeh
2019-11-03 20:38:43,334 Starting Bokeh server with process id: 1
Dockerfile contents
FROM python
RUN pip install bokeh
RUN pip install gmaps
RUN pip install pandas
RUN pip install xlrd
WORKDIR /Python
COPY . /Python
EXPOSE 2000
CMD ["bokeh", "serve","/Python/Gmaps_Bokeh.py"]
To get access to folder on host, you need to use docker volumes to map host's c:/python into some linux path. Also, you need to reconfigure your application to use that path (on container) and not c:/python (or any other direct host windows path).
It seems to me you have your ports messed up. Think of the host and container ports separately.
As seen in the console output once you run the container inside your container, you have bokeh which publishes on port 5006 (here localhost is from the point of view of the container). This is what you need to expose in your Dockerfile (thus it should be EXPOSE 5006). So far you're inside the container and don't know anything about port 2000.
If you want to expose your container port 5006 (where bokeh serves) to a host system port 2000, you would do this as in #Tony's comment using -p 2000:5006 in your docker run command and look for it with http://localhost:2000 in your browser.
One important clarification that should glue all this together: localhost when requested from the host system (where you run your browser) is different from localhost when requested from the container (where the bokeh console output comes from).

Docker Port Not Exposing Golang

I am building a golang WebService in docker. The build seems fine but I am unable to expose the port for external (outside of container) access. When I curl from the command line (inside the container) the app appears to work fine.
I saw quite a few posts of similar problems but unfortunately many were not resolved or didn't seem applicable.
FROM golang:alpine
RUN mkdir /go/src/webservice_refArch
ADD . /go/src/webservice_refArch
WORKDIR /go/src/webservice_refArch
RUN apk add curl
RUN cd /go/src/webservice_refArch/ && go get ./...
RUN cd /go/src/webservice_refArch/cmd/reference-w-s-server && go build -o ../../server
EXPOSE 7878
ENTRYPOINT ["./server", "--port=7878"]
I have tried both:
:7878
localhost:7878
I was facing the same issue. Then what I did is change the ListernHost from localhost to 0.0.0.0 and it worked.
To debug this tried curl inside the container it was working fine but outside the container the response of the curl was blank. The port mapped but the content was not served outside the container. Once you change the "localhost" to 0.0.0.0 it will work.
See https://docs.docker.com/engine/reference/run/#expose-incoming-ports, just expose port in dockerfile is not enough.
You can add -p 7878:7878 when start container, or use -P to let docker set a automatical host port mapping for you.
If you do not want to do above, you can also add --net=host when start the container, then container will use host's network, if also works for you.
if you are trying to access the port inside your docker container from your local machine, you need map it to the desired port on your local machine
docker run -p 7878:7878 IMAGE
Then you should be able to access it on your host

.Net Core WebApi refuses connection in Docker container

I am trying out Docker with a small WebApi which I have written in dotnet core.
The Api seems to work fine because when I run it with dotnet run it starts normally and is reachable on port 5000. But when I run it in a Docker container it starts, but I cannot reach it on the exposed/mapped port. I'm running Docker on Windows 10 withing VirtualBox.
My Dockerfile looks like this:
FROM microsoft/aspnetcore-build:latest
COPY . /app
WORKDIR /app
RUN dotnet restore
EXPOSE 5000
ENV ASPNETCORE_URLS http://*:5000
ENTRYPOINT ["dotnet", "run"]
I am building the dontainer like this:
docker build -t api-test:v0 .
And run it with this command:
docker run -p 5000:5000 api-test:v0
The output of the run command is:
Hosting environment: Production
Content root path: /app
Now listening on: http://localhost:5000
I have also tried different approaches of binding the URL:
as http://+:5000, http://0.0.0.0:5000, http://localhost:5000, ...
via CLI parameters --urls / --server.urls
but without success. Does anyone see what I'm doing wrong or missing?
Now listening on: http://localhost:5000
Binding to localhost will not work for your scenario. You need to get the app to bind to 0.0.0.0 for the docker port forwarding to work. Once you do that, you should be able to reach the app on the VM IP, port 5000
Make sure your service is listening on all ports using http://*:500 or similar (if it prints localhost when running, it won't work).
If you set up your docker environment with VirtualBox and used e.g. docker-machine, you n need to use the IP address of the virtual machine that runs the docker containers. you can get the IP via docker-machine ip default.
I found a way round this. All you need to do is edit launchSettings.json change to "applicationUrl": "http://*:5000/" of your app setting. Build the image. Then run the image docker run -d -p 81:5000 aspnetcoreapp after it runs get ip address of the container docker exec container_id ipconfig. Then in browser http://container_ip:5000/api/values. For some reason it does not work http://localhost:81 still need to figure out why that is.
I had the same issue recently with Docker version 20.x. The comment above provided good lights. If anyone faces the same issue here is how I've solved: Edit launchSettings.json to
"applicationUrl": "http://localhost:5001;http://host.docker.internal:5001",
This will let you test your web API locally and also to be consumed from the container.

Is it possible to restart docker container from inside it

I'd like to package Selenium grid exrtas into a docker image.
This service being run without using docker container can reboot the OS it's running in. I wonder if I can setup the container to restart by Selemiun grid extras service running inside the container.
I am not familiar with Selenium Grid, but as a general idea: you could mount a folder from the host as data volume, then let Selenium write information to there, like a flag file.
On the host, you have a scheduled task / cronjob running on the host that would check for this flag in the shared folder and if it has a certain status, you would invoke a docker restart from there.
Not sure if there are other more elegant solutions for this, but this is what came to my mind adhoc.
Update:
I just found this on the Docker forum:
https://forums.docker.com/t/how-can-i-run-docker-command-inside-a-docker-container/337
I'm not sure about CoreOS but normally you can manage your host
containers from within a container by mounting the Docker socket.
Such as
docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:latest sh -c "apt-get update ; apt-get install docker.io -y ;
bash"
or
https://registry.hub.docker.com/u/abh1nav/dockerui/

Resources