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

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?

Related

I can bind to port 80 as a non-root user in a docker container. Why? What's going on?

Short version:
I can bind to port 80 inside a docker container while running as a non-root user. Please explain.
Long version:
I'm newish to docker, but have a lot of experience otherwise. Everything is making sense to me except this behavior.
I've tried with both the Google centos base image, and the latest docker ubuntu image.
I build a docker image off those bases with the following Dockerfile:
FROM marketplace.gcr.io/google/centos7
# or for ubuntu
# FROM ubuntu
# RUN apt-get update -y && apt-get install -y python
RUN groupadd -g 1000 container && useradd -r -u 1000 -g container container
USER container
Great. Then I build and run it with docker run --rm -it <img_name>, and now I'm in the container with whoami returning "container". I don't have root privileges. touch /root/foo fails with access denied.
Ok, cool. Non-root user, running without root privileges. I can't sudo. I can't su root. Just like I expect.
Then I run:
python -m SimpleHTTPServer 80 and it happily binds to port 80. I can run curl localhost inside the container and I get a response.
What's going on? What am I missing.
Thanks for any help.
I'm running Docker for Mac if it matters. I don't expect it does. (I expected wrong.)
This behavior was added in 20.3.0 by changing the value of net.ipv4.ip_unprivileged_port_start inside the network namespace to be 0, effectively making all ports unprivileged. Since containers typically run a single app, there's little value to restricting that app to only listen on privileged ports like you would want on a multi-user host.
I just tried this with ubuntu:18.04 image on Linux Host and it fails to bind to port 80.
I repeated on a Mac and the same that is happening to you happened there.
Now on the Mac you CAN bind to lower ports with non root user (just try running python -m SimpleHTTPServer 80 as your login user) So maybe this is normal on the Mac.

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

Add xserver into Docker container (the host is headless)

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

Connection refused on docker container

