mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-16 14:33:00 +00:00
Merge branch 'master' into named_servers
This commit is contained in:
@@ -99,7 +99,7 @@ more configuration of the system.
|
|||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The [Getting Started](docs/source/getting-started.md) section of the
|
The [Getting Started](http://jupyterhub.readthedocs.io/en/latest/getting-started.html) section of the
|
||||||
documentation explains the common steps in setting up JupyterHub.
|
documentation explains the common steps in setting up JupyterHub.
|
||||||
|
|
||||||
The [**JupyterHub tutorial**](https://github.com/jupyterhub/jupyterhub-tutorial)
|
The [**JupyterHub tutorial**](https://github.com/jupyterhub/jupyterhub-tutorial)
|
||||||
|
@@ -1,45 +1,72 @@
|
|||||||
# Configuration Basics
|
# Configuration Basics
|
||||||
|
|
||||||
The [getting started document](docs/source/getting-started.md) contains
|
The section contains basic information about configuring settings for a JupyterHub
|
||||||
general information about configuring a JupyterHub deployment and the
|
deployment. The [configuration reference](./configuration-guide.html)
|
||||||
[configuration reference](docs/source/configuration-guide.md) provides more
|
provides additional detail.
|
||||||
comprehensive detail.
|
|
||||||
|
|
||||||
## JupyterHub configuration
|
This section will help you learn how to:
|
||||||
|
|
||||||
Configuration parameters may be set by:
|
- generate a default configuration file, `jupyterhub_config.py`
|
||||||
- a configuration file `jupyterhub_config.py`, or
|
- start with a specific configuration file
|
||||||
- as options from the command line.
|
- configure JupyterHub using command line options
|
||||||
|
- find information and examples for some common deployments
|
||||||
|
|
||||||
### Generate a default config file
|
## Generate a default config file
|
||||||
|
|
||||||
On startup, JupyterHub will look by default for a configuration file named
|
On startup, JupyterHub will look by default for a configuration file,
|
||||||
`jupyterhub_config.py` in the current working directory.
|
`jupyterhub_config.py`, in the current working directory.
|
||||||
|
|
||||||
To generate a default config file `jupyterhub_config.py`:
|
To generate a default config file, `jupyterhub_config.py`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
jupyterhub --generate-config
|
jupyterhub --generate-config
|
||||||
```
|
```
|
||||||
|
|
||||||
This default `jupyterhub_config.py` file contains comments and guidance for all
|
This default `jupyterhub_config.py` file contains comments and guidance for all
|
||||||
configuration variables and their default values.
|
configuration variables and their default values. We recommend storing
|
||||||
|
configuration files in the standard UNIX filesystem location, i.e.
|
||||||
|
`/etc/jupyterhub`.
|
||||||
|
|
||||||
### Configure using command line options
|
## Start with a specific config file
|
||||||
|
|
||||||
|
You can load a specific config file and start JupyterHub using:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
jupyterhub -f /path/to/jupyterhub_config.py
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have stored your configuration file in the recommended UNIX filesystem
|
||||||
|
location, `/etc/jupyterhub`, the following command will start JupyterHub using
|
||||||
|
the configuration file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
|
||||||
|
```
|
||||||
|
|
||||||
|
The IPython documentation provides additional information on the
|
||||||
|
[config system](http://ipython.readthedocs.io/en/stable/development/config.html)
|
||||||
|
that Jupyter uses.
|
||||||
|
|
||||||
|
## Configure using command line options
|
||||||
|
|
||||||
To display all command line options that are available for configuration:
|
To display all command line options that are available for configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
jupyterhub --help-all
|
jupyterhub --help-all
|
||||||
|
```
|
||||||
|
|
||||||
Configuration using the command line options is done when launching JupyterHub.
|
Configuration using the command line options is done when launching JupyterHub.
|
||||||
For example, to start JupyterHub on ``10.0.1.2:443`` with **https**, you
|
For example, to start JupyterHub on ``10.0.1.2:443`` with https, you
|
||||||
would enter:
|
would enter:
|
||||||
|
|
||||||
|
```bash
|
||||||
jupyterhub --ip 10.0.1.2 --port 443 --ssl-key my_ssl.key --ssl-cert my_ssl.cert
|
jupyterhub --ip 10.0.1.2 --port 443 --ssl-key my_ssl.key --ssl-cert my_ssl.cert
|
||||||
|
```
|
||||||
|
|
||||||
All configurable options are technically configurable on the command-line,
|
All configurable options may technically be set on the command-line,
|
||||||
even if some are really inconvenient to type. Just replace the desired option,
|
though some are inconvenient to type. To set a particular configuration
|
||||||
`c.Class.trait`, with `--Class.trait`. For example, to configure the
|
parameter, `c.Class.trait`, you would use the command line option,
|
||||||
|
`--Class.trait`, when starting JupyterHub. For example, to configure the
|
||||||
`c.Spawner.notebook_dir` trait from the command-line, use the
|
`c.Spawner.notebook_dir` trait from the command-line, use the
|
||||||
`--Spawner.notebook_dir` option:
|
`--Spawner.notebook_dir` option:
|
||||||
|
|
||||||
@@ -47,23 +74,14 @@ even if some are really inconvenient to type. Just replace the desired option,
|
|||||||
jupyterhub --Spawner.notebook_dir='~/assignments'
|
jupyterhub --Spawner.notebook_dir='~/assignments'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Load a specific config file
|
## Configure for various deployment environments
|
||||||
|
|
||||||
You can load a specific config file with:
|
The default authentication and process spawning mechanisms can be replaced, and
|
||||||
|
specific [authenticators](./authenticators-users-basics.html) and
|
||||||
```bash
|
[spawners](./spawners-basics.html) can be set in the configuration file.
|
||||||
jupyterhub -f /path/to/jupyterhub_config.py
|
This enables JupyterHub to be used with a variety of authentication methods or
|
||||||
```
|
process control and deployment environments. [Some examples](./config-examples.html),
|
||||||
|
meant as illustration, are:
|
||||||
See also: [general docs](http://ipython.org/ipython-doc/dev/development/config.html)
|
|
||||||
on the config system Jupyter uses.
|
|
||||||
|
|
||||||
### Configuration for different deployment environments
|
|
||||||
|
|
||||||
The default authentication and process spawning mechanisms can be replaced,
|
|
||||||
which allows plugging into a variety of authentication methods or process
|
|
||||||
control and deployment environments. Some examples, meant as illustration and
|
|
||||||
testing of this concept, are:
|
|
||||||
|
|
||||||
- Using GitHub OAuth instead of PAM with [OAuthenticator](https://github.com/jupyterhub/oauthenticator)
|
- Using GitHub OAuth instead of PAM with [OAuthenticator](https://github.com/jupyterhub/oauthenticator)
|
||||||
- Spawning single-user servers with Docker, using the [DockerSpawner](https://github.com/jupyterhub/dockerspawner)
|
- Spawning single-user servers with Docker, using the [DockerSpawner](https://github.com/jupyterhub/dockerspawner)
|
||||||
|
@@ -1,30 +1,30 @@
|
|||||||
# Configuration examples
|
# Configuration examples
|
||||||
|
|
||||||
This section provides configuration files and tips for the following
|
This section provides examples, including configuration files and tips, for the
|
||||||
configurations:
|
following configurations:
|
||||||
|
|
||||||
- Example with GitHub OAuth
|
- Using GitHub OAuth
|
||||||
- Example with nginx reverse proxy
|
- Using nginx reverse proxy
|
||||||
- JupyterHub deployment on AWS with NGINX
|
|
||||||
|
|
||||||
|
## Using GitHub OAuth
|
||||||
|
|
||||||
## Example with GitHub OAuth
|
In this example, we show a configuration file for a fairly standard JupyterHub
|
||||||
|
deployment with the following assumptions:
|
||||||
|
|
||||||
In the following example, we show a configuration files for a fairly standard JupyterHub deployment with the following assumptions:
|
* Running JupyterHub on a single cloud server
|
||||||
|
|
||||||
* JupyterHub is running on a single cloud server
|
|
||||||
* Using SSL on the standard HTTPS port 443
|
* Using SSL on the standard HTTPS port 443
|
||||||
* You want to use GitHub OAuth (using oauthenticator) for login
|
* Using GitHub OAuth (using oauthenticator) for login
|
||||||
* You need the users to exist locally on the server
|
* Users exist locally on the server
|
||||||
* You want users' notebooks to be served from `~/assignments` to allow users to browse for notebooks within
|
* Users' notebooks to be served from `~/assignments` to allow users to browse
|
||||||
other users home directories
|
for notebooks within other users' home directories
|
||||||
* You want the landing page for each user to be a Welcome.ipynb notebook in their assignments directory.
|
* You want the landing page for each user to be a `Welcome.ipynb` notebook in
|
||||||
|
their assignments directory.
|
||||||
* All runtime files are put into `/srv/jupyterhub` and log files in `/var/log`.
|
* All runtime files are put into `/srv/jupyterhub` and log files in `/var/log`.
|
||||||
|
|
||||||
Let's start out with `jupyterhub_config.py`:
|
The `jupyterhub_config.py` file would have these settings:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# jupyterhub_config.py
|
# jupyterhub_config.py file
|
||||||
c = get_config()
|
c = get_config()
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -35,7 +35,6 @@ ssl_dir = pjoin(runtime_dir, 'ssl')
|
|||||||
if not os.path.exists(ssl_dir):
|
if not os.path.exists(ssl_dir):
|
||||||
os.makedirs(ssl_dir)
|
os.makedirs(ssl_dir)
|
||||||
|
|
||||||
|
|
||||||
# Allows multiple single-server per user
|
# Allows multiple single-server per user
|
||||||
c.JupyterHub.allow_named_servers = True
|
c.JupyterHub.allow_named_servers = True
|
||||||
|
|
||||||
@@ -54,9 +53,9 @@ c.JupyterHub.db_url = pjoin(runtime_dir, 'jupyterhub.sqlite')
|
|||||||
c.JupyterHub.extra_log_file = '/var/log/jupyterhub.log'
|
c.JupyterHub.extra_log_file = '/var/log/jupyterhub.log'
|
||||||
|
|
||||||
# use GitHub OAuthenticator for local users
|
# use GitHub OAuthenticator for local users
|
||||||
|
|
||||||
c.JupyterHub.authenticator_class = 'oauthenticator.LocalGitHubOAuthenticator'
|
c.JupyterHub.authenticator_class = 'oauthenticator.LocalGitHubOAuthenticator'
|
||||||
c.GitHubOAuthenticator.oauth_callback_url = os.environ['OAUTH_CALLBACK_URL']
|
c.GitHubOAuthenticator.oauth_callback_url = os.environ['OAUTH_CALLBACK_URL']
|
||||||
|
|
||||||
# create system users that don't exist yet
|
# create system users that don't exist yet
|
||||||
c.LocalAuthenticator.create_system_users = True
|
c.LocalAuthenticator.create_system_users = True
|
||||||
|
|
||||||
@@ -72,34 +71,42 @@ c.Spawner.notebook_dir = '~/assignments'
|
|||||||
c.Spawner.args = ['--NotebookApp.default_url=/notebooks/Welcome.ipynb']
|
c.Spawner.args = ['--NotebookApp.default_url=/notebooks/Welcome.ipynb']
|
||||||
```
|
```
|
||||||
|
|
||||||
Using the GitHub Authenticator [requires a few additional env variables][oauth-setup],
|
Using the GitHub Authenticator requires a few additional
|
||||||
which we will need to set when we launch the server:
|
environment variable to be set prior to launching JupyterHub:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export GITHUB_CLIENT_ID=github_id
|
export GITHUB_CLIENT_ID=github_id
|
||||||
export GITHUB_CLIENT_SECRET=github_secret
|
export GITHUB_CLIENT_SECRET=github_secret
|
||||||
export OAUTH_CALLBACK_URL=https://example.com/hub/oauth_callback
|
export OAUTH_CALLBACK_URL=https://example.com/hub/oauth_callback
|
||||||
export CONFIGPROXY_AUTH_TOKEN=super-secret
|
export CONFIGPROXY_AUTH_TOKEN=super-secret
|
||||||
jupyterhub -f /path/to/aboveconfig.py
|
jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example with nginx reverse proxy
|
## Using nginx reverse proxy
|
||||||
|
|
||||||
In the following example, we show configuration files for a JupyterHub server running locally on port `8000` but accessible from the outside on the standard SSL port `443`. This could be useful if the JupyterHub server machine is also hosting other domains or content on `443`. The goal here is to have the following be true:
|
In the following example, we show configuration files for a JupyterHub server
|
||||||
|
running locally on port `8000` but accessible from the outside on the standard
|
||||||
|
SSL port `443`. This could be useful if the JupyterHub server machine is also
|
||||||
|
hosting other domains or content on `443`. The goal in this example is to
|
||||||
|
satisfy the following:
|
||||||
|
|
||||||
* JupyterHub is running on a server, accessed *only* via `HUB.DOMAIN.TLD:443`
|
* JupyterHub is running on a server, accessed *only* via `HUB.DOMAIN.TLD:443`
|
||||||
* On the same machine, `NO_HUB.DOMAIN.TLD` strictly serves different content, also on port `443`
|
* On the same machine, `NO_HUB.DOMAIN.TLD` strictly serves different content,
|
||||||
* `nginx` is used to manage the web servers / reverse proxy (which means that only nginx will be able to bind two servers to `443`)
|
also on port `443`
|
||||||
* After testing, the server in question should be able to score an A+ on the Qualys SSL Labs [SSL Server Test](https://www.ssllabs.com/ssltest/)
|
* `nginx` is used to manage the web servers / reverse proxy (which means that
|
||||||
|
only nginx will be able to bind two servers to `443`)
|
||||||
|
* After testing, the server in question should be able to score an A+ on the
|
||||||
|
Qualys SSL Labs [SSL Server Test](https://www.ssllabs.com/ssltest/)
|
||||||
|
|
||||||
Let's start out with `jupyterhub_config.py`:
|
Let's start out with needed JupyterHub configuration in `jupyterhub_config.py`:
|
||||||
|
|
||||||
```python
|
```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'
|
c.JupyterHub.ip = '127.0.0.1'
|
||||||
```
|
```
|
||||||
|
|
||||||
The `nginx` server config files are fairly standard fare except for the two `location` blocks within the `HUB.DOMAIN.TLD` config file:
|
The **`nginx` server config file** is fairly standard fare except for the two
|
||||||
|
`location` blocks within the `HUB.DOMAIN.TLD` config file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# HTTP server to redirect all 80 traffic to SSL/HTTPS
|
# HTTP server to redirect all 80 traffic to SSL/HTTPS
|
||||||
@@ -162,7 +169,11 @@ server {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`nginx` will now be the front facing element of JupyterHub on `443` which means it is also free to bind other servers, like `NO_HUB.DOMAIN.TLD` to the same port on the same machine and network interface. In fact, one can simply use the same server blocks as above for `NO_HUB` and simply add line for the root directory of the site as well as the applicable location call:
|
`nginx` will now be the front facing element of JupyterHub on `443` which means
|
||||||
|
it is also free to bind other servers, like `NO_HUB.DOMAIN.TLD` to the same port
|
||||||
|
on the same machine and network interface. In fact, one can simply use the same
|
||||||
|
server blocks as above for `NO_HUB` and simply add line for the root directory
|
||||||
|
of the site as well as the applicable location call:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
server {
|
server {
|
||||||
@@ -195,4 +206,6 @@ server {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Now just restart `nginx`, restart the JupyterHub, and enjoy accessing https://HUB.DOMAIN.TLD while serving other content securely on https://NO_HUB.DOMAIN.TLD.
|
Now just restart `nginx`, restart the JupyterHub, and enjoy accessing
|
||||||
|
https://HUB.DOMAIN.TLD while serving other content securely on
|
||||||
|
https://NO_HUB.DOMAIN.TLD.
|
||||||
|
@@ -247,7 +247,19 @@ class Hashed(object):
|
|||||||
def token(self, token):
|
def token(self, token):
|
||||||
"""Store the hashed value and prefix for a token"""
|
"""Store the hashed value and prefix for a token"""
|
||||||
self.prefix = token[:self.prefix_length]
|
self.prefix = token[:self.prefix_length]
|
||||||
self.hashed = hash_token(token, rounds=self.rounds, salt=self.salt_bytes, algorithm=self.algorithm)
|
if len(token) >= 32:
|
||||||
|
# Tokens are generally UUIDs, which have sufficient entropy on their own
|
||||||
|
# and don't need salt & hash rounds.
|
||||||
|
# ref: https://security.stackexchange.com/a/151262/155114
|
||||||
|
rounds = 1
|
||||||
|
salt_bytes = b''
|
||||||
|
else:
|
||||||
|
# users can still specify API tokens in a few ways,
|
||||||
|
# so trigger salt & hash rounds if they provide a short token
|
||||||
|
app_log.warning("Applying salt & hash rounds to %sB token" % len(token))
|
||||||
|
rounds = self.rounds
|
||||||
|
salt_bytes = self.salt_bytes
|
||||||
|
self.hashed = hash_token(token, rounds=rounds, salt=salt_bytes, algorithm=self.algorithm)
|
||||||
|
|
||||||
def match(self, token):
|
def match(self, token):
|
||||||
"""Is this my token?"""
|
"""Is this my token?"""
|
||||||
@@ -394,7 +406,7 @@ class OAuthAccessToken(Hashed, Base):
|
|||||||
|
|
||||||
# from Hashed
|
# from Hashed
|
||||||
hashed = Column(Unicode(64))
|
hashed = Column(Unicode(64))
|
||||||
prefix = Column(Unicode(16))
|
prefix = Column(Unicode(16), index=True)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<{cls}('{prefix}...', user='{user}'>".format(
|
return "<{cls}('{prefix}...', user='{user}'>".format(
|
||||||
|
@@ -373,14 +373,14 @@ class Spawner(LoggingConfigurable):
|
|||||||
|
|
||||||
This can be set independent of any concrete spawner implementation.
|
This can be set independent of any concrete spawner implementation.
|
||||||
|
|
||||||
Example:
|
Example::
|
||||||
|
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
def my_hook(spawner):
|
def my_hook(spawner):
|
||||||
username = spawner.user.name
|
username = spawner.user.name
|
||||||
check_call(['./examples/bootstrap-script/bootstrap.sh', username])
|
check_call(['./examples/bootstrap-script/bootstrap.sh', username])
|
||||||
|
|
||||||
c.Spawner.pre_spawn_hook = my_hook
|
c.Spawner.pre_spawn_hook = my_hook
|
||||||
|
|
||||||
"""
|
"""
|
||||||
).tag(config=True)
|
).tag(config=True)
|
||||||
|
Reference in New Issue
Block a user