Dockerspawner with start.sh

I try to create an individual notebook setup for each user.

jupyerhub_config.py

docker_notebook_image = os.environ['DOCKER_NOTEBOOK_IMAGE']
c.DockerSpawner.image = docker_notebook_image
c.DockerSpawner.cmd = ["start.sh"]
c.DockerSpawner.default_url = '/lab'
c.DockerSpawner.notebook_dir = '/home/{username}'
c.DockerSpawner.environments = {
    'NB_USER': '{username}',
    'CHOWN_HOME': 'yes', 
    'CHOWN_EXTRA': '/home/{username}',
    'CHOWN_EXTRA_OPTS': '-R'
}

Result:

Set username to: {username}
Relocating home dir to /home/{username}
Setting CWD to /home/{username}/
Changing ownership of /home/{username} to 1000:100 with options ''
Executing the command: --ip=0.0.0.0 --port=8888 --notebook-dir=/home/haag --SingleUserNotebookApp.default_url=/lab --debug

When I add

c.DockerSpawner.extra_create_kwargs = { 'user': 'root'}

container fails with:

[I 2021-04-15 14:55:37.507 SingleUserNotebookApp mixins:557] Starting jupyterhub-singleuser server version 1.3.0
[D 2021-04-15 14:55:37.512 SingleUserNotebookApp _version:76] jupyterhub and jupyterhub-singleuser both on version 1.3.0
[C 2021-04-15 14:55:37.512 SingleUserNotebookApp notebookapp:2252] Running as root is not recommended. Use --allow-root to bypass.
[D 2021-04-15 14:55:37.512 SingleUserNotebookApp application:834] Exiting application: jupyter-notebook

What am I doing wrong?

Fixed it.
First error was using

c.DockerSpawner.cmd = [“start.sh”]

start.sh is not executing passed parameters in jupyterhub_config.py as expected. Using

c.DockerSpawner.cmd = ["start-notebook.sh"]

was the key. (Or simply not using it since it is part of docker-stacks/Dockerfile at 20c9b80428d89421e71ce2f0e2b7ef6c2d1762c4 · jupyter/docker-stacks · GitHub)

My second error was using {username}

c.DockerSpawner.environments = {
‘NB_USER’: ‘{username}’,
‘CHOWN_HOME’: ‘yes’,
‘CHOWN_EXTRA’: ‘/home/{username}’,
‘CHOWN_EXTRA_OPTS’: ‘-R’
}

(as I thought it is a global variable). Was not working for me. I fixed it by adding those env variables via Dockerspawner constructor:

class MyDockerSpawner(DockerSpawner):
    def get_env(self):
        username = self.user.name
        env = super().get_env()
        env['NB_USER'] = username
        env['NB_GROUP'] = 'rc'
        env['CHOWN_HOME'] = 'yes'
        env['CHOWN_EXTRA'] = '/home/' + username
        env['CHOWN_EXTRA_OPTS'] = '-R'
        return env
c.JupyterHub.spawner_class = MyDockerSpawner

Worked like a charm!