I'm new to Docker and trying to make a demo Rails app. I made a dockerfile that looks like this:
FROM ruby:2.2
MAINTAINER marko#codeship.com
# Install apt based dependencies required to run Rails as
# well as RubyGems. As the Ruby image itself is based on a
# Debian image, we use apt-get to install those.
RUN apt-get update && apt-get install -y \
build-essential \
nodejs
# Configure the main working directory. This is the base
# directory used in any further RUN, COPY, and ENTRYPOINT
# commands.
RUN mkdir -p /app
WORKDIR /app
# Copy the Gemfile as well as the Gemfile.lock and install
# the RubyGems. This is a separate step so the dependencies
# will be cached unless changes to one of those two files
# are made.
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && bundle install --jobs 20 --retry 5
# Copy the main application.
COPY . ./
# Expose port 8080 to the Docker host, so we can access it
# from the outside.
EXPOSE 8080
# The main command to run when the container starts. Also
# tell the Rails dev server to bind to all interfaces by
# default.
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "8080"]
I then built it like so:
docker build -t demo .
And call a command to start the server which does start the server on port 8080:
Johns-MacBook-Pro:demo johnkealy$ docker run -it demo
=> Booting WEBrick
=> Rails 4.2.5 application starting in development on http://0.0.0.0:8080
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2016-04-23 16:50:34] INFO WEBrick 1.3.1
[2016-04-23 16:50:34] INFO ruby 2.2.4 (2015-12-16) [x86_64-linux]
[2016-04-23 16:50:34] INFO WEBrick::HTTPServer#start: pid=1 port=8080
I then try to find the correct IP to navigate to:
Johns-MacBook-Pro:demo johnkealy$ docker-machine ip default
192.168.99.100
I navigate to http://192.168.99.100:8080 and get the error This site can’t be reached 192.168.99.100 refused to connect.
What could I be doing wrong ?
You need to publish the exposed ports by using the following options:
-P (upper case) or --publish-all that will tell Docker to use random ports from your host and map them to the exposed container's ports.
-p (lower case) or --publish=[] that will tell Docker to use ports you manually set and map them to the exposed container's ports.
The second option is preferred because you already know which ports are mapped. If you use the first option then you will need to call docker inspect demo and check which random ports are being used from your host at the Ports section.
Just run the following command:
docker run -it -p 8080:8080 demo
After that your url will work.
If you are using Docker toolkit on window 10 home you will need to access the webpage through docker-machine ip command. It is generally 192.168.99.100:
It is assumed that you are running with publish command like below.
docker run -it -p 8080:8080 demo
With Window 10 pro version you can access with localhost or corresponding loopback 127.0.0.1:8080 etc (Tomcat or whatever you wish). This is because you don't have a virtual box there and docker is running directly on Window Hyper V and loopback is directly accessible.
Verify the hosts file in window for any digression. It should have
127.0.0.1 mapped to localhost
I had the same problem. I was using Docker Toolbox on Windows Home.
Instead of localhost I had to use http://192.168.99.100:8080/.
You can get the correct IP address using the command:
docker-machine ip
The above command returned 192.168.99.100 for me.
Command EXPOSE in your Dockerfile lets you bind container's port to some port on the host machine but it doesn't do anything else.
When running container, to bind ports specify -p option.
So let's say you expose port 5000. After building the image when you run the container, run docker run -p 5000:5000 name. This binds container's port 5000 to your laptop/computers port 5000 and that portforwarding lets container to receive outside requests.
This should do it.
In Docker Quickstart Terminal run following command:
$ docker-machine ip 192.168.99.100
In Windows, you also normally need to run command line as administrator.
As standard-user:
docker build -t myimage -f Dockerfile .
Sending build context to Docker daemon 106.8MB
Step 1/1 : FROM mcr.microsoft.com/dotnet/core/runtime:3.0
Get https://mcr.microsoft.com/v2/: dial tcp: lookup mcr.microsoft.com on [::1]:53: read udp [::1]:45540->[::1]:53: read:
>>>connection refused
But as an administrator.
docker build -t myimage -f Dockerfile .
Sending build context to Docker daemon 106.8MB
Step 1/1 : FROM mcr.microsoft.com/dotnet/core/runtime:3.0
3.0: Pulling from dotnet/core/runtime
68ced04f60ab: Pull complete e936bd534ffb: Pull complete caf64655bcbb: Pull complete d1927dbcbcab: Pull complete Digest: sha256:e0c67764f530a9cad29a09816614c0129af8fe3bd550eeb4e44cdaddf8f5aa40
Status: Downloaded newer image for mcr.microsoft.com/dotnet/core/runtime:3.0
---> f059cd71a22a
Successfully built f059cd71a22a
Successfully tagged myimage:latest
Make sure that you use the -p flag before the image name like this:
docker run -p 8080:8080 demo

How do I start tensorflow docker jupyter notebook

