Problem with DockerSpawner volumes

Hi Guys!
Nice to meet you all here.
I have a problem with permissions for user volumes.
They are being created with root:root ownership and user does not have permission to write there.

def create_dir_hook(spawner):
username = spawner.user.name # get the username
volume_path = os.path.join(‘/volumes/jupyterhub/’, username)
print(f"Checking if {volume_path} exists…")

if not os.path.exists(volume_path):
    print(f"{volume_path} does not exist. Creating directory...")
    # create a directory with umask 0755
    # hub and container user must have the same UID to be writeable
    # still readable by other users on the system
    try:
        # Attempt to create the directory
        os.mkdir(volume_path)
        print(f"Directory {volume_path} created.")
        # Now, do whatever you think your user needs
        # ...
    except OSError as e:
        print(f"Error creating directory {volume_path}: {e}")
  
    try:
        os.chown(volume_path, 1003, 1003) 
        print(f"Ownership of changed successfully.")
    except OSError as e:
        print(f"Error changing ownership of: {e}")
    # now do whatever you think your user needs        

c.Spawner.pre_spawn_hook = create_dir_hook

I’ve set up pre_spawn_hook to create folder for new user with proper rights (container running with uid 1003), but unfortunately they still are root:root

image

notebook_dir = os.environ.get("/volumes/jupyterhub/", "/home/jovyan") c.DockerSpawner.notebook_dir = notebook_dir c.DockerSpawner.volumes = {'/volumes/jupyterhub/{username}/': '/home/jovyan/work11' ,'/volumes/jupyterhub/test/': '/home/jovyan/test'} "test" folder also occurs there so I assume it's created in c.DockerSpawner.volumes not pre_spawn_hook.

Could anyone help me?
I would really appreciate this, cause I have overtook project with Jupyter after my colleague and I’m lost now :smiley:
I’ve search through all web, but nothing works for me :confused:

Here’s also Docker Compose file

version: ‘3.3’

services:
proxy:
build: ./app/proxy
container_name: proxy
ports:
- “443:443”
volumes:
- “/var/run/docker.sock:/var/run/docker.sock”
- ./app/proxy/traefik.yml:/etc/traefik/traefik.yml
- ./letsencrypt:/letsencrypt

jupyterhub:
build: ./app/jupyterhub
container_name: jupyterhub
volumes:
- “/var/run/docker.sock:/var/run/docker.sock:rw”
- “jupyterhub-data:/data”
- “./app/jupyterhub/jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py:ro”
environment:
- ACTIVE_SERVER_LIMIT=${ACTIVE_SERVER_LIMIT}
- ACTIVITY_RESOLUTION=${ACTIVITY_RESOLUTION}
- MEM_LIMIT=${MEM_LIMIT}
- CPU_LIMIT=${CPU_LIMIT}
- DOCKER_NOTEBOOK_IMAGE=notebook_img
- DOCKER_NETWORK_NAME=${COMPOSE_PROJECT_NAME}_default
- HOST=${HOST}
- JUPYTERHUB_IDLE_CULLER_TIMEOUT=${IDLE_CULLER_TIMEOUT}
- DEBUG=${DEBUG}
labels:
- “traefik.http.routers.jupyterhub.rule=Host(${HOST})”
- “traefik.http.routers.whoami.entrypoints=https”
- “traefik.http.routers.jupyterhub.tls.certresolver=tlsresolver”

notebook:
build: ./app/notebook
image: notebook_img
container_name: notebook-throwaway
network_mode: none
command: echo

volumes:
jupyterhub-data:

What do the logs corresponding to your pre_spawn_hook function show?

They seem fine:

 Checking if /volumes/jupyterhub/999 exists...
 /volumes/jupyterhub/999 does not exist. Creating directory...
 Directory /volumes/jupyterhub/999 created.
 /srv/jupyterhub
 Ownership of changed successfully.
 20:36:53.791 [ConfigProxy] e[32minfoe[39m: Proxying http://*:8000 to (no default)
 20:36:53.802 [ConfigProxy] e[32minfoe[39m: Proxy API at http://127.0.0.1:8001/api/routes
 20:36:54.073 [ConfigProxy] e[32minfoe[39m: 200 GET /api/routes 
 20:36:54.080 [ConfigProxy] e[32minfoe[39m: 200 GET /api/routes 
 20:36:54.084 [ConfigProxy] e[32minfoe[39m: Adding route / -> http://jupyterhub:9090
 20:36:54.085 [ConfigProxy] e[32minfoe[39m: Route added / -> http://jupyterhub:9090
 20:36:54.088 [ConfigProxy] e[32minfoe[39m: 201 POST /api/routes/ 
 20:37:04.339 [ConfigProxy] e[31merrore[39m: 503 GET /hub/static/favicon.ico socket hang up
 20:37:21.578 [ConfigProxy] e[32minfoe[39m: Adding route /user/logs-test -> http://172.18.0.4:8888
 20:37:21.580 [ConfigProxy] e[32minfoe[39m: Route added /user/logs-test -> http://172.18.0.4:8888
 20:37:21.584 [ConfigProxy] e[32minfoe[39m: 201 POST /api/routes/user/logs-test 
 20:37:24.649 [ConfigProxy] e[31merrore[39m: 503 GET /user/logs-test/api/kernelspecs socket hang up
 20:37:24.658 [ConfigProxy] e[31merrore[39m: 503 GET /user/logs-test/api/me socket hang up
 20:37:25.023 [ConfigProxy] e[31merrore[39m: 503 GET /user/logs-test/static/favicons/favicon.ico socket hang up

but the folder is still owned by root :confused:
Is it possible that it’s creating it somewhere else?

Now I created user logs-test and I can see this folder in here:
root@master:/jupyter# locate logs-test
/var/lib/docker/overlay2/6dd936fe4111cacba6ebf6e7c7fd82e86b7f5165a9137ddd1253fd3d8b840f99/diff/volumes/jupyterhub/logs-test
/var/lib/docker/overlay2/6dd936fe4111cacba6ebf6e7c7fd82e86b7f5165a9137ddd1253fd3d8b840f99/merged/volumes/jupyterhub/logs-test

May that be an isssue that instead of creating it on server it creates tthem in container?
Would you be able to help me with that?
Thanks in advance! :smiley:

You could try mounting the parent (host) volume inside your JupyterHub container?