Running dummy authenticator on JupyterHub?

I’m trying to install and run JupyterHub on an Ubuntu 20.04 server.

I would like to install JupyterHub with no authentication, since for now I’ll only be sharing notebooks with folks that will just browse them (I do not need proper auth for people that will edit/create notebooks, as required when you are doing classroom grading and such).

At first I thought I’d want to install tmpauthenticator, but I ended up really not liking the idea of creating a new Unix user for each and every visit to the page; so I thought, dummy is likely to get easier?

Anyways, I got to this setup:

$ grep authenticator_class /home/jupyter/.jupyter/jupyterhub_config.py
#              e.g. `c.JupyterHub.authenticator_class = 'pam'`
# c.JupyterHub.authenticator_class = 'jupyterhub.auth.PAMAuthenticator'
#c.JupyterHub.authenticator_class = 'tmpauthenticator.TmpAuthenticator'
c.JupyterHub.authenticator_class = 'dummy'

… but then I got an error - here from syslog:

Sep 16 15:18:36 srv004808 jupyterhub[1059]: [I 2021-09-16 15:18:36.503 JupyterHub provider:574] Creating oauth client jupyterhub-user-0a3b9869-d0e1-4e60-827f-3fb6e7de29e6
Sep 16 15:18:36 srv004808 jupyterhub[1059]: [E 2021-09-16 15:18:36.515 JupyterHub user:718] Unhandled error starting 0a3b9869-d0e1-4e60-827f-3fb6e7de29e6's server: "getpwnam(): name not found: '0a3b9869-d0e1-4e60-827f-3fb6e7de29e6'"

I’m pretty sure this error occurs, because I’m trying to run jupyterhub under a non-sudo user; but then, as far as I understood, dummy authenticator should not create new users?!

Anyways, then I found this:

create server for new users · Issue #1247 · jupyterhub/jupyterhub

I think DummyAuthenticator doesn’t create users on your system. With DummyAuthenticator, you generally want to use a Spawner that doesn’t map onto system users, such as DockerSpawner.

Oh cool - then I should go with DockerSpawner?

$ grep 'authenticator_class\|spawner_class' /home/jupyter/.jupyter/jupyterhub_config.py
#              e.g. `c.JupyterHub.authenticator_class = 'pam'`
# c.JupyterHub.authenticator_class = 'jupyterhub.auth.PAMAuthenticator'
#c.JupyterHub.authenticator_class = 'tmpauthenticator.TmpAuthenticator'
c.JupyterHub.authenticator_class = 'dummy'
#              e.g. `c.JupyterHub.spawner_class = 'localprocess'`
# c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner'
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'

$ pip3 install dockerspawner

$ sudo systemctl restart jupyterhub

… but now when I visit the page:

500 : Internal Server Error

Error in Authenticator.pre_spawn_start: DockerException Error while fetching server API version: (‘Connection aborted.’, FileNotFoundError(2, ‘No such file or directory’))

Then I found python - docker.errors.DockerException: Error while fetching server API version - Stack Overflow :

Are you sure docker is running on your system? You can get that error when compose is not able to connect to docker via docker socket (if any other way for connection is not defined).

Ok, so let me get this straight: if I do not want to do proper auth, and I do not want to create new Unix users for each visit to the page - that is, I want to use dummy authenticator - then I should actually install docker, even if I don’t need it for anything else?!

Is there any other way to run dummy authenticator, without having to install docker, or any other extra software?

Ok, I think I found a solution for this - Setting up a development install — JupyterHub documentation :

Using DummyAuthenticator & SimpleLocalProcessSpawner

To simplify testing of JupyterHub, it’s helpful to use DummyAuthenticator instead of the default JupyterHub authenticator and SimpleLocalProcessSpawner instead of the default spawner.

There is a sample configuration file that does this in testing/jupyterhub_config.py . To launch jupyterhub with this configuration:

