Good afternoon!
I’ve been trying to setup a VM with a public-facing JupyterHub that provides users with Notebooks within Docker containers.
I’ve followed https://jupyterhub.readthedocs.io/en/stable/installation-guide.html which has worked absolutely fine. It resulted in a working core with GitHub OAuth and SSL encryption through nginx. But upon trying to incorporate DockerSpawner all attempts to create a server now yield 500 errors as below:
Failed to connect to Hub API at ‘http:// 172.17.0.1:8081/jupyter/hub/api’. Is the Hub accessible at this URL (from host: b1845483a200)?
I have been trying to debug this for at least a week now, and have read every post/resource mentioning anything similar that I can find with no luck. My relevant files/logs are below (hopefully I didn’t go overboard in this regard), please let me know if you have any suggestions or require further details. Thank you!
(note the random url spaces are due to the link limit)
jupyterhub_config.py
c.JupyterHub.bind_url = ‘https:// 127.0.0.1:8000/jupyter’
from dockerspawner import DockerSpawner
c.JupyterHub.spawner_class = DockerSpawner
import netifaces
docker0 = netifaces.ifaddresses( ‘docker0’ )
docker0_ipv4 = docker0[netifaces.AF_INET][0]
c.JupyterHub.hub_ip = ‘0.0.0.0’
c.DockerSpawner.hub_ip_connect = docker0_ipv4[ ‘addr’ ]
c.Spawner.debug = True
c.LocalProcessSpawner.debug = True
c.JupyterHub.log_level = ‘DEBUG’
docker logs (repetition trimmed)
Executing the command: jupyterhub-singleuser --ip=0.0.0.0 --port=8888 --debug --hub-api-url=http://172.17.0.1:8081/jupyter/hub/api
…
[I 2021-03-17 14:40:40.881 SingleUserNotebookApp mixins:557] Starting jupyterhub-singleuser server version 1.3.0
[E 2021-03-17 14:40:40.884 SingleUserNotebookApp mixins:430] Failed to connect to my Hub at http:// 172.17.0.1:8081/jupyter/hub/api (attempt 1/5). Is it running?
Traceback (most recent call last):
File “/opt/conda/lib/python3.8/site-packages/jupyterhub/singleuser/mixins.py”, line 428, in check_hub_version
resp = await client.fetch(self.hub_api_url)
ConnectionRefusedError: [Errno 111] Connection refused
…
[E 2021-03-17 14:40:42.107 SingleUserNotebookApp auth:333] Error connecting to http:// 172.17.0.1:8081/jupyter/hub/api: HTTPConnectionPool(host=‘172.17.0.1’, port=8081): Max retries exceeded with url: /jupyter/hub/api/oauth2/token (Caused by NewConnectionError(‘<urllib3.connection.HTTPConnection object at 0x7f1fd92394c0>: Failed to establish a new connection: [Errno 111] Connection refused’))
JupyterHub Logs (tried to trim it down)
[I 2021-03-17 16:47:57.682 JupyterHub app:2349] Running JupyterHub version 1.3.0
[I 2021-03-17 16:47:57.682 JupyterHub app:2379] Using Authenticator: oauthenticator.github.LocalGitHubOAuthenticator-0.13.0
[I 2021-03-17 16:47:57.683 JupyterHub app:2379] Using Spawner: dockerspawner.dockerspawner.DockerSpawner-0.11.1
[I 2021-03-17 16:47:57.683 JupyterHub app:2379] Using Proxy: jupyterhub.proxy.ConfigurableHTTPProxy-1.3.0
…
[I 2021-03-17 16:47:57.755 JupyterHub proxy:666] Starting proxy @ http:// 127.0.0.1:8000/jupyter
[D 2021-03-17 16:47:57.755 JupyterHub proxy:667] Proxy cmd: [‘configurable-http-proxy’, ‘–ip’, ‘127.0.0.1’, ‘–port’, ‘8000’, ‘–api-ip’, ‘127.0.0.1’, ‘–api-port’, ‘8001’, ‘–error-target’, ‘http:// SERVER.helsinki. fi:8081/jupyter/hub/error’]
…
16:47:58.376 [ConfigProxy] info: Proxying http:// 127.0.0.1:8000 to (no default)
16:47:58.379 [ConfigProxy] info: Proxy API at http:// 127.0.0.1:8001/api/routes
[D 2021-03-17 16:47:58.737 JupyterHub proxy:702] Proxy started and appears to be up
[D 2021-03-17 16:47:58.745 JupyterHub proxy:795] Proxy: Fetching GET http:// 127.0.0.1:8001/api/routes
[I 2021-03-17 16:47:58.760 JupyterHub app:2664] Hub API listening on http:// 0.0.0.0:8081/jupyter/hub/
[I 2021-03-17 16:47:58.761 JupyterHub app:2666] Private Hub API connect url http:// SERVER.helsinki. fi:8081/jupyter/hub/
[D 2021-03-17 16:47:58.761 JupyterHub proxy:314] Fetching routes to check
[D 2021-03-17 16:47:58.761 JupyterHub proxy:795] Proxy: Fetching GET http:// 127.0.0.1:8001/api/routes
16:47:58.763 [ConfigProxy] info: 200 GET /api/routes
[I 2021-03-17 16:47:58.765 JupyterHub proxy:319] Checking routes
[I 2021-03-17 16:47:58.766 JupyterHub proxy:399] Adding default route for Hub: /jupyter/ => http:// SERVER.helsinki. fi:8081
[D 2021-03-17 16:47:58.766 JupyterHub proxy:795] Proxy: Fetching POST http:// 127.0.0.1:8001/api/routes/jupyter
16:47:58.768 [ConfigProxy] info: 200 GET /api/routes
16:47:58.770 [ConfigProxy] info: Adding route /jupyter → http:// SERVER.helsinki. fi:8081
16:47:58.771 [ConfigProxy] info: Route added /jupyter → http:// SERVER.helsinki. fi:8081
[I 2021-03-17 16:47:58.772 JupyterHub app:2739] JupyterHub is now running at http:// 127.0.0.1:8000/jupyter
[D 2021-03-17 16:47:58.773 JupyterHub app:2342] It took 1.100 seconds for the Hub to start
16:47:58.774 [ConfigProxy] info: 201 POST /api/routes/jupyter
…
[D 2021-03-17 16:48:08.816 JupyterHub user:288] Creating <class ‘dockerspawner.dockerspawner.DockerSpawner’> for djprice:
…
[D 2021-03-17 16:48:08.916 JupyterHub dockerspawner:873] Starting host with config: {‘binds’: {}, ‘links’: {}, ‘port_bindings’: {8888: (‘127.0.0.1’,)}, ‘network_mode’: ‘bridge’}
[I 2021-03-17 16:48:08.979 JupyterHub dockerspawner:985] Created container jupyter-djprice (id: 2b021c7) from image jupyterhub/singleuser:1.3
…
[I 2021-03-17 16:48:09.938 JupyterHub pages:402] djprice is pending spawn
[I 2021-03-17 16:48:09.994 JupyterHub log:181] 200 GET /jupyter/hub/spawn-pending/djprice (djprice@SERVER-IP) 63.00ms
[D 2021-03-17 16:48:12.732 JupyterHub utils:224] Server at http:// 127.0.0.1:49158/jupyter/user/djprice/ responded with 302
[D 2021-03-17 16:48:12.732 JupyterHub _version:76] jupyterhub and jupyterhub-singleuser both on version 1.3.0
[I 2021-03-17 16:48:12.732 JupyterHub base:904] User djprice took 3.878 seconds to start
[I 2021-03-17 16:48:12.733 JupyterHub proxy:257] Adding user djprice to proxy /jupyter/user/djprice/ => http:// 127.0.0.1:49158
[D 2021-03-17 16:48:12.733 JupyterHub proxy:795] Proxy: Fetching POST http:// 127.0.0.1:8001/api/routes/jupyter/user/djprice
16:48:12.736 [ConfigProxy] info: Adding route /jupyter/user/djprice → http:// 127.0.0.1:49158
16:48:12.737 [ConfigProxy] info: Route added /jupyter/user/djprice → http:// 127.0.0.1:49158
16:48:12.737 [ConfigProxy] info: 201 POST /api/routes/jupyter/user/djprice
[I 2021-03-17 16:48:12.739 JupyterHub users:664] Server djprice is ready
[I 2021-03-17 16:48:12.741 JupyterHub log:181] 200 GET /jupyter/hub/api/users/djprice/server/progress (djprice@SERVER-IP) 2593.07ms
[I 2021-03-17 16:48:12.812 JupyterHub log:181] 302 GET /jupyter/hub/spawn-pending/djprice → /jupyter/user/djprice/ (djprice@SERVER-IP) 4.34ms
[D 2021-03-17 16:48:12.929 JupyterHub provider:409] Validating client id jupyterhub-user-djprice
[D 2021-03-17 16:48:12.930 JupyterHub provider:484] validate_redirect_uri: client_id=jupyterhub-user-djprice, redirect_uri=/jupyter/user/djprice/oauth_callback
[D 2021-03-17 16:48:12.932 JupyterHub auth:244] Skipping oauth confirmation for <User(djprice 1/1 running)> accessing Server at /jupyter/user/djprice/
[D 2021-03-17 16:48:12.933 JupyterHub provider:409] Validating client id jupyterhub-user-djprice
[D 2021-03-17 16:48:12.934 JupyterHub provider:484] validate_redirect_uri: client_id=jupyterhub-user-djprice, redirect_uri=/jupyter/user/djprice/oauth_callback
[D 2021-03-17 16:48:12.935 JupyterHub provider:231] Saving authorization code jupyterhub-user-djprice, OxC…, (), {}
[I 2021-03-17 16:48:12.954 JupyterHub log:181] 302 GET /jupyter/hub/api/oauth2/authorize?client_id=jupyterhub-user-djprice&redirect_uri=%2Fjupyter%2Fuser%2Fdjprice%2Foauth_callback&response_type=code&state=[secret] → /jupyter/user/djprice/oauth_callback?code=[secret]&state=[secret] (djprice@SERVER-IP) 26.87ms
[D 2021-03-17 16:48:39.447 JupyterHub dockerspawner:777] Getting container ‘jupyter-djprice’
[D 2021-03-17 16:48:39.451 JupyterHub dockerspawner:761] Container 2b021c7 status: {‘Dead’: False,
‘Error’: ‘’,
‘ExitCode’: 0,
‘FinishedAt’: ‘0001-01-01T00:00:00Z’,
‘OOMKilled’: False,
‘Paused’: False,
‘Pid’: 8919,
‘Restarting’: False,
‘Running’: True,
‘StartedAt’: ‘2021-03-17T14:48:09.429332729Z’,
‘Status’: ‘running’}
[W 2021-03-17 16:49:09.454 JupyterHub base:1067] User djprice server stopped, with exit code: ExitCode=1, Error=‘’, FinishedAt=2021-03-17T14:48:57.811885955Z
[I 2021-03-17 16:49:09.454 JupyterHub proxy:281] Removing user djprice from proxy (/jupyter/user/djprice/)
[D 2021-03-17 16:49:09.454 JupyterHub proxy:795] Proxy: Fetching DELETE http:// 127.0.0.1:8001/api/routes/jupyter/user/djprice
16:49:09.457 [ConfigProxy] info: Removing route /jupyter/user/djprice
16:49:09.457 [ConfigProxy] info: 204 DELETE /api/routes/jupyter/user/djprice
[D 2021-03-17 16:49:09.458 JupyterHub user:790] Stopping djprice
Docker Inspect
“Ports”: { “8888/tcp”: [ {
“HostIp”: “127.0.0.1”,
“HostPort”: “49159” } ] },
“Gateway”: “172.17.0.1”,
“IPAddress”: “172.17.0.3”,
The docker container spawned by the Hub dies too fast for testing, but I did manually run the jupyterhub/singleuser image and try to connect to the Hub from inside in a variety of ways with no luck beyond this one example:
$ sudo docker exec thirsty_kowalevski wget -O- https:// 172.17.0.1/jupyter/hub/api --no-check-certificate
–2021-03-12 14:51:14-- https:// 172.17.0.1/jupyter/hub/api
Connecting to 172.17.0.1:443… connected.
WARNING: cannot verify 172.17.0.1’s certificate, issued by ‘CN=GEANT OV RSA CA 4,O=GEANT Vereniging,C=NL’:
Unable to locally verify the issuer’s authority.
WARNING: certificate common name ‘SERVER.helsinki. fi’ doesn’t match requested host name ‘172.17.0.1’.
HTTP request sent, awaiting response… 200 OK
Length: 20 [application/json]
Saving to: ‘STDOUT’
0K 100% 3.89M=0s
2021-03-12 14:51:14 (3.89 MB/s) - written to stdout [20/20]
But connecting from the server to the container works using the forwarded port, albeit as an isolated test not connected to the Hub. It feels like I’m missing something regarding the communication, maybe with configurable-http-proxy and docker, but can’t quite track it down. Thanks again for any input.