Concerns about Redirecting to Local JupyterHub

Hi all,

I have a concern regarding accessing a local JupyterHub via a public IP. Here’s my scenario: I have a website running on a public IP address, and within that webpage, there’s a tab labeled “Jupyter.” When a user clicks on that tab, it redirects them to the local JupyterHub IP using port forwarding. However, I’m uncertain about how the spawner and user accounts would function in this setup. Any insights or best practices would be greatly appreciated.

Best, James

You only need to expose a single host/port for JupyterHub, by default this is port 8000. JupyterHub runs its own proxy to manage connections between the front-end web and singleuser servers, but as long as everything is correctly configured that shouldn’t matter.

If you’re running into problems can you tell us how you’ve setup your JupyterHub, and show us your configuration?

Hi manics,

Thanks for your response. Currently I am waiting for my team to allow a port to be open to the public. From there, I will then continue with setting up the JupyterHub.

My configuration in jupyterhub_config.py is as shown below. However, this is a local setup which works out.

import os, pwd                                                                                                                                                                                
import inspect, concurrent,asyncio                                                                                                                                                            
                                                                                                                                                                                              
from subprocess import check_call, Popen, STDOUT                                                                                                                                              
                                                                                                                                                                                              
# log file                                                                                                                                                                                    
logfile = open('/var/log/singleuser.log', 'wb')                                                                                                                                               
Popen(['jupyterhub-singleuser'], stdout=logfile, stderr=STDOUT)                                                                                                                               
                                                                                                                                                                                              
# generate key                                                                                                                                                                                
if 'JUPYTERHUB_CRYPT_KEY' not in os.environ:                                                                                                                                                  
        c.CryptKeeper.keys = [ os.urandom(32) ]                                                                                                                                               
                                                                                                                                                                                              
# globus config                                                                                                                                                                               
c.OAuthenticator.authorize_url = "https://auth.globus.org/v2/oauth2/authorize"                                                                                                                
c.OAuthenticator.token_url = "https://auth.globus.org/v2/oauth2/token"                                                                                                                        
c.OAuthenticator.userdata_url = "https://auth.globus.org/v2/oauth2/userinfo"                                                                                                                  
c.OAuthenticator.logout_redirect_url = 'https://globus.org/logout'                                                                                                                            
c.JupyterHub.authenticator_class = "globus"                                                                                                                                                   
                                                                                                                                                                                              
c.OAuthenticator.scope = ['openid', 'profile', 'email']                                                                                                                                       
c.OAuthenticator.exclude_tokens = ['auth.globus.org']                                                                                                                                         
c.OAuthenticator.revoke_tokens_on_logout = False                                                                                                                                              
                                                                                                                                                                                              
# Globus Authentication                                                                                                                                                                       
c.OAuthenticator.oauth_callback_url = "http://127.0.0.1:8888/hub/oauth_callback"                                                                                                              
c.OAuthenticator.client_id = <client id>                                                                                                                           
c.OAuthenticator.client_secret = <client secret>
c.OAuthenticator.allow_all = True                                                                                                                                                             
c.OAuthenticator.enable_auth_state = True
c = get_config()
c.JupyterHub.admin_access = True 
c.JupyterHub.base_url = '/'
c.JupyterHub.bind_url = 'http://127.0.0.1:8888'
c.JupyterHub.data_files_path = '/home/<username>/jupyterhub/share/jupyterhub'
c.JupyterHub.debug_proxy = True
c.JupyterHub.extra_log_file = '/var/log/jupyterhub.log' 
c.JupyterHub.hub_ip = '127.0.0.1'
c.JupyterHub.hub_port = 8087
c.Spawner.args = ['--debug'] 
c.Spawner.cmd = ['jupyterhub-singleuser']
c.Spawner.debug = True
c.Spawner.default_url = '/lab'
c.Spawner.disable_user_config = True
c.Spawner.notebook_dir = '/opt/{username}'
c.Authenticator.auto_login = True                                                                                                                                                             

Currently, We are unsure how we can transition from a local setup to a public setup, and we would like to get some suggestions from the community.

Below is a simple setup for our JupyterHub. In the diagram, we have a public IP running a web service. On the web service, we have a tab that redirects users to a host (in a local network) running JupyterHub. I am curious if this setup is possible since we need to have a public IP and port running JupyterHub for Globus to work. If we have to run JupyterHub on a public IP and port, is there a way to make users access JupyterHub via our web service and not directly from the public IP? Thanks in advance for the help provided.
JupyterHub

best,
james

I’m not sure what you mean by “via our web service”. However many JupyterHub deployment use a reverse proxy such as Nginx:

Any HTTP proxy that supports websockets should work.

Since you’re using OAuthenticator oauth_callback_url needs to be an externally accessible URL (which will be forwarded to JupyterHub by the proxy).

If I am understanding it correctly, we can setup the jupyterhub in a local environment running on 127.0.0.1 and using nginx, we will redirect an IP to 127.0.0.1 which jupyterhub is running on? Since I am using the oauth_callback_url to authenticate my jupyterhub, I will need a Public IP and port to reach from globus back to the 127.0.0.1?

You can’t redirect a user to 127.0.0.1 since that’s only accessible internally. You need to use Nginx as a reverse proxy.

If you’re not familiar with reverse proxies https://www.cloudflare.com/en-gb/learning/cdn/glossary/reverse-proxy/ contains a brief explanation.

Thanks for the direction. I will try that out, and if I have further questions, I will definitely post it here.