I'd like to create a ssh tunnel from my computer to a remote server to a docker container running Jupyter Notebook (computer>server>Docker container) that allows me to run a Jupyter Notebook in my browser on my computer.
The Docker container is hosted on a machine running OS X (El Capitan). Docker is using the default machine IP: 192.168.99.100.
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.99.100:2376 v1.11.1
I am able to physically sit at the server running the Docker container and use my browser (192.168.99.100:8888) to create Jupyter Notebooks from that Docker container. This verifies that my Docker port bindings work and that I'm running the Jupyter Notebook correctly.
However, I don't know how to establish a ssh tunnel from a client machine to that remote machine's Docker container and launch a Jupyter Notebook in my browser on the client machine.
The output from:
$ docker ps
produces the following:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48a8ac126c72 kubu4/bioinformatics:v11 "/bin/bash" 55 minutes ago Up 55 minutes 8787/tcp, 0.0.0.0:8888->8888/tcp stupefied_pasteur
My attempts at creating a ssh tunnel to the remote machine's Docker container results in the following error message in Terminal when I try to launch the Jupyter Notebook in my browser on the client machine (localhost:8888):
channel 3: open failed: connect failed: Connection refused
I'm currently using the following in my .ssh/config file to create the tunnel:
Host tunnel3
HostName remote.ip.address
User user
ControlMaster auto
ServerAliveInterval 30
ServerAliveCountMax 3
LocalForward localhost:8888 localhost:8888
I can use this tunneling configuration to successfully launch Jupyter Notebooks in my client browser if I run the Jupyter Notebook on the remote machine outside of the Docker container that's on the remote machine.
Just for added info, this is the output when I launch the Jupyter Notebook in the remote machine's Docker container:
$ jupyter notebook
[I 18:23:32.951 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
[I 18:23:33.072 NotebookApp] Serving notebooks from local directory: /usr/local/bioinformatics
[I 18:23:33.073 NotebookApp] 0 active kernels
[I 18:23:33.073 NotebookApp] The Jupyter Notebook is running at: http://0.0.0.0:8888/
[I 18:23:33.074 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
Had the same problem, trying to ssh-tunnel into a google cloud instance, then into a docker container.
Find the IP address Debian assigns to docker (credit):
This gave me 172.18.0.2 for the first instance running, 172.18.0.3 for the second, ..0.4, ..0.5, etc.
(Note: The below didn't work if I was running multiple containers on the same instance. Since I only need to run one container, I'm not going to figure out how to fix it)
ssh into the compute instance
Make sure ports are exposed between your Docker container and Compute instance (I used 8888:8888), then (credit):
Run jupyter
Now I can open my local browser to localhost:8888/?token... and use jupyter running in a container on my gcloud instance.
I figured it out! The "A-ha!" moment was remembering that the remote machine running Docker was OS X (El Capitan). All my Docker builds/tests had been performed on a Linux (Ubuntu 14.04) machine. The difference, it turns out, is critical to solving this problem.
Docker installs on Ubuntu allow you to use "localhost" to address the Docker container. Docker installs on OSX generate an IP address to use to address the Docker container.
Realizing this, I changed my ssh tunneling configuration in the.ssh/config file on my client computer.
Old tunneling config:
New tunneling config:
With this change, I can successfully create/use Jupyter Notebooks in my client browser that are actually hosted in the Docker container on the remote machine, using localhost:8888 in the URL bar.