Ah, great - and this file is: https://github.com/jupyterhub/jupyterhub/blob/9d2ceaa1563bc9463cfd22d8d1abe07ebccd79e0/testing/jupyterhub_config.py , which is essentially this:

c = get_config()  # noqa

from jupyterhub.auth import DummyAuthenticator
c.JupyterHub.authenticator_class = DummyAuthenticator

from jupyterhub.spawner import SimpleLocalProcessSpawner
c.JupyterHub.spawner_class = SimpleLocalProcessSpawner

At first, I was confused, because the above example says to import DummyAuthenticator, then assign it - while the gihub page GitHub - jupyterhub/dummyauthenticator: A Dummy JupyterHub Authenticator to make testing easy says:

DEPRECATED

DummyAuthenticator is now a part of JupyterHub core. You can migrate to it by setting:

c.JupyterHub.authenticator_class = "dummy"

… that is, we assign a string, not a class; however, it turns out, both of these work fine (which can be confirmed by the server startup messages).

So the problem with running DummyAuthenticator for me was not due to the authenticator itself, it was due to finding an appropriate spawner that does not create new Unix system users. And the right spawner for me turned out to be not DockerSpawner (which, even if it does not create system users, requires presence of running Docker process) - but SimpleLocalProcessSpawner.

Eventually, this is what I have in my config now:

$ grep 'authenticator_class\|spawner_class' /home/jupyter/.jupyter/jupyterhub_config.py
#              e.g. `c.JupyterHub.authenticator_class = 'pam'`
# c.JupyterHub.authenticator_class = 'jupyterhub.auth.PAMAuthenticator'
#c.JupyterHub.authenticator_class = 'tmpauthenticator.TmpAuthenticator'
c.JupyterHub.authenticator_class = 'dummy'
#c.JupyterHub.authenticator_class = DummyAuthenticator
#              e.g. `c.JupyterHub.spawner_class = 'localprocess'`
# c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner'
#c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
#c.JupyterHub.spawner_class = 'sudospawner.SudoSpawner'
c.JupyterHub.spawner_class = SimpleLocalProcessSpawner

So, now when I start the server (here is how I start it with pdb direct from the command line instead of as a service, since I had difficulties finding the example for that):

$ python3 -m pdb /home/web/Jupyter/notebook/bin/jupyterhub --config=/home/jupyter/.jupyter/jupyterhub_config.py
> /home/web/Jupyter/notebook/bin/jupyterhub(3)<module>()
-> import re
(Pdb) c
[I 2021-09-17 09:23:39.392 JupyterHub app:2459] Running JupyterHub version 1.4.2
[I 2021-09-17 09:23:39.393 JupyterHub app:2489] Using Authenticator: jupyterhub.auth.DummyAuthenticator-1.4.2
[I 2021-09-17 09:23:39.393 JupyterHub app:2489] Using Spawner: jupyterhub.spawner.SimpleLocalProcessSpawner-1.4.2
[I 2021-09-17 09:23:39.393 JupyterHub app:2489] Using Proxy: jupyterhub.proxy.ConfigurableHTTPProxy-1.4.2
[I 2021-09-17 09:23:39.395 JupyterHub app:1534] Loading cookie_secret from /home/web/Jupyter/jupyterhub_cookie_secret
[I 2021-09-17 09:23:39.416 JupyterHub proxy:497] Generating new CONFIGPROXY_AUTH_TOKEN
...
[I 2021-09-17 09:23:39.825 JupyterHub app:2849] JupyterHub is now running at http://:8000
...

… I can confirm I have the right authenticator and spawner loaded; and then when I visit http://mysite.com:8000, I get the “Sign In” form - and as per the documentation, I can enter whatever login (e.g. username) and password, and I get my own Jupyter instance, which actually runs from a newly created folder, /tmp/username (which gets created for each username).

So - at least this problem is solved; nice! Shame I always seem to find the wrong documentation first, though :slight_smile: