    def load_config_file(self):
        """Load JupyterHub singleuser config from the environment"""
        self._log_app_versions()
        if not os.environ.get('JUPYTERHUB_SERVICE_URL'):
            raise KeyError("Missing required environment $JUPYTERHUB_SERVICE_URL")

        cfg = self.config.ServerApp
        cfg.identity_provider_class = JupyterHubIdentityProvider

        # disable some single-user features
        cfg.allow_remote_access = True
        cfg.open_browser = False
        cfg.trust_xheaders = True
        cfg.quit_button = False
        cfg.port_retries = 0
        cfg.answer_yes = True
        self.config.FileContentsManager.delete_to_trash = False

        # load Spawner.notebook_dir configuration, if given
        root_dir = os.getenv("JUPYTERHUB_ROOT_DIR", None)
        if root_dir:
            cfg.root_dir = os.path.expanduser(root_dir)

        # load http server config from environment
        url = urlparse(os.environ['JUPYTERHUB_SERVICE_URL'])
        if url.port:
            cfg.port = url.port
        elif url.scheme == 'http':
            cfg.port = 80
        elif url.scheme == 'https':
            cfg.port = 443
        if url.hostname:
            cfg.ip = url.hostname
        else:
            # All interfaces (ipv4+ipv6)
            cfg.ip = ""

        cfg.base_url = os.environ.get('JUPYTERHUB_SERVICE_PREFIX') or '/'

        # load default_url at all kinds of priority,
        # to make sure it has the desired effect
        cfg.default_url = self.default_url = self.get_default_url()

        # load internal SSL configuration
        cfg.keyfile = os.environ.get('JUPYTERHUB_SSL_KEYFILE') or ''
        cfg.certfile = os.environ.get('JUPYTERHUB_SSL_CERTFILE') or ''
        cfg.client_ca = os.environ.get('JUPYTERHUB_SSL_CLIENT_CA') or ''
        if cfg.certfile:
            self.serverapp.log.info(f"Using SSL cert {cfg.certfile}")

        # Jupyter Server default: config files have higher priority than extensions,
        # by:
        # 1. load config files and CLI
        # 2. load extension config
        # 3. merge file config into extension config

        # we invert that by merging our extension config into server config before
        # they get merged the other way
        # this way config from this extension should always have highest priority

        # but this also puts our config above _CLI_ options,
        # and CLI should come before env,
        # so merge that into _our_ config before loading
        if self.serverapp.cli_config:
            for cls_name, cls_config in self.serverapp.cli_config.items():
                if cls_name in self.config:
                    self.config[cls_name].merge(cls_config)

        self.serverapp.update_config(self.config)

        # config below here has _lower_ priority than user config
        self.config.NotebookApp.extra_template_paths.append(SINGLEUSER_TEMPLATES_DIR)
Load JupyterHub singleuser config from the environment
jupyterhub/singleuser/extension.py