> ## Documentation Index
> Fetch the complete documentation index at: https://anaconda.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Installing JupyterHub

export const Danger = ({children}) => {
  return <div class="callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border danger-admonition dark:danger-admonition" data-callout-type="danger">
      <div class="mt-0.5 w-4">
        <svg width="14" height="14" viewBox="0 0 14 14" fill="rgb(239, 68, 68)" xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 text-sky-500" aria-label="Danger">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
      </div>
      <div class="text-sm prose min-w-0 w-full">
        {children}
      </div>
    </div>;
};

## Prerequisites

Before you begin, make sure you have the following:

* A working installation of Package Security Manager version `6.4.0` or later.
* A Linux server that meets the [system requirements](/psm-on-prem/6.8.0/admin/integrations/jupyterhub/sys-reqs-and-env-prep).

## Installing JupyterHub

<Steps>
  <Step title="Download and unpack the installer">
    1. Log in to your Linux server as a root user.

    2. Download the installer by running the following command:

       ```sh theme={null}
       # Replace <INSTALLER_LOCATION> with the provided location of your installer
       curl -O <INSTALLER_LOCATION>
       ```

    3. Unpack the installer tarball:

       ```sh Example theme={null}
       tar -xvf jupyterhub-<VERSION>-<HASH>.tar
       ```
  </Step>

  <Step title="Gather your SSL/TLS certificate information">
    Locate your SSL/TLS `.crt` and `.key` files and note their paths for later use.

    If you don't have valid SSL/TLS certificates, you can proceed by using the `DIY-SSL-CA` package (included with the installer):

    <Danger>
      The self-signed certificates created by the `DIY-SSL-CA` package can reduce your time to first use of JupyterHub, *but should be replaced with valid certificates from a trusted certificate authority as soon as possible*. Do not use self-signed certificates in production environments!
    </Danger>

    ```sh theme={null}
    # Replace <HOSTNAME> with your JupyterHub server hostname
    cd DIY-SSL-CA
    bash create_noprompt.sh <HOSTNAME>
    ```

    The `create_noprompt.sh` script generates the files that you'll reference later as environment variables at the following directory locations:

    * `DIY-SSL-CA/CA/ca.crt`
    * `DIY-SSL-CA/out/<HOSTNAME>/<HOSTNAME>-bundle.crt`
    * `DIY-SSL-CA/out/<HOSTNAME>/<HOSTNAME>.key`

    <Note>
      `<HOSTNAME>` is your JupyterHub server hostname.
    </Note>
  </Step>

  <Step title="Create a service account">
    The installer comes with a `keycloak.py` script. Use it to programmatically create a dedicated client for the JupyterHub services to authenticate users via Keycloak:

    ```sh theme={null}
    # Replace <KC_ADMIN> with the username for the Keycloak admin user
    # Replace <KC_PASSWORD> with the password for the Keycloak admin user
    # Replace <PSM_FQDN> with the fully qualified domain name of your Package Security Manager server
    # Replace <CLIENT_ID> with the client ID for the JupyterHub service account
    # Replace <JHUB_FQDN> with the fully qualified domain name of your JupyterHub server
    python keycloak.py create -u <KC_ADMIN> -p <KC_PASSWORD> --protocol https --domain <PSM_FQDN> --clientid <CLIENT_ID> --baseurl https://<JHUB_FQDN>
    ```

    <Note>
      Save the **Client ID** and **Client Secret** in a secure location.
    </Note>
  </Step>

  <Step title="Create an environment file">
    Create an environment file named `.env` in your `/home/<username>/` directory.

    <Note>
      If you already have an `.env` file in your home directory, you can name your new file something else, like `.env_jhub_anaconda`.
    </Note>

    Add the following information to the `.env`file you just created, including the actual values:

    ```sh theme={null}
    # Replace <ANACONDA_SERVER> with the fully qualified domain name of your Package Security Manager server
    # Replace <CLIENT_SECRET> with the client secret for the JupyterHub service account
    # Replace <CERT> with the path to your SSL/TLS certificate file
    # Replace <KEY> with the path to your SSL/TLS key file
    # Replace <CA_CERT> with the path to your CA certificate file (self-signed certificates only)
    # Replace <SPAWNER_TYPE> with your JupyterHub spawner type: local|systemd. Defaults to systemd if not supplied.
    ANACONDA_SERVER= <ANACONDA_SERVER>
    CLIENT_SECRET= <CLIENT_SECRET>
    CERT= <CERT>
    KEY= <KEY>
    CA_CERT= <CA_CERT>
    JUPYTERHUB_SPAWNER_TYPE=<SPAWNER_TYPE> 
    REPO_CHANNELS=("psm_chan1" "psm_chan2" "psm_chan3")
    ```

    <Note>
      `ANACONDA_SERVER=` is the fully qualified domain name of your Package Security Manager server.

      ***

      The CA Cert is only required if you are using self-signed certificates.

      ***

      The `REPO_CHANNELS` variable is a list of channels that the JupyterHub services will use to install packages when users build new environments in Jupyter. The installer configures conda to respect the order of the channels as they are listed in the environment file.
    </Note>
  </Step>

  <Step title="Run the installer">
    Run the installation command:

    ```sh theme={null}
    # Replace <PATH_TO_ENV_FILE> with the path to the environment file you just created
    # Replace <VERSION> with your installer version
    # Replace <HASH> with your installer hash
    sudo ENV_FILE=<PATH_TO_ENV_FILE> ./jupyterhub-<VERSION>-<HASH>.sh -b
    ```
  </Step>
</Steps>

## Troubleshooting

### I am receiving a `libcrypt.so.1` error post installation

<AccordionGroup>
  <Accordion title="Cause">
    Amazon Linux does not include `libxcrypt-compat`, which causes nginx services to error when starting.
  </Accordion>

  <Accordion title="Solution">
    If you receive a `libcrypt.so.1` error post installation, install the `libxcrypt-compat` package on your JupyterHub server:

    ```sh theme={null}
    sudo yum install libxcrypt-compat
    ```

    After installing the package, restart the nginx service:

    ```sh theme={null}
    sudo systemctl restart nginx.service
    ```
  </Accordion>
</AccordionGroup>

### SystemD version too old or unavailable, using local spawner

<AccordionGroup>
  <Accordion title="Cause">
    This warning occurs when JupyterHub is installed on a Linux system running `systemd < 245`. In this case, JupyterHub defaults to using the local spawner instead of systemdSpawner, and resource management is not enabled.
  </Accordion>

  <Accordion title="Solution">
    JupyterHub requires `systemd >= 245` or later for full resource management support.

    Verify your systemd version by running the following command:

    ```sh theme={null}
    systemctl --version
    ```

    If necessary, update your operating system to a Linux distribution that provides `systemd >= 245`.
  </Accordion>
</AccordionGroup>
