Launch the container
I choose this image: jupyter/datascience-notebook.
Its quite large (7.53 GB). But it has many packages pre-installed:
- For python: pandas, matplotlib, scipy, seaborn, scikit-learn, scikit-image, sympy, cython, patsy, statsmodel, cloudpickle, dill, numba, bokeh
- For R: plyr, devtools, shiny, rmarkdown, forecast, rsqlite, reshape2, nycflights13, caret, rcurl, and randomforest
Create a password
Before starting the container, we need to prepare a hashed password. See this doc:
Running a notebook server
I choosed to open my local notebook and run this code:
In [1]: from notebook.auth import passwd
In [2]: passwd()
Enter password:
Verify password:
Out[2]: 'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed'
Run the container
Then run the container with the prepared hashed password.
docker run -d --name jupyter_notebook \
-v {/path/to/folder}:/home/jovyan/work \
-p {port}:8888 \
jupyter/datascience-notebook \
start-notebook.sh --NotebookApp.password='sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed' \
--NotebookApp.base_url=/
Noted: If the {/path/to/folder} is under the root folder, then run chmod 777 /path/to/folder
to allow creating the notebook.
Config the Nginx
Firstly, I thought I just need to proxy the ip and port to the DNS like proxy_pass http://host.of.notebook:port;
.
But, then I found that the notebook is run and the chrome's console shows: failed: Error during WebSocket handshake: Unexpected response code: 400
The solution comes from this two post:
Websocket connection can't be made #412
Unable to establish websocket connection behind nginx reverse proxy #1311
For short, the conf file can be download from this Gist: nginx_reverse_for_notebook
The code is shown here. Just need to change the domain, hostname(ip) and port.
# /etc/nginx/sites-enabled/some.domain
# Change the server name {some.domain}
# Change the {host.of.notebook} and {port} in the following locations
server {
listen 80;
# Change the server name {some.domain}
server_name some.domain;
location / {
# Change the {host.of.notebook} and {port}
proxy_pass http://host.of.notebook:port;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
client_max_body_size 50M;
error_log /var/log/nginx/error.log;
location ~* /(api/kernels/[^/]+/(channels|iopub|shell|stdin)|terminals/websocket)/? {
# Change the {host.of.notebook} and {port}
proxy_pass http://host.of.notebook:port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
#proxy_set_header Upgrade $http_upgrade;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}
- Since the cloudflare has already allow websocket, so there is not need to turn off the cloud. The SSL is also working.