mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-11 12:03:00 +00:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7837a9cf68 | ||
![]() |
65a019e05b | ||
![]() |
f2014c5687 | ||
![]() |
109c315336 | ||
![]() |
941fc7e627 | ||
![]() |
80215f6b3c | ||
![]() |
84916062f0 | ||
![]() |
641154bf06 | ||
![]() |
14b0dbde0e | ||
![]() |
cd85766441 | ||
![]() |
6c072bdb3d | ||
![]() |
35f080458e | ||
![]() |
feac4f6bc4 | ||
![]() |
1bbabbb989 |
@@ -2,7 +2,24 @@
|
|||||||
|
|
||||||
See `git log` for a more detailed summary.
|
See `git log` for a more detailed summary.
|
||||||
|
|
||||||
## 0.3.0
|
## 0.4
|
||||||
|
|
||||||
|
### 0.4.1
|
||||||
|
|
||||||
|
Fix removal of `/login` page in 0.4.0, breaking some OAuth providers.
|
||||||
|
|
||||||
|
### 0.4.0
|
||||||
|
|
||||||
|
- Add `Spawner.user_options_form` for specifying an HTML form to present to users,
|
||||||
|
allowing users to influence the spawning of their own servers.
|
||||||
|
- Add `Authenticator.pre_spawn_start` and `Authenticator.post_spawn_stop` hooks,
|
||||||
|
so that Authenticators can do setup or teardown (e.g. passing credentials to Spawner,
|
||||||
|
mounting data sources, etc.).
|
||||||
|
These methods are typically used with custom Authenticator+Spawner pairs.
|
||||||
|
- 0.4 will be the last JupyterHub release where single-user servers running IPython 3 is supported instead of Notebook ≥ 4.0.
|
||||||
|
|
||||||
|
|
||||||
|
## 0.3
|
||||||
|
|
||||||
- No longer make the user starting the Hub an admin
|
- No longer make the user starting the Hub an admin
|
||||||
- start PAM sessions on login
|
- start PAM sessions on login
|
||||||
@@ -10,13 +27,13 @@ See `git log` for a more detailed summary.
|
|||||||
allowing deeper interaction between Spawner/Authenticator pairs.
|
allowing deeper interaction between Spawner/Authenticator pairs.
|
||||||
- login redirect fixes
|
- login redirect fixes
|
||||||
|
|
||||||
## 0.2.0
|
## 0.2
|
||||||
|
|
||||||
- Based on standalone traitlets instead of IPython.utils.traitlets
|
- Based on standalone traitlets instead of IPython.utils.traitlets
|
||||||
- multiple users in admin panel
|
- multiple users in admin panel
|
||||||
- Fixes for usernames that require escaping
|
- Fixes for usernames that require escaping
|
||||||
|
|
||||||
## 0.1.0
|
## 0.1
|
||||||
|
|
||||||
First preview release
|
First preview release
|
||||||
|
|
||||||
|
@@ -14,11 +14,11 @@ See [the readme](https://github.com/jupyter/jupyterhub/blob/master/README.md) fo
|
|||||||
JupyterHub is a set of processes that together provide a multiuser Jupyter Notebook server.
|
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:
|
There are three main categories of processes run by the `jupyterhub` command line program:
|
||||||
|
|
||||||
- *Single User Server*: a dedicated, single-user, Jupyter Notebook is started for each user on the system
|
- **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*.
|
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
|
- **Proxy**: the public facing part of the server that uses a dynamic proxy to route HTTP requests
|
||||||
to the *Hub* and *Single User Servers*.
|
to the Hub and Single User Servers.
|
||||||
- *Hub*: manages user accounts and authentication and coordinates *Single Users Servers* using a *Spawner*.
|
- **Hub**: manages user accounts and authentication and coordinates Single Users Servers using a Spawner.
|
||||||
|
|
||||||
## JupyterHub's default behavior
|
## JupyterHub's default behavior
|
||||||
|
|
||||||
@@ -34,29 +34,29 @@ Any user on the system with a password will be allowed to start a single-user no
|
|||||||
The default Spawner starts servers locally as each user, one dedicated server per user.
|
The default Spawner starts servers locally as each user, one dedicated server per user.
|
||||||
These servers listen on localhost, and start in the given user's home directory.
|
These servers listen on localhost, and start in the given user's home directory.
|
||||||
|
|
||||||
By default, the *Proxy* listens on all public interfaces on port 8000.
|
By default, the **Proxy** listens on all public interfaces on port 8000.
|
||||||
Thus you can reach JupyterHub through:
|
Thus you can reach JupyterHub through either:
|
||||||
|
|
||||||
http://localhost:8000
|
http://localhost:8000
|
||||||
|
|
||||||
or any other public IP or domain pointing to your system.
|
or any other public IP or domain pointing to your system.
|
||||||
|
|
||||||
In their default configuration, the other services, the *Hub* and *Single-User Servers*,
|
In their default configuration, the other services, the **Hub** and **Single-User Servers**,
|
||||||
all communicate with each other on localhost only.
|
all communicate with each other on localhost only.
|
||||||
|
|
||||||
**NOTE:** In its default configuration, JupyterHub runs without SSL encryption (HTTPS).
|
**NOTE:** In its default configuration, JupyterHub runs without SSL encryption (HTTPS).
|
||||||
You should not run JupyterHub without SSL encryption on a public network.
|
You should not run JupyterHub without SSL encryption on a public network.
|
||||||
See [below](#Security) for how to configure JupyterHub to use SSL.
|
See [Security documentation](#Security) for how to configure JupyterHub to use SSL.
|
||||||
|
|
||||||
By default, starting JupyterHub will write two files to disk in the current working directory:
|
By default, starting JupyterHub will write two files to disk in the current working directory:
|
||||||
|
|
||||||
- `jupyterhub.sqlite` is the sqlite database containing all of the state of the *Hub*.
|
- `jupyterhub.sqlite` is the sqlite database containing all of the state of the **Hub**.
|
||||||
This file allows the *Hub* to remember what users are running and where,
|
This file allows the **Hub** to remember what users are running and where,
|
||||||
as well as other information enabling you to restart parts of JupyterHub separately.
|
as well as other information enabling you to restart parts of JupyterHub separately.
|
||||||
- `jupyterhub_cookie_secret` is the encryption key used for securing cookies.
|
- `jupyterhub_cookie_secret` is the encryption key used for securing cookies.
|
||||||
This file needs to persist in order for restarting the Hub server to avoid invalidating cookies.
|
This file needs to persist in order for restarting the Hub server to avoid invalidating cookies.
|
||||||
Conversely, deleting this file and restarting the server effectively invalidates all login cookies.
|
Conversely, deleting this file and restarting the server effectively invalidates all login cookies.
|
||||||
The cookie secret file is discussed [below](#Security).
|
The cookie secret file is discussed in the [Cookie Secret documentation](#Cookie secret).
|
||||||
|
|
||||||
The location of these files can be specified via configuration, discussed below.
|
The location of these files can be specified via configuration, discussed below.
|
||||||
|
|
||||||
@@ -96,32 +96,37 @@ on the config system Jupyter uses.
|
|||||||
|
|
||||||
## Networking
|
## Networking
|
||||||
|
|
||||||
In most situations you will want to change the main IP address and port of the Proxy.
|
### Configuring the Proxy's IP address and port
|
||||||
This address determines where JupyterHub is available to your users.
|
The Proxy's main IP address setting determines where JupyterHub is available to users.
|
||||||
The default is all network interfaces (`''`) on port 8000.
|
By default, JupyterHub is configured to be available on all network interfaces
|
||||||
|
(`''`) on port 8000. **Note**: Use of `'*'` is discouraged for IP configuration;
|
||||||
|
instead, use of `'0.0.0.0'` is preferred.
|
||||||
|
|
||||||
This can be done with the following command line arguments:
|
Changing the IP address and port can be done with the following command line
|
||||||
|
arguments:
|
||||||
|
|
||||||
jupyterhub --ip=192.168.1.2 --port=443
|
jupyterhub --ip=192.168.1.2 --port=443
|
||||||
|
|
||||||
Or you can put the following lines in a configuration file:
|
Or by placing the following lines in a configuration file:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
c.JupyterHub.ip = '192.168.1.2'
|
c.JupyterHub.ip = '192.168.1.2'
|
||||||
c.JupyterHub.port = 443
|
c.JupyterHub.port = 443
|
||||||
```
|
```
|
||||||
|
|
||||||
Port 443 is used in these examples as it is the default port for SSL/HTTPS.
|
Port 443 is used as an example since 443 is the default port for SSL/HTTPS.
|
||||||
|
|
||||||
Configuring only the main IP and port of JupyterHub should be sufficient for most deployments of JupyterHub.
|
Configuring only the main IP and port of JupyterHub should be sufficient for most deployments of JupyterHub.
|
||||||
However, for more customized scenarios,
|
However, more customized scenarios may need additional networking details to
|
||||||
you can configure the following additional networking details.
|
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,
|
The Hub service talks to the proxy via a REST API on a secondary port,
|
||||||
whose network interface and port can be configured separately.
|
whose network interface and port can be configured separately.
|
||||||
By default, this REST API listens on port 8081 of localhost only.
|
By default, this REST API listens on port 8081 of localhost only.
|
||||||
If you want to run the Proxy separate from the Hub,
|
|
||||||
you may need to configure this IP and port with:
|
If running the Proxy separate from the Hub,
|
||||||
|
configure the REST API communication IP address and port with:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# ideally a private network address
|
# ideally a private network address
|
||||||
@@ -129,11 +134,12 @@ c.JupyterHub.proxy_api_ip = '10.0.1.4'
|
|||||||
c.JupyterHub.proxy_api_port = 5432
|
c.JupyterHub.proxy_api_port = 5432
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Configuring the Hub if Spawners or Proxy are remote or isolated in containers
|
||||||
The Hub service also listens only on localhost (port 8080) by default.
|
The Hub service also listens only on localhost (port 8080) by default.
|
||||||
The Hub needs needs to be accessible from both the proxy and all Spawners.
|
The Hub needs needs to be accessible from both the proxy and all Spawners.
|
||||||
When spawning local servers localhost is fine,
|
When spawning local servers, an IP address setting of localhost is fine.
|
||||||
but if *either* the Proxy or (more likely) the Spawners will be remote or isolated in containers,
|
If *either* the Proxy *or* (more likely) the Spawners will be remote or
|
||||||
the Hub must listen on an IP that is accessible.
|
isolated in containers, the Hub must listen on an IP that is accessible.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
c.JupyterHub.hub_ip = '10.0.1.4'
|
c.JupyterHub.hub_ip = '10.0.1.4'
|
||||||
@@ -193,7 +199,8 @@ openssl rand -hex 1024 > /srv/jupyterhub/cookie_secret
|
|||||||
|
|
||||||
In most deployments of JupyterHub, you should point this to a secure location on the file
|
In most deployments of JupyterHub, you should point this to a secure location on the file
|
||||||
system, such as `/srv/jupyterhub/cookie_secret`. If the cookie secret file doesn't exist when
|
system, such as `/srv/jupyterhub/cookie_secret`. If the cookie secret file doesn't exist when
|
||||||
the Hub starts, a new cookie secret is generated and stored in the file.
|
the Hub starts, a new cookie secret is generated and stored in the file. The recommended
|
||||||
|
permissions for the cookie secret file should be 600 (owner-only rw).
|
||||||
|
|
||||||
If you would like to avoid the need for files, the value can be loaded in the Hub process from
|
If you would like to avoid the need for files, the value can be loaded in the Hub process from
|
||||||
the `JPY_COOKIE_SECRET` environment variable:
|
the `JPY_COOKIE_SECRET` environment variable:
|
||||||
@@ -397,9 +404,9 @@ jupyterhub -f /path/to/aboveconfig.py
|
|||||||
|
|
||||||
# Further reading
|
# Further reading
|
||||||
|
|
||||||
- TODO: troubleshooting
|
|
||||||
- [Custom Authenticators](./authenticators.html)
|
- [Custom Authenticators](./authenticators.html)
|
||||||
- [Custom Spawners](./spawners.html)
|
- [Custom Spawners](./spawners.html)
|
||||||
|
- [Troubleshooting](./troubleshooting.html)
|
||||||
|
|
||||||
|
|
||||||
[oauth-setup]: https://github.com/jupyter/oauthenticator#setup
|
[oauth-setup]: https://github.com/jupyter/oauthenticator#setup
|
||||||
|
@@ -5,7 +5,7 @@ JupyterHub is a multi-user server that manages and proxies multiple instances of
|
|||||||
There are three basic processes involved:
|
There are three basic processes involved:
|
||||||
|
|
||||||
- multi-user Hub (Python/Tornado)
|
- multi-user Hub (Python/Tornado)
|
||||||
- configurable http proxy (nodejs)
|
- [configurable http proxy](https://github.com/jupyter/configurable-http-proxy) (node-http-proxy)
|
||||||
- multiple single-user IPython notebook servers (Python/IPython/Tornado)
|
- multiple single-user IPython notebook servers (Python/IPython/Tornado)
|
||||||
|
|
||||||
The proxy is the only process that listens on a public interface.
|
The proxy is the only process that listens on a public interface.
|
||||||
|
@@ -15,7 +15,7 @@ of the single-user Jupyter notebook server.
|
|||||||
Three actors:
|
Three actors:
|
||||||
|
|
||||||
* multi-user Hub (tornado process)
|
* multi-user Hub (tornado process)
|
||||||
* configurable http proxy (node-http-proxy)
|
* `configurable http proxy <https://github.com/jupyter/configurable-http-proxy>`_ (node-http-proxy)
|
||||||
* multiple single-user IPython notebook servers (Python/IPython/tornado)
|
* multiple single-user IPython notebook servers (Python/IPython/tornado)
|
||||||
|
|
||||||
Basic principles:
|
Basic principles:
|
||||||
@@ -29,7 +29,7 @@ Basic principles:
|
|||||||
Contents:
|
Contents:
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 2
|
||||||
:caption: User Documentation
|
:caption: User Documentation
|
||||||
|
|
||||||
getting-started
|
getting-started
|
||||||
@@ -41,6 +41,7 @@ Contents:
|
|||||||
|
|
||||||
authenticators
|
authenticators
|
||||||
spawners
|
spawners
|
||||||
|
troubleshooting
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
@@ -157,4 +157,4 @@ When `Spawner.spawn` is called, this dictionary is accessible as `self.user_opti
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Spawner]: ../jupyterhub/spawner.py
|
[Spawner]: https://github.com/jupyter/jupyterhub/blob/master/jupyterhub/spawner.py
|
||||||
|
11
docs/source/troubleshooting.md
Normal file
11
docs/source/troubleshooting.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Troubleshooting
|
||||||
|
|
||||||
|
This document is under active development.
|
||||||
|
|
||||||
|
## Networking
|
||||||
|
|
||||||
|
If JupyterHub proxy fails to start:
|
||||||
|
|
||||||
|
- check if the JupyterHub IP configuration setting is
|
||||||
|
``c.JupyterHub.ip = '*'``; if it is, try ``c.JupyterHub.ip = ''``
|
||||||
|
- Try starting with ``jupyterhub --ip=0.0.0.0``
|
@@ -86,7 +86,10 @@ class LoginHandler(BaseHandler):
|
|||||||
self.finish(html)
|
self.finish(html)
|
||||||
|
|
||||||
|
|
||||||
# Only logout is a default handler.
|
# /login renders the login page or the "Login with..." link,
|
||||||
|
# so it should always be registered.
|
||||||
|
# /logout clears cookies.
|
||||||
default_handlers = [
|
default_handlers = [
|
||||||
|
(r"/login", LoginHandler),
|
||||||
(r"/logout", LogoutHandler),
|
(r"/logout", LogoutHandler),
|
||||||
]
|
]
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
version_info = (
|
version_info = (
|
||||||
0,
|
0,
|
||||||
4,
|
4,
|
||||||
0,
|
1,
|
||||||
)
|
)
|
||||||
|
|
||||||
__version__ = '.'.join(map(str, version_info))
|
__version__ = '.'.join(map(str, version_info))
|
||||||
|
4
setup.py
4
setup.py
@@ -83,8 +83,8 @@ setup_args = dict(
|
|||||||
# this will be overridden when bower is run anyway
|
# this will be overridden when bower is run anyway
|
||||||
data_files = get_data_files() or ['dummy'],
|
data_files = get_data_files() or ['dummy'],
|
||||||
version = ns['__version__'],
|
version = ns['__version__'],
|
||||||
description = """JupyterHub: A multi-user server for Jupyter notebooks""",
|
description = "JupyterHub: A multi-user server for Jupyter notebooks",
|
||||||
long_description = "",
|
long_description = "See https://jupyterhub.readthedocs.org for more info.",
|
||||||
author = "Jupyter Development Team",
|
author = "Jupyter Development Team",
|
||||||
author_email = "jupyter@googlegroups.com",
|
author_email = "jupyter@googlegroups.com",
|
||||||
url = "http://jupyter.org",
|
url = "http://jupyter.org",
|
||||||
|
@@ -165,15 +165,13 @@ def make_env(*packages):
|
|||||||
return py
|
return py
|
||||||
|
|
||||||
|
|
||||||
def build_sdist(py, upload=False):
|
def build_sdist(py):
|
||||||
"""Build sdists
|
"""Build sdists
|
||||||
|
|
||||||
Returns the path to the tarball
|
Returns the path to the tarball
|
||||||
"""
|
"""
|
||||||
with cd(repo_root):
|
with cd(repo_root):
|
||||||
cmd = [py, 'setup.py', 'sdist', '--formats=zip,gztar']
|
cmd = [py, 'setup.py', 'sdist', '--formats=zip,gztar']
|
||||||
if upload:
|
|
||||||
cmd.append('upload')
|
|
||||||
run(cmd)
|
run(cmd)
|
||||||
|
|
||||||
return glob.glob(pjoin(repo_root, 'dist', '*.tar.gz'))[0]
|
return glob.glob(pjoin(repo_root, 'dist', '*.tar.gz'))[0]
|
||||||
@@ -184,7 +182,12 @@ def sdist(vs, upload=False):
|
|||||||
clone_repo()
|
clone_repo()
|
||||||
tag(vs, push=upload)
|
tag(vs, push=upload)
|
||||||
py = make_env()
|
py = make_env()
|
||||||
tarball = build_sdist(py, upload=upload)
|
tarball = build_sdist(py)
|
||||||
|
if upload:
|
||||||
|
with cd(repo_root):
|
||||||
|
install(py, 'twine')
|
||||||
|
run([py, '-m', 'twine', 'upload', 'dist/*'])
|
||||||
|
|
||||||
untag(vs, push=upload)
|
untag(vs, push=upload)
|
||||||
return untar(tarball)
|
return untar(tarball)
|
||||||
|
|
||||||
@@ -214,14 +217,10 @@ def untar(tarball):
|
|||||||
return glob.glob(pjoin(sdist_root, '*'))[0]
|
return glob.glob(pjoin(sdist_root, '*'))[0]
|
||||||
|
|
||||||
|
|
||||||
def bdist(upload=False):
|
def bdist():
|
||||||
"""build a wheel, optionally uploading it"""
|
"""build a wheel, optionally uploading it"""
|
||||||
py = make_env('wheel')
|
py = make_env('wheel')
|
||||||
cmd = [py, 'setup.py', 'bdist_wheel']
|
run([py, 'setup.py', 'bdist_wheel'])
|
||||||
if upload:
|
|
||||||
cmd.append('upload')
|
|
||||||
|
|
||||||
run(cmd)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
@task
|
||||||
@@ -233,7 +232,10 @@ def release(vs, upload=False):
|
|||||||
shutil.rmtree(env_root)
|
shutil.rmtree(env_root)
|
||||||
|
|
||||||
path = sdist(vs, upload=upload)
|
path = sdist(vs, upload=upload)
|
||||||
|
print("Working in %r" % path)
|
||||||
with cd(path):
|
with cd(path):
|
||||||
bdist(upload=upload)
|
bdist()
|
||||||
|
if upload:
|
||||||
|
py = make_env('twine')
|
||||||
|
run([py, '-m', 'twine', 'upload', 'dist/*'])
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user