diff --git a/docs/Makefile b/docs/Makefile index 9ca1fcaa..421d4f7d 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -47,6 +47,7 @@ help: @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " spelling to run spell check on documentation" clean: rm -rf $(BUILDDIR)/* @@ -179,6 +180,11 @@ linkcheck: @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." +spelling: + $(SPHINXBUILD) -b spelling $(ALLSPHINXOPTS) $(BUILDDIR)/spelling + @echo + @echo "Spell check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/spelling/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ diff --git a/docs/environment.yml b/docs/environment.yml index e7720b5b..6cc3d3cc 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -1,4 +1,4 @@ -name: jupyterhub_docs +name: jd channels: - conda-forge dependencies: @@ -12,5 +12,4 @@ dependencies: - traitlets>=4.1 - pip: - sphinx>=1.3.6 - - recommonmark==0.4.0 - + - recommonmark==0.4.0 \ No newline at end of file diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst index 76009e23..5fd71462 100644 --- a/docs/source/api/index.rst +++ b/docs/source/api/index.rst @@ -15,4 +15,4 @@ JupyterHub also provides a REST API for administration of the Hub and users. spawner user services.auth - rest + diff --git a/docs/source/api/rest.md b/docs/source/api/rest.md deleted file mode 100644 index c4b18714..00000000 --- a/docs/source/api/rest.md +++ /dev/null @@ -1,38 +0,0 @@ -# The JupyterHub REST API - -JupyterHub has a [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer), which you can use to perform actions on the Hub, -such as checking what users are active, adding or removing users, -stopping or starting user servers, etc. - -To get access to the JupyterHub API, you must create a token. -You can create a token for a particular user with: - - jupyterhub token USERNAME - -Alternately, you can load API tokens in your `jupyterhub_config.py`: - -```python -c.JupyterHub.api_tokens = { - 'secret-token': 'username', -} -``` - -To authenticate your requests, pass this token in the Authorization header. -For example, to list users with requests in Python: - -```python -import requests -api_url = 'http://127.0.0.1:8081/hub/api' -r = requests.get(api_url + '/users', - headers={ - 'Authorization': 'token %s' % token, - } -) -r.raise_for_status() -users = r.json() -``` - -You can see the full [REST API Spec](../_static/rest-api/index.html) for details. -A fancier version of the same information can be viewed [on swagger's petstore][]. - -[on swagger's petstore]: http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyterhub/jupyterhub/master/docs/rest-api.yml#!/default diff --git a/docs/source/api/services.auth.rst b/docs/source/api/services.auth.rst index 82ae8167..e2909726 100644 --- a/docs/source/api/services.auth.rst +++ b/docs/source/api/services.auth.rst @@ -1,6 +1,6 @@ -=========================================== -Authenticating your service with JupyterHub -=========================================== +======================= +Authenticating Services +======================= Module: :mod:`jupyterhub.services.auth` ======================================= diff --git a/docs/source/authenticators.md b/docs/source/authenticators.md index 74a247a7..1be46922 100644 --- a/docs/source/authenticators.md +++ b/docs/source/authenticators.md @@ -1,4 +1,4 @@ -# Writing a custom Authenticator +# Authenticators The [Authenticator][] is the mechanism for authorizing users. Basic authenticators use simple username and password authentication. @@ -18,7 +18,6 @@ See a list of custom Authenticators [on the wiki](https://github.com/jupyter/jup A basic Authenticator has one central method: - ### Authenticator.authenticate Authenticator.authenticate(handler, data) @@ -55,7 +54,6 @@ class DictionaryAuthenticator(Authenticator): return data['username'] ``` - ### Authenticator.whitelist Authenticators can specify a whitelist of usernames to allow authentication. @@ -103,6 +101,8 @@ You can see an example implementation of an Authenticator that uses [GitHub OAut at [OAuthenticator][]. +## Writing a custom authenticator + [Authenticator]: https://github.com/jupyter/jupyterhub/blob/master/jupyterhub/auth.py [PAM]: https://en.wikipedia.org/wiki/Pluggable_authentication_module [OAuth]: https://en.wikipedia.org/wiki/OAuth diff --git a/docs/source/changelog.md b/docs/source/changelog.md index df697f16..4a49cc66 100644 --- a/docs/source/changelog.md +++ b/docs/source/changelog.md @@ -1,6 +1,6 @@ -# Summary of changes in JupyterHub +# Change log summary -See `git log` for a more detailed summary. +See `git log` for additional detail. ## 0.6 diff --git a/docs/source/conf.py b/docs/source/conf.py index cd0fad2b..3782ea67 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,6 +38,14 @@ extensions = [ 'sphinx.ext.napoleon', ] +# Spelling +try: + import sphinxcontrib.spelling +except ImportError: + pass +else: + extensions.append("sphinxcontrib.spelling") + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -131,7 +139,10 @@ html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +html_theme_options = { + 'collapse_navigation': False, + 'display_version': False, +} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] @@ -388,3 +399,6 @@ else: from subprocess import check_call as sh sh(['make', 'rest-api'], cwd=docs) # otherwise, readthedocs.org uses their theme by default, so no need to specify it + +# Spell checking using sphinxcontrib-spelling +spelling_word_list_filename='spelling_wordlist.txt' diff --git a/docs/source/config-examples.md b/docs/source/config-examples.md index 17f3ff3f..05d41aea 100644 --- a/docs/source/config-examples.md +++ b/docs/source/config-examples.md @@ -91,7 +91,7 @@ In the following example, we show configuration files for a JupyterHub server ru Let's start out with `jupyterhub_config.py`: ```python -#Force the proxy to only listen to connections to 127.0.0.1 +# Force the proxy to only listen to connections to 127.0.0.1 c.JupyterHub.ip = '127.0.0.1' ``` diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index 4725be0d..1a6e810d 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -1,26 +1,56 @@ # Getting started with JupyterHub -This document describes some of the basics of configuring JupyterHub to do what you want. -JupyterHub is highly customizable, so there's a lot to cover. +## Technical Overview + +JupyterHub is a set of processes that together provide a single user Jupyter +Notebook server for each person in a group. + +### Three subsystems +Three major subsystems run by the `jupyterhub` command line program: + +- **Single User Server**: a dedicated, single-user, Jupyter Notebook server is + started for each user on the system when the user logs in. The object that + starts these servers is called a Spawner. +- **Proxy**: the public facing part of JupyterHub that uses a dynamic proxy + to route HTTP requests to the Hub and Single User Notebook Servers. +- **Hub**: manages user accounts, authentication, and coordinates Single User + Notebook Servers using a Spawner. + +![JupyterHub subsystems](images/jhub-parts.png) -## Installation +### Deployment server +To use JupyterHub, you need a Unix server (typically Linux) running somewhere +that is accessible to your team on the network. The JupyterHub server can be +on an internal network at your organization, or it can run on the public +internet (in which case, take care with the Hub's +[security](getting-started.html#security)). -See [the readme](https://github.com/jupyter/jupyterhub/blob/master/README.md) for help installing JupyterHub. +### Basic operation +Users access JupyterHub through a web browser, by going to the IP address or +the domain name of the server. +Basic principles of operation: -## Overview +* Hub spawns proxy +* Proxy forwards all requests to hub by default +* Hub handles login, and spawns single-user servers on demand +* Hub configures proxy to forward url prefixes to single-user servers -JupyterHub is a set of processes that together provide a multiuser Jupyter Notebook server. -There are three main categories of processes run by the `jupyterhub` command line program: +Different [authenticators](authenticators.html) control access +to JupyterHub. The default one (PAM) uses the user accounts on the server where +JupyterHub is running. If you use this, you will need to create a user account +on the system for each user on your team. Using other authenticators, you can +allow users to sign in with e.g. a GitHub account, or with any single-sign-on +system your organization has. -- **Single User Server**: a dedicated, single-user, Jupyter Notebook is started for each user on the system - when they log in. The object that starts these processes is called a Spawner. -- **Proxy**: the public facing part of the server that uses a dynamic proxy to route HTTP requests - to the Hub and Single User Servers. -- **Hub**: manages user accounts and authentication and coordinates Single Users Servers using a Spawner. +Next, [spawners](spawners.html) control how JupyterHub starts +the individual notebook server for each user. The default spawner will +start a notebook server on the same machine running under their system username. +The other main option is to start each server in a separate container, often +using Docker. -## JupyterHub's default behavior +### Default behavior **IMPORTANT:** In its default configuration, JupyterHub requires SSL encryption (HTTPS) to run. **You should not run JupyterHub without SSL encryption on a public network.** @@ -61,8 +91,29 @@ By default, starting JupyterHub will write two files to disk in the current work The location of these files can be specified via configuration, discussed below. +## Installation -## How to configure JupyterHub +See the project's [README](https://github.com/jupyterhub/jupyterhub/blob/master/README.md) +for help installing JupyterHub. + +### Planning your installation + +Prior to beginning installation, it's helpful to consider some of the following: +- deployment system (bare metal, Docker) +- Authentication (PAM, OAuth, etc.) +- Spawner of singleuser notebook servers (Docker, Batch, etc.) +- Services (nbgrader, etc.) + +### Folders and File Locations + +It is recommended to put all of the files used by JupyterHub into standard +UNIX filesystem locations. + +* `/srv/jupyterhub` for all security and runtime files +* `/etc/jupyterhub` for all configuration files +* `/var/log` for log files + +## Configuration JupyterHub is configured in two ways: @@ -129,7 +180,6 @@ However, more customized scenarios may need additional networking details to be configured. - ### Configuring the Proxy's REST API communication IP address and port (optional) The Hub service talks to the proxy via a REST API on a secondary port, whose network interface and port can be configured separately. @@ -263,10 +313,13 @@ subprocess of the Hub, this should happen automatically (this is the default con Another time you must set the Proxy authentication token yourself is if you want other services, such as [nbgrader](https://github.com/jupyter/nbgrader) to also be able to connect to the Proxy. -## Configuring authentication +## Authentication and users The default Authenticator uses [PAM][] to authenticate system users with their username and password. The default behavior of this Authenticator is to allow any user with an account and password on the system to login. + +### Creating a whitelist of users + You can restrict which users are allowed to login with `Authenticator.whitelist`: @@ -274,6 +327,8 @@ You can restrict which users are allowed to login with `Authenticator.whitelist` c.Authenticator.whitelist = {'mal', 'zoe', 'inara', 'kaylee'} ``` +### Managing Hub administrators + Admin users of JupyterHub have the ability to take actions on users' behalf, such as stopping and restarting their servers, and adding and removing new users from the whitelist. @@ -292,7 +347,7 @@ then admin users have permission to log in *as other users* on their respective Note: additional configuration examples are provided in this guide's [Configuration Examples section](./config-examples.html). -### Adding and removing users +### Add or remove users from the Hub Users can be added and removed to the Hub via the admin panel or REST API. These users will be added to the whitelist and database. Restarting the Hub will not require manually updating the @@ -316,7 +371,7 @@ hosted deployments of JupyterHub, to avoid the need to manually create all your launching the service. It is not recommended when running JupyterHub in situations where JupyterHub users maps directly onto UNIX users. -## Configuring single-user servers +## Spawners and single-user notebook servers Since the single-user server is an instance of `jupyter notebook`, an entire separate multi-process application, there are many aspect of that server can configure, and a lot of ways @@ -387,23 +442,7 @@ Adding API token for Now you can run your script, i.e. `cull_idle_servers`, by providing it the API token and it will authenticate through the REST API to interact with it. -## File locations -It is recommended to put all of the files used by JupyterHub into standard UNIX filesystem locations. - -* `/srv/jupyterhub` for all security and runtime files -* `/etc/jupyterhub` for all configuration files -* `/var/log` for log files - - -# Further reading - -- [Configuration Examples](./config-examples.html) -- [Custom Authenticators](./authenticators.html) -- [Custom Spawners](./spawners.html) -- [Troubleshooting](./troubleshooting.html) - - -[oauth-setup]: https://github.com/jupyter/oauthenticator#setup -[oauthenticator]: https://github.com/jupyter/oauthenticator +[oauth-setup]: https://github.com/jupyterhub/oauthenticator#setup +[oauthenticator]: https://github.com/jupyterhub/oauthenticator [PAM]: https://en.wikipedia.org/wiki/Pluggable_authentication_module diff --git a/docs/source/images/hub-pieces.png b/docs/source/images/hub-pieces.png new file mode 100644 index 00000000..21238f64 Binary files /dev/null and b/docs/source/images/hub-pieces.png differ diff --git a/docs/source/images/jhub-parts.png b/docs/source/images/jhub-parts.png new file mode 100644 index 00000000..00826502 Binary files /dev/null and b/docs/source/images/jhub-parts.png differ diff --git a/docs/source/index.rst b/docs/source/index.rst index f03a8555..0c361e38 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,99 +1,111 @@ JupyterHub ========== -JupyterHub is a server that gives multiple users access to Jupyter notebooks, -running an independent Jupyter notebook server for each user. - -To use JupyterHub, you need a Unix server (typically Linux) running -somewhere that is accessible to your team on the network. The JupyterHub server -can be on an internal network at your organisation, or it can run on the public -internet (in which case, take care with `security `__). -Users access JupyterHub in a web browser, by going to the IP address or -domain name of the server. - -Different :doc:`authenticators ` control access -to JupyterHub. The default one (pam) uses the user accounts on the server where -JupyterHub is running. If you use this, you will need to create a user account -on the system for each user on your team. Using other authenticators, you can -allow users to sign in with e.g. a Github account, or with any single-sign-on -system your organisation has. - -Next, :doc:`spawners ` control how JupyterHub starts -the individual notebook server for each user. The default spawner will -start a notebook server on the same machine running under their system username. -The other main option is to start each server in a separate container, often -using Docker. - -JupyterHub runs as three separate parts: - -* The multi-user Hub (Python & Tornado) -* A `configurable http proxy `_ (NodeJS) -* Multiple single-user Jupyter notebook servers (Python & Tornado) - -Basic principles: - -* Hub spawns proxy -* Proxy forwards ~all requests to hub by default -* Hub handles login, and spawns single-user servers on demand -* Hub configures proxy to forward url prefixes to single-user servers - -JupyterHub also provides a -[REST API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/jupyterhub/master/docs/rest-api.yml#/default) -for administration of the Hub and users. +With JupyterHub you can create a **multi-user Hub** which spawns, manages, +and proxies multiple instances of the single-user +`Jupyter notebook `_ server. +Due to its flexibility and customization options, JupyterHub can be used to +serve notebooks to a class of students, a corporate data science group, or a +scientific research group. -Contents: +.. image:: images/jhub-parts.png + :alt: JupyterHub subsystems + :width: 40% + :align: right + + +Three subsystems make up JupyterHub: + +* a multi-user **Hub** (tornado process) +* a **configurable http proxy** (node-http-proxy) +* multiple **single-user Jupyter notebook servers** (Python/IPython/tornado) + +JupyterHub's basic flow of operations includes: + +- The Hub spawns a proxy +- The proxy forwards all requests to the Hub by default +- The Hub handles user login and spawns single-user servers on demand +- The Hub configures the proxy to forward URL prefixes to the single-user notebook servers + +For convenient administration of the Hub, its users, and services, JupyterHub +also provides a +`REST API `_. + + +Contents +-------- + +**User Guide** + +* :doc:`getting-started` +* :doc:`howitworks` +* :doc:`websecurity` +* :doc:`rest` .. toctree:: :maxdepth: 2 - :caption: User Documentation + :hidden: + :caption: User Guide getting-started howitworks websecurity + rest + +**Configuration Guide** + +* :doc:`authenticators` +* :doc:`spawners` +* :doc:`config-examples` +* :doc:`troubleshooting` .. toctree:: :maxdepth: 2 - :caption: Configuration + :hidden: + :caption: Configuration Guide - config-examples authenticators spawners + config-examples troubleshooting + +**API Reference** + +* :doc:`api/index` + .. toctree:: - :maxdepth: 1 - :caption: Developer Documentation - + :maxdepth: 2 + :hidden: + :caption: API Reference + api/index -.. toctree:: - :maxdepth: 1 - :caption: Community documentation - +**About JupyterHub** +* :doc:`changelog` .. toctree:: :maxdepth: 2 + :hidden: :caption: About JupyterHub changelog -.. toctree:: - :maxdepth: 1 - :caption: Questions? Suggestions? - - Jupyter mailing list - Jupyter website - Stack Overflow - Jupyter - Stack Overflow - Jupyter-notebook - Indices and tables -================== +------------------ * :ref:`genindex` * :ref:`modindex` -* :ref:`search` + + +Questions? Suggestions? +----------------------- + +- `Jupyter mailing list `_ +- `Jupyter website `_ + diff --git a/docs/source/rest.md b/docs/source/rest.md new file mode 100644 index 00000000..62d5bd87 --- /dev/null +++ b/docs/source/rest.md @@ -0,0 +1,61 @@ +# Using JupyterHub's REST API + +Using the JupyterHub [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer), +you can perform actions on the Hub, such as: + +- checking which users are active +- adding or removing users +- stopping or starting single user notebook servers + +## Creating an API token +To send requests using JupyterHub API, you must pass an API token with the +request. You can create a token for an individual user using the following +command: + + jupyterhub token USERNAME + + +## Adding tokens to the config file +You may also add a dictionary of API tokens and usernames to the hub's +configuration file, `jupyterhub_config.py`: + +```python +c.JupyterHub.api_tokens = { + 'secret-token': 'username', +} +``` + + +## Making an API request + +To authenticate your requests, pass the API token in the request's +Authorization header. + +**Example: List the hub's users** + +Using the popular Python requests library, the following code sends an API +request and an API token for authorization: + +```python +import requests + +api_url = 'http://127.0.0.1:8081/hub/api' + +r = requests.get(api_url + '/users', + headers={ + 'Authorization': 'token %s' % token, + } + ) + +r.raise_for_status() +users = r.json() +``` + + +## Learning more about the API + +You can see the full [REST API Spec](../_static/rest-api/index.html) for details. +The same REST API Spec can be viewed in a more visually appealing style [on swagger's petstore][]. +Both resources contain the same information and differ only in its display. + +[on swagger's petstore]: http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyterhub/jupyterhub/master/docs/rest-api.yml#!/default diff --git a/docs/source/spawners.md b/docs/source/spawners.md index 539da9b4..c1d94c8e 100644 --- a/docs/source/spawners.md +++ b/docs/source/spawners.md @@ -1,4 +1,4 @@ -# Writing a custom Spawner +# Spawners A [Spawner][] starts each single-user notebook server. The Spawner represents an abstract interface to a process, @@ -8,8 +8,11 @@ and a custom Spawner needs to be able to take three actions: - poll whether the process is still running - stop the process + ## Examples -Custom Spawners for JupyterHub can be found on the [JupyterHub wiki](https://github.com/jupyter/jupyterhub/wiki/Spawners). Some examples include: +Custom Spawners for JupyterHub can be found on the [JupyterHub wiki](https://github.com/jupyter/jupyterhub/wiki/Spawners). +Some examples include: + - [DockerSpawner](https://github.com/jupyter/dockerspawner) for spawning user servers in Docker containers * `dockerspawner.DockerSpawner` for spawning identical Docker containers for each users @@ -24,6 +27,7 @@ Custom Spawners for JupyterHub can be found on the [JupyterHub wiki](https://git - [RemoteSpawner](https://github.com/zonca/remotespawner) to spawn notebooks and a remote server and tunnel the port via SSH + ## Spawner control methods ### Spawner.start @@ -61,11 +65,11 @@ and an integer exit status, otherwise. For the local process case, `Spawner.poll` uses `os.kill(PID, 0)` to check if the local process is still running. - ### Spawner.stop `Spawner.stop` should stop the process. It must be a tornado coroutine, which should return when the process has finished exiting. + ## Spawner state JupyterHub should be able to stop and restart without tearing down @@ -97,6 +101,7 @@ def clear_state(self): self.pid = 0 ``` + ## Spawner options form (new in 0.4) @@ -115,7 +120,6 @@ If `Spawner.options_form` is undefined, the user's server is spawned directly, a See [this example](https://github.com/jupyter/jupyterhub/blob/master/examples/spawn-form/jupyterhub_config.py) for a form that allows custom CLI args for the local spawner. - ### `Spawner.options_from_form` Options from this form will always be a dictionary of lists of strings, e.g.: @@ -156,5 +160,7 @@ which would return: When `Spawner.start` is called, this dictionary is accessible as `self.user_options`. - [Spawner]: https://github.com/jupyter/jupyterhub/blob/master/jupyterhub/spawner.py + + +## Writing a custom spawner \ No newline at end of file diff --git a/docs/source/spelling_wordlist.txt b/docs/source/spelling_wordlist.txt new file mode 100644 index 00000000..5f4310d5 --- /dev/null +++ b/docs/source/spelling_wordlist.txt @@ -0,0 +1,213 @@ +admin +Afterwards +alchemyst +alope +api +API +apps +args +asctime +auth +authenticator +Authenticator +authenticators +Authenticators +Autograde +autograde +autogradeapp +autograded +Autograded +autograder +Autograder +autograding +backends +Bitdiddle +bugfix +Bugfixes +bugtracker +Carreau +Changelog +changelog +checksum +checksums +cmd +cogsci +conda +config +coroutine +coroutines +crt +customizable +datefmt +decrypted +dev +DockerSpawner +dockerspawner +dropdown +duedate +Duedate +ellachao +ellisonbg +entrypoint +env +Filenames +filesystem +formatters +formdata +formgrade +formgrader +gif +GitHub +Gradebook +gradebook +Granger +hardcoded +hOlle +Homebrew +html +http +https +hubapi +Indices +IFramed +inline +iopub +ip +ipynb +IPython +ischurov +ivanslapnicar +jdfreder +jhamrick +jklymak +jonathanmorgan +joschu +JUPYTER +Jupyter +jupyter +jupyterhub +Kerberos +kerberos +letsencrypt +lgpage +linkcheck +linux +localhost +logfile +login +logins +logout +lookup +lphk +mandli +Marr +mathjax +matplotlib +metadata +mikebolt +minrk +Mitigations +mixin +Mixin +multi +multiuser +namespace +nbconvert +nbgrader +neuroscience +nginx +np +npm +oauth +OAuth +oauthenticator +ok +olgabot +osx +PAM +phantomjs +Phantomjs +plugin +plugins +Popen +positionally +postgres +pregenerated +prepend +prepopulate +preprocessor +Preprocessor +prev +Programmatically +programmatically +ps +py +Qualys +quickstart +readonly +redSlug +reinstall +resize +rst +runtime +rw +sandboxed +sansary +singleuser +smeylan +spawner +Spawner +spawners +Spawners +spellcheck +SQL +sqlite +startup +statsd +stdin +stdout +stoppped +subclasses +subcommand +subdomain +subdomains +Subdomains +suchow +suprocesses +svurens +sys +SystemUserSpawner +systemwide +tasilb +teardown +threadsafe +timestamp +timestamps +TLD +todo +toolbar +traitlets +travis +tuples +undeletable +unicode +uninstall +UNIX +unix +untracked +untrusted +url +username +usernames +utcnow +utils +vinaykola +virtualenv +whitelist +whitespace +wildcard +Wildcards +willingc +wordlist +Workflow +workflow \ No newline at end of file diff --git a/docs/source/troubleshooting.md b/docs/source/troubleshooting.md index 26e07b26..f6a9db63 100644 --- a/docs/source/troubleshooting.md +++ b/docs/source/troubleshooting.md @@ -1,23 +1,13 @@ # Troubleshooting -This document is under active development. - When troubleshooting, you may see unexpected behaviors or receive an error -message. These two lists provide links to identifying the cause of the +message. This section provide links for identifying the cause of the problem and how to resolve it. -## Behavior problems -- [JupyterHub proxy fails to start](#jupyterhub-proxy-fails-to-start) -## Errors -- [500 error after spawning a single-user server](#500-error-after-spawning-my-single-user-server) +## Behavior -## How do I...? -- [Use a chained certificate for SSL](#chained-certificates-for-ssl) - ----- - -## JupyterHub proxy fails to start +### JupyterHub proxy fails to start If you have tried to start the JupyterHub proxy and it fails to start: @@ -25,13 +15,14 @@ If you have tried to start the JupyterHub proxy and it fails to start: ``c.JupyterHub.ip = '*'``; if it is, try ``c.JupyterHub.ip = ''`` - Try starting with ``jupyterhub --ip=0.0.0.0`` ----- -## 500 error after spawning my single-user server +## Errors +### 500 error after spawning my single-user server -You receive a 500 error when accessing the URL `/user/you/...`. This is often -seen when your single-user server cannot check your cookies with the Hub. +You receive a 500 error when accessing the URL `/user//...`. +This is often seen when your single-user server cannot verify your user cookie +with the Hub. There are two likely reasons for this: @@ -39,23 +30,23 @@ There are two likely reasons for this: configuration problems) 2. The single-user server cannot *authenticate* its requests (invalid token) -### Symptoms: +#### Symptoms The main symptom is a failure to load *any* page served by the single-user -server, met with a 500 error. This is typically the first page at `/user/you` -after logging in or clicking "Start my server". When a single-user server -receives a request, it makes an API request to the Hub to check if the cookie -corresponds to the right user. This request is logged. +server, met with a 500 error. This is typically the first page at `/user/` +after logging in or clicking "Start my server". When a single-user notebook server +receives a request, the notebook server makes an API request to the Hub to +check if the cookie corresponds to the right user. This request is logged. -If everything is working, it will look like this: +If everything is working, the response logged will be similar to this: ``` 200 GET /hub/api/authorizations/cookie/jupyter-hub-token-name/[secret] (@10.0.1.4) 6.10ms ``` You should see a similar 200 message, as above, in the Hub log when you first -visit your single-user server. If you don't see this message in the log, it -may mean that your single-user server isn't connecting to your Hub. +visit your single-user notebook server. If you don't see this message in the log, it +may mean that your single-user notebook server isn't connecting to your Hub. If you see 403 (forbidden) like this, it's a token problem: @@ -63,12 +54,12 @@ If you see 403 (forbidden) like this, it's a token problem: 403 GET /hub/api/authorizations/cookie/jupyter-hub-token-name/[secret] (@10.0.1.4) 4.14ms ``` -Check the logs of the single-user server, which may have more detailed +Check the logs of the single-user notebook server, which may have more detailed information on the cause. -### Causes and resolutions: +#### Causes and resolutions -#### No authorization request +##### No authorization request If you make an API request and it is not received by the server, you likely have a network configuration issue. Often, this happens when the Hub is only @@ -81,7 +72,7 @@ that all single-user servers can connect to, e.g.: c.JupyterHub.hub_ip = '10.0.0.1' ``` -#### 403 GET /hub/api/authorizations/cookie +##### 403 GET /hub/api/authorizations/cookie If you receive a 403 error, the API token for the single-user server is likely invalid. Commonly, the 403 error is caused by resetting the JupyterHub @@ -93,7 +84,7 @@ the container every time. This means that the same API token is used by the server for its whole life, until the container is rebuilt. The fix for this Docker case is to remove any Docker containers seeing this -issue (typicaly all containers created before a certain point in time): +issue (typically all containers created before a certain point in time): docker rm -f jupyter-name @@ -101,9 +92,10 @@ After this, when you start your server via JupyterHub, it will build a new container. If this was the underlying cause of the issue, you should see your server again. ----- -### Chained certificates for SSL +## How do I...? + +### Use a chained SSL certificate Some certificate providers, i.e. Entrust, may provide you with a chained certificate that contains multiple files. If you are using a chained