I've installed the tensorflow docker container on an ubuntu machine. The tensorflow docker setup instructions specify:
docker run -it b.gcr.io/tensorflow/tensorflow
This puts me into the docker container terminal, and I can run python and execute the Hello World example. I can also manually run .\run_jupyter.sh to start the jupyter notebook. However, I can't reach the notebook from host.
How do I start the jupyter notebook such that I can use the notebook from the host machine? Ideally I would like to use docker to launch the container and start jupyter in a single command.
For a Linux host Robert Graves answer will work, but for Mac OS X or Windows there is more to be done because docker runs in a virtual machine.
So to begin launch the docker shell (or any shell if you are using Linux) and run the following command to launch a new TensorFlow container:
docker run -p 8888:8888 -p 6006:6006 b.gcr.io/tensorflow/tensorflow ./run_jupyter.sh
Then for Mac OS X and Windows you need to do the following only once:
Open VirtualBox
Click on the docker vm (mine was automatically named "default")
Open the settings by clicking settings
In the network settings open the port forwarding dialog
Click the + symbol to add another port and connect a port from your mac to the VM by filling in the dialog as shown below. In this example I chose port 8810 because I run other notebooks using port 8888.
then open a browser and connect to http://localhost:8810 (or whichever port you set in the host port section
Make your fancy pants machine learning app!
My simple yet efficient workflow:
TL;DR version:
Open Docker Quickstart Terminal. If it is already open, run $ cd
Run this once: $ docker run -it -p 8888:8888 -p 6006:6006 -v /$(pwd)/tensorflow:/notebooks --name tf b.gcr.io/tensorflow/tensorflow
To start every time: $ docker start -i tf
If you are not on windows, you should probably change /$(pwd) to $(pwd)
You will get an empty folder named tensorflow in your home directory for use as a persistent storage of project files such as Ipython Notebooks and datasets.
Explanation:
cd for making sure you are in your home directory.
params:
-it stands for interactive, so you can interact with the container in the terminal environment.
-v host_folder:container_folder enables sharing a folder between the host and the container. The host folder should be inside your home directory. /$(pwd) translates to //c/Users/YOUR_USER_DIR in Windows 10. This folder is seen as notebooks directory in the container which is used by Ipython/Jupyter Notebook.
--name tf assigns the name tf to the container.
-p 8888:8888 -p 6006:6006 mapping ports of container to host, first pair for Jupyter notebook, the second one for Tensorboard
-i stands for interactive
Running TensorFlow on the cloud
After further reading of docker documentation I have a solution that works for me:
docker run -p 8888:8888 -p 6006:6006 b.gcr.io/tensorflow/tensorflow ./run_jupyter.sh
The -p 8888:8888 and -p 6006:6006 expose the container ports to the host on the same port number. If you just use -p 8888, a random port on the host will be assigned.
The ./run_jupyter.sh tells docker what to execute within the container.
With this command, I can use a browser on the host machine to connect to http://localhost:8888/ and access the jupyter notebook.
UPDATE:
After wrestling with docker on windows I switched back to a Ubuntu machine with docker. My notebook was being erased between docker sessions which makes sense after reading more docker documentation. Here is an updated command which also mounts a host directory within the container and starts jupyter pointing to that mounted directory. Now my notebook is saved on the host and will be available next time start up tensorflow.
docker run -p 8888:8888 -p 6006:6006 -v /home/rob/notebook:/notebook b.gcr.io/tensorflow/tensorflow sh -c "jupyter notebook /notebook"
Jupyter now has a ready to run Docker image for TensorFlow:
docker run -d -v $(pwd):/home/jovyan/work -p 8888:8888 jupyter/tensorflow-notebook
These steps worked for me if you are a total docker noob using a windows machine.
Versions: Windows 8.1, docker 1.10.3, tensorflow r0.7
Run Docker Quickstart Terminal
After it is loaded, note the ip address. If you can't find it use this docker-machine ip and make a note. Lets call it 'ip address'. Will look something like this: 192.168.99.104 (I made up this ip address)
Paste this command on the docker terminal:
docker run -p 8888:8888 -p 6006:6006 b.gcr.io/tensorflow/tensorflow.
If you are running this for the first time, it will download and install the image on this light weight vm. Then it should say 'The Jupyter notebook is running at ....' -> This is a good sign!
Open your browser at: <your ip address (see above)>:8888. Eg. 192.168.99.104:8888/
Hopefully you can see your ipython files.
To get this to run under hyper-v. Perform the following steps:
1) Create a docker virtual machine using https://blogs.msdn.microsoft.com/scicoria/2014/10/09/getting-docker-running-on-hyper-v-8-1-2012-r2/ this will get you a working docker container. You can connect to it via the console or via ssh. I'd put at least 8gb of memory since I'm sure this will use a lot of memory.
2) run "ifconfig" to determine the IP address of the Docker VM
3) On the docker shell prompt type:
docker run -p 8888:8888 -p 6006:6006 -it b.gcr.io/tensorflow/tensorflow
4) Connect to the Jupyter Workbench using http:/[ifconfig address]:8888/
To tidy up the things a little bit, I want to give some additional explanations because I also suffered a lot setting up docker with tensorflow. For this I refer to this video which is unfortunately not selfexplanatory in all cases.
I assume you already installed docker. The really interesting general part of the video starts at minute 0:44 where he finally started docker. Until there he only downloads the tensorflow repo into the folder, that he then mounts into the container. You can of course put anything else into the container and access it later in the docker VM.
First he runs the long docker command docker run –dit -v /c/Users/Jay/:/media/disk –p 8000 –p 8888 –p 6006 b.gcr.io/tensorflow/tensorflow. The “run” command starts containers. In this case it starts the container “b.gcr.io/tensorflow/tensorflow”, whose address is provided within the tensorflow docker installation tutorial. The container will be downloaded by docker if not already locally available.
Then he gives two additional kinds of arguments: He mounts a folder of the hostsystem at the given path to the container. DO NOT forget to give the partition in the beginning (eg. "/c/").
Additionally he declares ports being available later from the host machine with the params -p.
From all this command you get back the [CONTAINER_ID] of this container execution!
You can always see the currently running containers by running “docker ps” in the docker console. Your container created above should appear in this list with the same id.
Next Step: With your container running, you now want to execute something in it. In our case jupyter notebook or tensorflow or whatever: To do this you make docker execute the bash on the newly created container: docker exec –ti [CONTAINER_ID] bash. This command now starts a bash shell on your container. You see this because the “$” now changed to root#[CONTAINER_ID]:. From here is no way back. If you want to get back to the docker terminal, you have to start another fresh docker console like he is doing in minute 1:10. Now with a bash shell running in the container you can do whatever you want and execute Jupiter or tensorflow or whatever. The folder of the host system, you gave in the run command, should be available now under “/media/disk”.
Last step accessing the VM output. It still did not want to work out for me and I could not access my notebook. You still have to find the correct IP and Port to access the launched notebook, tensorboard session or whatever. First find out the main IP by using docker-machine –ls. In this list you get the URL. (If it is your only container it is called default.) You can leave away the port given here. Then from docker ps you get the list of forwarded ports. When there is written 0.0.0.32776->6006/tcp in the list, you can access it from the hostmachine by using the port given in the first place (Awkyard). So in my case the executed tensorboard in the container said “launched on port 6006”. Then from my hostmachine I needed to enter http://192.168.99.100:32776/ to access it.
-> And that’s it! It ran for me like this!
It gives you the terminal prompt:
FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd vdocker') DO %i
docker run -it tensorflow/tensorflow:r0.9-devel
or
FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd vdocker') DO %i
docker run -it b.gcr.io/tensorflow/tensorflow:latest-devel
You should have 'vdocker' or change vdocker to 'default'.
For some reason I ran into one additional problem that I needed to overcome beyond the examples provided, using the --ip flag:
nvidia-docker run --rm \
-p 8888:8888 -p 6006:6006 \
-v `pwd`:/root \
-it tensorflow/tensorflow:latest-devel-gpu-py3 sh -c "jupyter notebook --ip 0.0.0.0 ."
And then I can access via http://localhost:8888 from my machine. In some ways this makes sense; within the container you bind to 0.0.0.0 which represents all available addresses. But whether I need to do this seems to vary (e.g I've started notebooks using jupyter/scipy-notebook without having to do this).
In any case, the above command works for me, might be of use to others.
As an alternative to the official TensorFlow image, you can also use the ML Workspace Docker image. The ML Workspace is an open-source web IDE that combines Jupyter, VS Code, TensorFlow, and many other tools & libraries into one convenient Docker image. Deploying a single workspace instance is as simple as:
docker run -p 8080:8080 mltooling/ml-workspace:latest
All tools are accessible from the same port and integrated into the Jupyter UI. You can find the documentation here.

Resources