提交 d1f97b27 创建 作者: 宋海霞's avatar 宋海霞

上传新文件

上级 a27a76f9
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Install JupyterHub and JupyterLab from the ground up — JupyterHub 1.3.0 documentation</title>
<link rel="stylesheet" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/index.css">
<link rel="stylesheet" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/all.css">
<link rel="preload" as="font" type="font/woff2" crossorigin="" href="https://jupyterhub.readthedocs.io/en/stable/_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin="" href="https://jupyterhub.readthedocs.io/en/stable/_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/index_003.css">
<link rel="stylesheet" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/index_002.css">
<link rel="stylesheet" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/basic.css" type="text/css">
<link rel="stylesheet" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/pygments.css" type="text/css">
<link rel="stylesheet" type="text/css" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copybutton.css">
<link rel="stylesheet" type="text/css" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/custom.css">
<link rel="stylesheet" type="text/css" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/badge_only.css">
<link rel="preload" as="script" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/index.js">
<script type="text/javascript" id="documentation_options" data-url_root="./" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/documentation_options.js"></script>
<script type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/jquery.js"></script>
<script type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/underscore.js"></script>
<script type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/doctools.js"></script>
<script type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/language_data.js"></script>
<script type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/clipboard.js"></script>
<script type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copybutton.js"></script>
<script async="async" type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/readthedocs-doc-embed.js"></script>
<link rel="shortcut icon" href="https://jupyterhub.readthedocs.io/en/stable/_static/favicon.ico">
<link rel="index" title="Index" href="https://jupyterhub.readthedocs.io/en/stable/genindex.html">
<link rel="search" title="Search" href="https://jupyterhub.readthedocs.io/en/stable/search.html">
<link rel="next" title="Get Started" href="https://jupyterhub.readthedocs.io/en/stable/getting-started/index.html">
<link rel="prev" title="Installation Basics" href="https://jupyterhub.readthedocs.io/en/stable/installation-basics.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="docsearch:language" content="en">
<!-- RTD Extra Head -->
<!--
Always link to the latest version, as canonical.
http://docs.readthedocs.org/en/latest/canonical.html
-->
<link rel="canonical" href="https://jupyterhub.readthedocs.io/en/stable/installation-guide-hard.html">
<link rel="stylesheet" href="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/readthedocs-doc-embed.css" type="text/css">
<script type="application/json" id="READTHEDOCS_DATA">{"ad_free": false, "api_host": "https://readthedocs.org", "build_date": "2020-12-11T11:11:56Z", "builder": "sphinx", "canonical_url": "https://jupyterhub.readthedocs.io/en/stable/", "commit": "a9119763", "docroot": "/docs/source/", "features": {"docsearch_disabled": false}, "global_analytics_code": "UA-17997319-1", "language": "en", "page": "installation-guide-hard", "programming_language": "py", "project": "jupyterhub", "proxied_api_host": "/_", "source_suffix": ".md", "subprojects": {}, "theme": "pydata_sphinx_theme", "user_analytics_code": "", "version": "stable"}</script>
<!--
Using this variable directly instead of using `JSON.parse` is deprecated.
The READTHEDOCS_DATA global variable will be removed in the future.
-->
<script type="text/javascript">
READTHEDOCS_DATA = JSON.parse(document.getElementById('READTHEDOCS_DATA').innerHTML);
</script>
<script type="text/javascript" src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/readthedocs-analytics.js" async="async"></script>
<!-- end RTD <extrahead> -->
<script src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/js" type="text/javascript" async=""></script><script src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/ethicalads.js" type="text/javascript" async="" id="ethicaladsjs"></script><style>[data-ea-publisher].loaded,[data-ea-type].loaded{font-size:14px;font-family:-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;font-weight:normal;font-style:normal;leter-spacing:0px;vertical-align:baseline;line-height:1.3em}[data-ea-publisher].loaded a,[data-ea-type].loaded a{text-decoration:none}[data-ea-publisher].loaded .ea-pixel,[data-ea-type].loaded .ea-pixel{display:none}[data-ea-publisher].loaded .ea-content,[data-ea-type].loaded .ea-content{margin:1em 1em 0.5em 1em;padding:1em;background:rgba(0,0,0,0.03);color:#505050}[data-ea-publisher].loaded .ea-content a:link,[data-ea-type].loaded .ea-content a:link{color:#505050}[data-ea-publisher].loaded .ea-content a:visited,[data-ea-type].loaded .ea-content a:visited{color:#505050}[data-ea-publisher].loaded .ea-content a:hover,[data-ea-type].loaded .ea-content a:hover{color:#373737}[data-ea-publisher].loaded .ea-content a:active,[data-ea-type].loaded .ea-content a:active{color:#373737}[data-ea-publisher].loaded .ea-content a strong,[data-ea-publisher].loaded .ea-content a b,[data-ea-type].loaded .ea-content a strong,[data-ea-type].loaded .ea-content a b{color:#088cdb}[data-ea-publisher].loaded .ea-callout a:link,[data-ea-type].loaded .ea-callout a:link{color:#6a6a6a}[data-ea-publisher].loaded .ea-callout a:visited,[data-ea-type].loaded .ea-callout a:visited{color:#6a6a6a}[data-ea-publisher].loaded .ea-callout a:hover,[data-ea-type].loaded .ea-callout a:hover{color:#505050}[data-ea-publisher].loaded .ea-callout a:active,[data-ea-type].loaded .ea-callout a:active{color:#505050}[data-ea-publisher].loaded .ea-callout a strong,[data-ea-publisher].loaded .ea-callout a b,[data-ea-type].loaded .ea-callout a strong,[data-ea-type].loaded .ea-callout a b{color:#088cdb}[data-ea-publisher].loaded .ea-callout a,[data-ea-type].loaded .ea-callout a{font-size:0.8em}[data-ea-publisher].loaded.dark .ea-content,[data-ea-type].loaded.dark .ea-content{background:rgba(255,255,255,0.05);color:#dcdcdc}[data-ea-publisher].loaded.dark .ea-content a:link,[data-ea-type].loaded.dark .ea-content a:link{color:#dcdcdc}[data-ea-publisher].loaded.dark .ea-content a:visited,[data-ea-type].loaded.dark .ea-content a:visited{color:#dcdcdc}[data-ea-publisher].loaded.dark .ea-content a:hover,[data-ea-type].loaded.dark .ea-content a:hover{color:#f6f6f6}[data-ea-publisher].loaded.dark .ea-content a:active,[data-ea-type].loaded.dark .ea-content a:active{color:#f6f6f6}[data-ea-publisher].loaded.dark .ea-content a strong,[data-ea-publisher].loaded.dark .ea-content a b,[data-ea-type].loaded.dark .ea-content a strong,[data-ea-type].loaded.dark .ea-content a b{color:#50baf9}[data-ea-publisher].loaded.dark .ea-callout a:link,[data-ea-type].loaded.dark .ea-callout a:link{color:#c3c3c3}[data-ea-publisher].loaded.dark .ea-callout a:visited,[data-ea-type].loaded.dark .ea-callout a:visited{color:#c3c3c3}[data-ea-publisher].loaded.dark .ea-callout a:hover,[data-ea-type].loaded.dark .ea-callout a:hover{color:#dcdcdc}[data-ea-publisher].loaded.dark .ea-callout a:active,[data-ea-type].loaded.dark .ea-callout a:active{color:#dcdcdc}[data-ea-publisher].loaded.dark .ea-callout a strong,[data-ea-publisher].loaded.dark .ea-callout a b,[data-ea-type].loaded.dark .ea-callout a strong,[data-ea-type].loaded.dark .ea-callout a b{color:#50baf9}[data-ea-publisher].loaded .ea-content,[data-ea-type].loaded .ea-content{border:0px;border-radius:3px;box-shadow:0px 2px 3px rgba(0,0,0,0.15)}[data-ea-publisher].loaded.raised .ea-content,[data-ea-type].loaded.raised .ea-content{border:0px;border-radius:3px;box-shadow:0px 2px 3px rgba(0,0,0,0.15)}[data-ea-publisher].loaded.bordered .ea-content,[data-ea-type].loaded.bordered .ea-content{border:1px solid rgba(0,0,0,0.04);border-radius:3px;box-shadow:none}[data-ea-publisher].loaded.bordered.dark .ea-content,[data-ea-type].loaded.bordered.dark .ea-content{border:1px solid rgba(255,255,255,0.07)}[data-ea-publisher].loaded.flat .ea-content,[data-ea-type].loaded.flat .ea-content{border:0px;border-radius:3px;box-shadow:none}[data-ea-type="image"].loaded,[data-ea-publisher]:not([data-ea-type]).loaded,.ea-type-image{display:inline-block}[data-ea-type="image"].loaded .ea-content,[data-ea-publisher]:not([data-ea-type]).loaded .ea-content,.ea-type-image .ea-content{max-width:180px;overflow:auto;text-align:center}[data-ea-type="image"].loaded .ea-content>a>img,[data-ea-publisher]:not([data-ea-type]).loaded .ea-content>a>img,.ea-type-image .ea-content>a>img{width:120px;height:90px;display:inline-block}[data-ea-type="image"].loaded .ea-content>.ea-text,[data-ea-publisher]:not([data-ea-type]).loaded .ea-content>.ea-text,.ea-type-image .ea-content>.ea-text{margin-top:1em;font-size:1em;text-align:center}[data-ea-type="image"].loaded .ea-callout,[data-ea-publisher]:not([data-ea-type]).loaded .ea-callout,.ea-type-image .ea-callout{max-width:180px;margin:0em 1em 1em 1em;padding-left:1em;padding-right:1em;font-style:italic;text-align:right}[data-ea-type="image"].loaded.horizontal .ea-content,[data-ea-publisher]:not([data-ea-type]).loaded.horizontal .ea-content,.ea-type-image.horizontal .ea-content{max-width:320px}[data-ea-type="image"].loaded.horizontal .ea-content>a>img,[data-ea-publisher]:not([data-ea-type]).loaded.horizontal .ea-content>a>img,.ea-type-image.horizontal .ea-content>a>img{float:left;margin-right:1em}[data-ea-type="image"].loaded.horizontal .ea-content .ea-text,[data-ea-publisher]:not([data-ea-type]).loaded.horizontal .ea-content .ea-text,.ea-type-image.horizontal .ea-content .ea-text{margin-top:0em;text-align:left;overflow:auto}[data-ea-type="image"].loaded.horizontal .ea-callout,[data-ea-publisher]:not([data-ea-type]).loaded.horizontal .ea-callout,.ea-type-image.horizontal .ea-callout{max-width:320px;text-align:right}[data-ea-type="text"].loaded,.ea-type-text{font-size:14px}[data-ea-type="text"].loaded .ea-content,.ea-type-text .ea-content{text-align:left}[data-ea-type="text"].loaded .ea-callout,.ea-type-text .ea-callout{margin:0.5em 1em 1em 1em;padding-left:1em;padding-right:1em;text-align:right;font-style:italic}
</style></head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<nav class="navbar navbar-light navbar-expand-lg bg-light fixed-top bd-navbar" id="navbar-main">
<div class="container-xl">
<a class="navbar-brand" href="https://jupyterhub.readthedocs.io/en/stable/index.html">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/logo.png" class="logo" alt="logo">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-menu" aria-controls="navbar-menu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar-menu" class="col-lg-9 collapse navbar-collapse">
<ul id="navbar-main-elements" class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="https://jupyterhub.readthedocs.io/en/stable/installation-guide.html">Installation</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="https://jupyterhub.readthedocs.io/en/stable/getting-started/index.html">Get Started</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="https://jupyterhub.readthedocs.io/en/stable/reference/index.html">Technical Reference</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="https://jupyterhub.readthedocs.io/en/stable/index-admin.html">Administrator’s Guide</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="https://jupyterhub.readthedocs.io/en/stable/api/index.html">JupyterHub API</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="https://jupyterhub.readthedocs.io/en/stable/contributing/index.html">Contributing</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="https://jupyterhub.readthedocs.io/en/stable/index-about.html">About</a>
</li>
</ul>
<ul class="navbar-nav">
</ul>
</div>
</div>
</nav>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar"><form class="bd-search d-flex align-items-center" action="search.html" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off">
</form>
<nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<ul class="nav bd-sidenav">
<li class="">
<a href="https://jupyterhub.readthedocs.io/en/stable/quickstart.html">Quickstart</a>
</li>
<li class="">
<a href="https://jupyterhub.readthedocs.io/en/stable/quickstart-docker.html">Using Docker</a>
</li>
<li class="">
<a href="https://jupyterhub.readthedocs.io/en/stable/installation-basics.html">Installation Basics</a>
</li>
<li class="active">
<a href="">Install JupyterHub and JupyterLab from the ground up</a>
</li>
</ul>
</div></nav>
</div>
<div class="d-none d-xl-block col-xl-2 bd-toc">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> On this page
</div>
<nav id="bd-toc-nav">
<ul class="nav section-nav flex-column">
<li class="nav-item toc-entry toc-h2">
<a href="#prerequisites" class="nav-link">Prerequisites</a>
</li>
<li class="nav-item toc-entry toc-h2">
<a href="#goals" class="nav-link">Goals</a>
</li>
<li class="nav-item toc-entry toc-h2">
<a href="#part-1-jupyterhub-and-jupyterlab" class="nav-link">Part 1: JupyterHub and JupyterLab</a><ul class="nav section-nav flex-column">
<li class="nav-item toc-entry toc-h3">
<a href="#setup-the-jupyterhub-and-jupyterlab-in-a-virtual-environment" class="nav-link">Setup the JupyterHub and JupyterLab in a virtual environment</a>
</li>
<li class="nav-item toc-entry toc-h3">
<a href="#create-the-configuration-for-jupyterhub" class="nav-link">Create the configuration for JupyterHub</a>
</li>
<li class="nav-item toc-entry toc-h3">
<a href="#setup-systemd-service" class="nav-link">Setup Systemd service</a>
</li>
</ul>
</li>
<li class="nav-item toc-entry toc-h2">
<a href="#part-2-conda-environments" class="nav-link">Part 2: Conda environments</a><ul class="nav section-nav flex-column">
<li class="nav-item toc-entry toc-h3">
<a href="#install-conda-for-the-whole-system" class="nav-link">Install conda for the whole system</a>
</li>
<li class="nav-item toc-entry toc-h3">
<a href="#install-a-default-conda-environment-for-all-users" class="nav-link">Install a default conda environment for all users</a>
</li>
<li class="nav-item toc-entry toc-h3">
<a href="#setting-up-users-own-conda-environments" class="nav-link">Setting up users’ own conda environments</a>
</li>
</ul>
</li>
<li class="nav-item toc-entry toc-h2">
<a href="#setting-up-a-reverse-proxy" class="nav-link">Setting up a reverse proxy</a><ul class="nav section-nav flex-column">
<li class="nav-item toc-entry toc-h3">
<a href="#using-nginx" class="nav-link">Using Nginx</a>
</li>
</ul>
</li>
<li class="nav-item toc-entry toc-h2 active">
<a href="#getting-started-using-your-new-jupyterhub" class="nav-link active">Getting started using your new JupyterHub</a>
</li>
</ul>
</nav>
</div>
<main class="col-12 col-md-9 col-xl-7 py-md-5 pl-md-5 pr-md-4 bd-content" role="main">
<div>
<div class="section" id="install-jupyterhub-and-jupyterlab-from-the-ground-up">
<h1>Install JupyterHub and JupyterLab from the ground up<a class="headerlink" href="#install-jupyterhub-and-jupyterlab-from-the-ground-up" title="Permalink to this headline"></a></h1>
<p>The combination of <a class="reference external" href="https://jupyterhub.readthedocs.io/">JupyterHub</a> and <a class="reference external" href="https://jupyterlab.readthedocs.io/">JupyterLab</a>
is a great way to make shared computing resources available to a group.</p>
<p>These instructions are a guide for a manual, ‘bare metal’ install of <a class="reference external" href="https://jupyterhub.readthedocs.io/">JupyterHub</a>
and <a class="reference external" href="https://jupyterlab.readthedocs.io/">JupyterLab</a>. This is ideal for running on a single server: build a beast
of a machine and share it within your lab, or use a virtual machine from any VPS or cloud provider.</p>
<p>This guide has similar goals to <a class="reference external" href="https://the-littlest-jupyterhub.readthedocs.io/">The Littlest JupyterHub</a> setup
script. However, instead of bundling all these step for you into one installer, we will perform every step manually.
This makes it easy to customize any part (e.g. if you want to run other services on the same system and need to make them
work together), as well as giving you full control and understanding of your setup.</p>
<div class="section" id="prerequisites">
<h2>Prerequisites<a class="headerlink" href="#prerequisites" title="Permalink to this headline"></a></h2>
<p>Your own server with administrator (root) access. This could be a local machine, a remotely hosted one, or a cloud instance
or VPS. Each user who will access JupyterHub should have a standard user account on the machine. The install will be done
through the command line - useful if you log into your machine remotely using SSH.</p>
<p>This tutorial was tested on <strong>Ubuntu 18.04</strong>. No other Linux distributions have been tested, but the instructions
should be reasonably straightforward to adapt.</p>
</div>
<div class="section" id="goals">
<h2>Goals<a class="headerlink" href="#goals" title="Permalink to this headline"></a></h2>
<p>JupyterLab enables access to a multiple ‘kernels’, each one being a given environment for a given language. The most
common is a Python environment, for scientific computing usually one managed by the <code class="docutils literal notranslate"><span class="pre">conda</span></code> package manager.</p>
<p>This guide will set up JupyterHub and JupyterLab seperately from the Python environment. In other words, we treat
JupyterHub+JupyterLab as a ‘app’ or webservice, which will connect to the kernels available on the system. Specifically:</p>
<ul class="simple">
<li><p>We will create an installation of JupyterHub and JupyterLab using a virtualenv under <code class="docutils literal notranslate"><span class="pre">/opt</span></code> using the system Python.</p></li>
<li><p>We will install conda globally.</p></li>
<li><p>We will create a shared conda environment which can be used (but not modified) by all users.</p></li>
<li><p>We will show how users can create their own private conda environments, where they can install whatever they like.</p></li>
</ul>
<p>The default JupyterHub Authenticator uses PAM to authenticate system users with their username and password. One can
<a class="reference external" href="https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html#authenticators">choose the authenticator</a>
that best suits their needs. In this guide we will use the default
Authenticator because it makes it easy for everyone to manage data
in their home folder and to mix and match different services and access
methods (e.g. SSH) which all work using the
Linux system user accounts. Therefore, each user of JupyterHub will need
a standard system user account.</p>
<p>Another goal of this guide is to use system provided packages wherever possible. This has the advantage that these packages
get automatic patches and security updates (be sure to turn on automatic updates in Ubuntu). This means less maintenance
work and a more reliable system.</p>
</div>
<div class="section" id="part-1-jupyterhub-and-jupyterlab">
<h2>Part 1: JupyterHub and JupyterLab<a class="headerlink" href="#part-1-jupyterhub-and-jupyterlab" title="Permalink to this headline"></a></h2>
<div class="section" id="setup-the-jupyterhub-and-jupyterlab-in-a-virtual-environment">
<h3>Setup the JupyterHub and JupyterLab in a virtual environment<a class="headerlink" href="#setup-the-jupyterhub-and-jupyterlab-in-a-virtual-environment" title="Permalink to this headline"></a></h3>
<p>First we create a virtual environment under ‘/opt/jupyterhub’. The ‘/opt’ folder is where apps not belonging to the operating
system are <a class="reference external" href="https://unix.stackexchange.com/questions/11544/what-is-the-difference-between-opt-and-usr-local">commonly installed</a>.
Both jupyterlab and jupyterhub will be installed into this virtualenv. Create it with the command:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell0"><span></span>sudo python3 -m venv /opt/jupyterhub/
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell0">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Now we use pip to install the required Python packages into the new virtual environment. Be sure to install
<code class="docutils literal notranslate"><span class="pre">wheel</span></code> first. Since we are separating the user interface from the computing kernels, we don’t install
any Python scientific packages here. The only exception is <code class="docutils literal notranslate"><span class="pre">ipywidgets</span></code> because this is needed to allow connection
between interactive tools running in the kernel and the user interface.</p>
<p>Note that we use <code class="docutils literal notranslate"><span class="pre">/opt/jupyterhub/bin/python3</span> <span class="pre">-m</span> <span class="pre">pip</span> <span class="pre">install</span></code> each time - this <a class="reference external" href="https://snarky.ca/why-you-should-use-python-m-pip/">makes sure</a>
that the packages are installed to the correct virtual environment.</p>
<p>Perform the install using the following commands:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell1"><span></span>sudo /opt/jupyterhub/bin/python3 -m pip install wheel
sudo /opt/jupyterhub/bin/python3 -m pip install jupyterhub jupyterlab
sudo /opt/jupyterhub/bin/python3 -m pip install ipywidgets
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell1">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>JupyterHub also currently defaults to requiring <code class="docutils literal notranslate"><span class="pre">configurable-http-proxy</span></code>, which needs <code class="docutils literal notranslate"><span class="pre">nodejs</span></code> and <code class="docutils literal notranslate"><span class="pre">npm</span></code>. The versions
of these available in Ubuntu therefore need to be installed first (they are a bit old but this is ok for our needs):</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell2"><span></span>sudo apt install nodejs npm
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell2">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Then install <code class="docutils literal notranslate"><span class="pre">configurable-http-proxy</span></code>:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell3"><span></span>sudo npm install -g configurable-http-proxy
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell3">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
</div>
<div class="section" id="create-the-configuration-for-jupyterhub">
<h3>Create the configuration for JupyterHub<a class="headerlink" href="#create-the-configuration-for-jupyterhub" title="Permalink to this headline"></a></h3>
<p>Now we start creating configuration files. To keep everything together, we put all the configuration into the folder
created for the virtualenv, under <code class="docutils literal notranslate"><span class="pre">/opt/jupyterhub/etc/</span></code>. For each thing needing configuration, we will create a further
subfolder and necessary files.</p>
<p>First create the folder for the JupyterHub configuration and navigate to it:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell4"><span></span>sudo mkdir -p /opt/jupyterhub/etc/jupyterhub/
<span class="nb">cd</span> /opt/jupyterhub/etc/jupyterhub/
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell4">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Then generate the default configuration file</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell5"><span></span>sudo /opt/jupyterhub/bin/jupyterhub --generate-config
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell5">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>This will produce the default configuration file <code class="docutils literal notranslate"><span class="pre">/opt/jupyterhub/etc/jupyterhub/jupyterhub_config.py</span></code></p>
<p>You will need to edit the configuration file to make the JupyterLab interface by the default.
Set the following configuration option in your <code class="docutils literal notranslate"><span class="pre">jupyterhub_config.py</span></code> file:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre id="codecell6"><span></span><span class="n">c</span><span class="o">.</span><span class="n">Spawner</span><span class="o">.</span><span class="n">default_url</span> <span class="o">=</span> <span class="s1">'/lab'</span>
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell6">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Further configuration options may be found in the documentation.</p>
</div>
<div class="section" id="setup-systemd-service">
<h3>Setup Systemd service<a class="headerlink" href="#setup-systemd-service" title="Permalink to this headline"></a></h3>
<p>We will setup JupyterHub to run as a system service using Systemd (which is responsible for managing all services and
servers that run on startup in Ubuntu). We will create a service file in a suitable location in the virtualenv folder
and then link it to the system services. First create the folder for the service file:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell7"><span></span>sudo mkdir -p /opt/jupyterhub/etc/systemd
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell7">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Then create the following text file using your <a class="reference external" href="https://micro-editor.github.io/">favourite editor</a> at</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell8"><span></span>/opt/jupyterhub/etc/systemd/jupyterhub.service
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell8">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Paste the following service unit definition into the file:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre id="codecell9"><span></span><span class="p">[</span><span class="n">Unit</span><span class="p">]</span>
<span class="n">Description</span><span class="o">=</span><span class="n">JupyterHub</span>
<span class="n">After</span><span class="o">=</span><span class="n">syslog</span><span class="o">.</span><span class="n">target</span> <span class="n">network</span><span class="o">.</span><span class="n">target</span>
<span class="p">[</span><span class="n">Service</span><span class="p">]</span>
<span class="n">User</span><span class="o">=</span><span class="n">root</span>
<span class="n">Environment</span><span class="o">=</span><span class="s2">"PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/jupyterhub/bin"</span>
<span class="n">ExecStart</span><span class="o">=/</span><span class="n">opt</span><span class="o">/</span><span class="n">jupyterhub</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">jupyterhub</span> <span class="o">-</span><span class="n">f</span> <span class="o">/</span><span class="n">opt</span><span class="o">/</span><span class="n">jupyterhub</span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">jupyterhub</span><span class="o">/</span><span class="n">jupyterhub_config</span><span class="o">.</span><span class="n">py</span>
<span class="p">[</span><span class="n">Install</span><span class="p">]</span>
<span class="n">WantedBy</span><span class="o">=</span><span class="n">multi</span><span class="o">-</span><span class="n">user</span><span class="o">.</span><span class="n">target</span>
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell9">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>This sets up the environment to use the virtual environment we created, tells Systemd how to start jupyterhub using
the configuration file we created, specifies that jupyterhub will be started as the <code class="docutils literal notranslate"><span class="pre">root</span></code> user (needed so that it can
start jupyter on behalf of other logged in users), and specifies that jupyterhub should start on boot after the network
is enabled.</p>
<p>Finally, we need to make systemd aware of our service file. First we symlink our file into systemd’s directory:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell10"><span></span>sudo ln -s /opt/jupyterhub/etc/systemd/jupyterhub.service /etc/systemd/system/jupyterhub.service
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell10">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Then tell systemd to reload its configuration files</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell11"><span></span>sudo systemctl daemon-reload
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell11">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>And finally enable the service</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell12"><span></span>sudo systemctl <span class="nb">enable</span> jupyterhub.service
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell12">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>The service will start on reboot, but we can start it straight away using:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell13"><span></span>sudo systemctl start jupyterhub.service
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell13">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>…and check that it’s running using:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell14"><span></span>sudo systemctl status jupyterhub.service
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell14">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>You should now be already be able to access jupyterhub using <code class="docutils literal notranslate"><span class="pre">&lt;your</span> <span class="pre">servers</span> <span class="pre">ip&gt;:8000</span></code> (assuming you haven’t already set
up a firewall or something). However, when you log in the jupyter notebooks will be trying to use the Python virtualenv
that was created to install JupyterHub, this is not what we want. So on to part 2</p>
</div>
</div>
<div class="section" id="part-2-conda-environments">
<h2>Part 2: Conda environments<a class="headerlink" href="#part-2-conda-environments" title="Permalink to this headline"></a></h2>
<div class="section" id="install-conda-for-the-whole-system">
<h3>Install conda for the whole system<a class="headerlink" href="#install-conda-for-the-whole-system" title="Permalink to this headline"></a></h3>
<p>We will use <code class="docutils literal notranslate"><span class="pre">conda</span></code> to manage Python environments. We will install the officially maintained <code class="docutils literal notranslate"><span class="pre">conda</span></code> packages for Ubuntu,
this means they will get automatic updates with the rest of the system. Setup repo for the official Conda debian packages,
instructions are copied from <a class="reference external" href="https://docs.conda.io/projects/conda/en/latest/user-guide/install/rpm-debian.html">here</a>:</p>
<p>Install Anacononda public gpg key to trusted store</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell15"><span></span>curl https://repo.anaconda.com/pkgs/misc/gpgkeys/anaconda.asc <span class="p">|</span> gpg --dearmor &gt; conda.gpg
sudo install -o root -g root -m <span class="m">644</span> conda.gpg /etc/apt/trusted.gpg.d/
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell15">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Add Debian repo</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell16"><span></span><span class="nb">echo</span> <span class="s2">"deb [arch=amd64] https://repo.anaconda.com/pkgs/misc/debrepo/conda stable main"</span> <span class="p">|</span> sudo tee /etc/apt/sources.list.d/conda.list
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell16">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Install conda</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell17"><span></span>sudo apt update
sudo apt install conda
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell17">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>This will install conda into the folder <code class="docutils literal notranslate"><span class="pre">/opt/conda/</span></code>, with the conda command available at <code class="docutils literal notranslate"><span class="pre">/opt/conda/bin/conda</span></code>.</p>
<p>Finally, we can make conda more easily available to users by symlinking the conda shell setup script to the profile
‘drop in’ folder so that it gets run on login</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell18"><span></span>sudo ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell18">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
</div>
<div class="section" id="install-a-default-conda-environment-for-all-users">
<h3>Install a default conda environment for all users<a class="headerlink" href="#install-a-default-conda-environment-for-all-users" title="Permalink to this headline"></a></h3>
<p>First create a folder for conda envs (might exist already):</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell19"><span></span>sudo mkdir /opt/conda/envs/
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell19">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Then create a conda environment to your liking within that folder.
Here we have called it ‘python’ because it will
be the obvious default - call it whatever you like. You can install
whatever you like into this environment, but you MUST at least install <code class="docutils literal notranslate"><span class="pre">ipykernel</span></code>.</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell20"><span></span>sudo /opt/conda/bin/conda create --prefix /opt/conda/envs/python <span class="nv">python</span><span class="o">=</span><span class="m">3</span>.7 ipykernel
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell20">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Once your env is set up as desired, make it visible to Jupyter by installing the kernel spec. There are two options here:</p>
<p>1 ) Install into the JupyterHub virtualenv - this ensures it
overrides the default python version. It will only be visible
to the JupyterHub installation we have just created. This is useful to
avoid conda environments appearing where they are not expected.</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell21"><span></span>sudo /opt/conda/envs/python/bin/python -m ipykernel install --prefix<span class="o">=</span>/opt/jupyterhub/ --name <span class="s1">'python'</span> --display-name <span class="s2">"Python (default)"</span>
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell21">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>2 ) Install it system-wide by putting it into <code class="docutils literal notranslate"><span class="pre">/usr/local</span></code>. It will be visible to any parallel install of JupyterHub or
JupyterLab, and will persist even if you later delete or modify the JupyterHub installation. This is useful if the kernels
might be used by other services, or if you want to modify the JupyterHub installation independently from the conda environments.</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell22"><span></span>sudo /opt/conda/envs/python/bin/python -m ipykernel install --prefix /usr/local/ --name <span class="s1">'python'</span> --display-name <span class="s2">"Python (default)"</span>
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell22">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
</div>
<div class="section" id="setting-up-users-own-conda-environments">
<h3>Setting up users’ own conda environments<a class="headerlink" href="#setting-up-users-own-conda-environments" title="Permalink to this headline"></a></h3>
<p>There is relatively little for the administrator to do here, as users
will have to set up their own environments using the shell.
On login they should run <code class="docutils literal notranslate"><span class="pre">conda</span> <span class="pre">init</span></code> or <code class="docutils literal notranslate"><span class="pre">/opt/conda/bin/conda</span></code>. The can then use conda to set up their environment,
although they must also install <code class="docutils literal notranslate"><span class="pre">ipykernel</span></code>. Once done, they can enable their kernel using:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell23"><span></span>/path/to/kernel/env/bin/python -m ipykernel install --name <span class="s1">'python-my-env'</span> --display-name <span class="s2">"Python My Env"</span>
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell23">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>This will place the kernel spec into their home folder, where Jupyter will look for it on startup.</p>
</div>
</div>
<div class="section" id="setting-up-a-reverse-proxy">
<h2>Setting up a reverse proxy<a class="headerlink" href="#setting-up-a-reverse-proxy" title="Permalink to this headline"></a></h2>
<p>The guide so far results in JupyterHub running on port 8000. It is not generally advisable to run open web services in
this way - instead, use a reverse proxy running on standard HTTP/HTTPS ports.</p>
<blockquote>
<div><p><strong>Important</strong>: Be aware of the security implications especially if you are running a server that is accessible from the open internet
i.e. not protected within an institutional intranet or private home/office network. You should set up a firewall and
HTTPS encryption, which is outside of the scope of this guide. For HTTPS consider using <a class="reference external" href="https://letsencrypt.org/">LetsEncrypt</a>
or setting up a <a class="reference external" href="https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-18-04">self-signed certificate</a>.
Firewalls may be set up using <code class="docutils literal notranslate"><span class="pre">ufw</span></code> or <code class="docutils literal notranslate"><span class="pre">firewalld</span></code> and combined with <code class="docutils literal notranslate"><span class="pre">fail2ban</span></code>.</p>
</div></blockquote>
<div class="section" id="using-nginx">
<h3>Using Nginx<a class="headerlink" href="#using-nginx" title="Permalink to this headline"></a></h3>
<p>Nginx is a mature and established web server and reverse proxy and is easy to install using <code class="docutils literal notranslate"><span class="pre">sudo</span> <span class="pre">apt</span> <span class="pre">install</span> <span class="pre">nginx</span></code>.
Details on using Nginx as a reverse proxy can be found elsewhere. Here, we will only outline the additional steps needed
to setup JupyterHub with Nginx and host it at a given URL e.g. <code class="docutils literal notranslate"><span class="pre">&lt;your-server-ip-or-url&gt;/jupyter</span></code>.
This could be useful for example if you are running several services or web pages on the same server.</p>
<p>To achieve this needs a few tweaks to both the JupyterHub configuration and the Nginx config. First, edit the
configuration file <code class="docutils literal notranslate"><span class="pre">/opt/jupyterhub/etc/jupyterhub/jupyterhub_config.py</span></code> and add the line:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre id="codecell24"><span></span><span class="n">c</span><span class="o">.</span><span class="n">JupyterHub</span><span class="o">.</span><span class="n">bind_url</span> <span class="o">=</span> <span class="s1">'http://:8000/jupyter'</span>
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell24">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>where <code class="docutils literal notranslate"><span class="pre">/jupyter</span></code> will be the relative URL of the JupyterHub.</p>
<p>Now Nginx must be configured with a to pass all traffic from <code class="docutils literal notranslate"><span class="pre">/jupyter</span></code> to the the local address <code class="docutils literal notranslate"><span class="pre">127.0.0.1:8000</span></code>.
Add the following snippet to your nginx configuration file (e.g. <code class="docutils literal notranslate"><span class="pre">/etc/nginx/sites-available/default</span></code>).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre id="codecell25"><span></span> location /jupyter/ {
# NOTE important to also set base url of jupyterhub to /jupyter in its config
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
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_set_header X-Forwarded-Proto $scheme;
# websocket headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell25">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Also add this snippet before the <em>server</em> block:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre id="codecell26"><span></span>map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell26">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>Nginx will not run if there are errors in the configuration, check your configuration using:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell27"><span></span>nginx -t
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell27">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
<p>If there are no errors, you can restart the Nginx service for the new configuration to take effect.</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre id="codecell28"><span></span>sudo systemctl restart nginx.service
</pre><a class="copybtn o-tooltip--left" style="background-color: rgb(250, 250, 250)" data-tooltip="Copy" data-clipboard-target="#codecell28">
<img src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/copy-button.svg" alt="Copy to clipboard">
</a></div>
</div>
</div>
</div>
<div class="section" id="getting-started-using-your-new-jupyterhub">
<h2>Getting started using your new JupyterHub<a class="headerlink" href="#getting-started-using-your-new-jupyterhub" title="Permalink to this headline"></a></h2>
<p>Once you have setup JupyterHub and Nginx proxy as described, you can browse to your JupyterHub IP or URL
(e.g. if your server IP address is <code class="docutils literal notranslate"><span class="pre">123.456.789.1</span></code> and you decided to host JupyterHub at the <code class="docutils literal notranslate"><span class="pre">/jupyter</span></code> URL, browse
to <code class="docutils literal notranslate"><span class="pre">123.456.789.1/jupyter</span></code>). You will find a login page where you enter your Linux username and password. On login
you will be presented with the JupyterLab interface, with the file browser pane showing the contents of your users’
home directory on the server.</p>
</div>
</div>
</div>
<div class="prev-next-bottom">
<a class="left-prev" id="prev-link" href="https://jupyterhub.readthedocs.io/en/stable/installation-basics.html" title="previous page">Installation Basics</a>
<a class="right-next" id="next-link" href="https://jupyterhub.readthedocs.io/en/stable/getting-started/index.html" title="next page">Get Started</a>
</div>
</main>
</div>
</div>
<script src="Install%20JupyterHub%20and%20JupyterLab%20from%20the%20ground%20up%20%E2%80%94%20JupyterHub%201.3.0%20documentation_files/index.js"></script>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
© Copyright 2016, Project Jupyter team.<br>
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.5.<br>
</p>
</div>
</footer>
<!-- Inserted RTD Footer -->
<div class="injected">
<div class="rst-versions rst-badge" data-toggle="rst-versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span class="fa fa-book">&nbsp;</span>
v: stable
<span class="fa fa-caret-down"></span>
</span>
<div class="rst-other-versions">
<dl>
<dt>Versions</dt>
<dd><a href="https://jupyterhub.readthedocs.io/en/latest/installation-guide-hard.html">latest</a></dd>
<strong>
<dd><a href="https://jupyterhub.readthedocs.io/en/stable/installation-guide-hard.html">stable</a></dd>
</strong>
<dd><a href="https://jupyterhub.readthedocs.io/en/1.3.0/installation-guide-hard.html">1.3.0</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/1.2.2/installation-guide-hard.html">1.2.2</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/1.2.1/installation-guide-hard.html">1.2.1</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/1.2.0/installation-guide-hard.html">1.2.0</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/1.1.0/installation-guide-hard.html">1.1.0</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/1.0.0/installation-guide-hard.html">1.0.0</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.9.6/installation-guide-hard.html">0.9.6</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.9.5/installation-guide-hard.html">0.9.5</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.9.4/installation-guide-hard.html">0.9.4</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.9.3/installation-guide-hard.html">0.9.3</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.9.2/installation-guide-hard.html">0.9.2</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.9.1/installation-guide-hard.html">0.9.1</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.9.0/installation-guide-hard.html">0.9.0</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.8.1/installation-guide-hard.html">0.8.1</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.8.0/installation-guide-hard.html">0.8.0</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.7.2/installation-guide-hard.html">0.7.2</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.7.1/installation-guide-hard.html">0.7.1</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.7.0/installation-guide-hard.html">0.7.0</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/en/0.6.1/installation-guide-hard.html">0.6.1</a></dd>
</dl>
<dl>
<dt>Downloads</dt>
<dd><a href="https://jupyterhub.readthedocs.io/_/downloads/en/stable/htmlzip/">HTML</a></dd>
<dd><a href="https://jupyterhub.readthedocs.io/_/downloads/en/stable/epub/">Epub</a></dd>
</dl>
<dl>
<!-- These are kept as relative links for internal installs that are http -->
<dt>On Read the Docs</dt>
<dd>
<a href="https://readthedocs.org/projects/jupyterhub/">Project Home</a>
</dd>
<dd>
<a href="https://readthedocs.org/projects/jupyterhub/builds/">Builds</a>
</dd>
<dd>
<a href="https://readthedocs.org/projects/jupyterhub/downloads/">Downloads</a>
</dd>
</dl>
<dl>
<dt>On GitHub</dt>
<dd>
<a href="https://github.com/jupyterhub/jupyterhub/blob/a91197635ab1a9d8c9b3d2e83b4f213d0d535d8d/docs/source/installation-guide-hard.md">View</a>
</dd>
</dl>
<dl>
<dt>Search</dt>
<dd>
<div style="padding: 6px;">
<form id="flyout-search-form" class="wy-form" target="_blank" action="//readthedocs.org/projects/jupyterhub/search/" method="get">
<input type="text" name="q" placeholder="Search docs">
</form>
</div>
</dd>
</dl>
<hr>
<small>
<span>Hosted by <a href="https://readthedocs.org/">Read the Docs</a></span>
<span> · </span>
<a href="https://docs.readthedocs.io/page/privacy-policy.html">Privacy Policy</a>
</small>
</div>
</div>
</div>
</body></html>
\ No newline at end of file
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论