Sharing information between docker containers and host

Hello Docker Community,

I am quite a beginner when it comes to dockers and would really appreciate any advice or help on how to fix my current issue.

I am running a jupyterhub multi-user deployment using docker containers. Each user should solve an assignment on their instance of the hub. at the end of their assignment, a score is generated.

I would like to be able to send this score back to the host container. I am trying to bind-mount a directory where every user will add their score in a text file in this shared directory. This is then read in the host directory.

I would like the changes to be seen instantly on the host side. I can not restart the containers or close them as the data would be lost.

This is my current docker-compose:

version: "3"

services:
  jupyterhub:
    restart: always
    build: ./jupyterhub
    hostname: jupyterhub
    ports:
      - "8080:8000"
      - "10101:10101"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "/home/jupyterhub/user_score:/home/jovyan/data"

I have created a directory called ‘user_score’ on the host container.

when I deploy, I don’t see the directory ‘data’ in the user container nor any of the files I added in the ‘user_score’ directory for testing.

Any suggestions or clues on how to achieve this would be highly appreciated as I am still new with docker and learning as I go :slight_smile:

Thank you very much!

[quote=“melhayany, post:1, topic:127164”]
I have ceated a directory called ‘user_score’ on the host container.
[/quote]1
Just because not everyone knows JupyterHub, let’s clarify that when you write “host container” you mean the JupyterHub container which will start new containers for each user when they log in on the web ui served by the JupyterHub container. Right?

Why do you expect to see that directory? You mounted it only to the JupyterHub container. I don’t know if you can define bind mounts for the user containers, but if you can, the host will be your Docker host and not JupyterHub, so you need to mount the same source path: /home/jupyterhub/user_score

I know that in a Kubernetes cluster JupyterHub would request a persistent volume for each user container, not a bind mount. What I can suggest is using a REST API which you can implement for this purpose or maybe an S3 storage where you can save the files and read it in any container with the proper access tokens.

@rimelek Thank you for your reply.

To answer your first question mentioned here:

Just because not everyone knows JupyterHub, let’s clarify that when you write “host container” you mean the JupyterHub container which will start new containers for each user when they log in on the web ui served by the JupyterHub container. Right?

Yes, you are right.

Why do you expect to see that directory?

Maybe I misunderstood what I read about volumes. I also read here in this post that it was possible to share a directory between containers but I was not sure how to apply the implementation they mentioned to my current deployment.

Thank you for your suggestion to use a REST API or S3 storage. I will look that up, but it would be better if it is possible to do it with the approach I mentioned.

Thanks again for your reply. if you have any idea about what they mentioned in the post I linked (and time to check it out :slight_smile: ), it would be great.

This appers to be a JupyterHub specific problem.

According the docs the user instances are created by spawners.

In your case probably the dockerspawner, which has an option for volumes. You might want to take a closer look to the api, to figure out how to spawn user instances that use a volume.

1 Like

Could you explain what you understood, why you think it should work? The whole topic is about mounting a folder from the host to a container. Yes, that is possible, but you need to define the mount for each container and you only defined it on the main JupyterHub container.

As @meyay wrote, there are spawners to run the user containers. If you find a way to define bind mounts for those containers using some spawner parameter, that could work. But JupyterHub will probably not automatically share its mounts. Docker itself would definitely not do that.

It looks like the Docker spawner has some mount parameters, so you could try that.

@meyay Thank you for your reply. yes I investigated the spawner option and added this to my jupyterhub_config.py

c.DockerSpawner.volumes = {
        '/home/jupyterhub/user_score': '/home/jovyan/user_score'
}

By doing so, I am able to see ‘user_score’ on the user side. Any additional file I add from the user side appears instantly on the host side (and vice versa)

However, the folder doesn’t appear in the host jupyterhub container.

I know it sounds a bit confusing, mentioning the host many times. to clarify my implementation:

There is the VM machine that deploys the host container of jupyterhub. the host container of jupyterhub then creates user instances/containers.

‘user_score’ is created on the VM machine. and so by doing the snippet of code above, I bound that directory with the user instances.

I am just missing this folder in the host jupyterhub container as well.

I hope I made it clear. sorry for any confusion in my wording before. :pray:t3:

@rimelek Thank you for replying back.

From my understanding, volumes are used to persist/save data even after a container is lost. from my understanding, it can also be used to share a directory/file with all containers.

I am still trying to understand the connection of Jupyterhub with dockers and how they deploy everything. There are just too many paths, and it starts to get confusing :sweat_smile:.

I probably need to adjust the dockerfiles as well as the jupyterhub configuration.

I already adjusted the jupyterhub_config file, hence I now see the folder I mounted. I need it to appear at the host container as well now. which I am not sure in which config/file I need to add this.

Thank you again

You alread have this (volume) bind in the compose file of your initial post:

      - "/home/jupyterhub/user_score:/home/jovyan/data"

Which litteraly bind mounts the provided host folder into the provided container target folder. So :/home/jovyan/data` inside the container already accesses the host folder directly…

Dockers is an other brand of garments :slight_smile: We are talking about Docker containers. Docker is the software with multiple components that runs these containers.

If you define it for all containers using the same source volume or host directory.

I removed this from the docker-compose file to see the effect of this line:

c.DockerSpawner.volumes = {
        '/home/jupyterhub/user_score': '/home/jovyan/user_score'
}

Now the docker compose doesn’t include any volume mounting. which is probably the missing part, if I understood correctly?

This is the current docker-compose for reference:

version: "3"

services:
  jupyterhub:
    restart: always
    build: ./jupyterhub
    hostname: jupyterhub
    ports:
      - "8080:8000"
      - "10101:10101"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment:
      HUB_IP: "jupyterhub"
      DOCKER_NOTEBOOK_IMAGE: "exam-scipy-notebook"
      DOCKER_NETWORK_NAME: "jupyterhub-network"
      DOCKER_JUPYTER_IMAGE:  "jupyter/scipy-notebook:hub-1.5.0"
      JUPYTERHUB_CRYPT_KEY: "${JUPYTER_CRYPT_KEY}"  
      LTI_CLIENT_KEY: "${LTI_CLIENT_KEY}"
      LTI_SHARED_SECRET: "${LTI_SHARED_SECRET}"

    networks:
      - default
    
networks:
  default:
    external:
      name: "jupyterhub-network"

Yes, correct! Sorry, I know my explanation can be confusing sometimes :sweat_smile:

Please re-add that line. By removing the line, you made the opposite of what you intended to do.
The jupyterhub IS configured by the compose file, the spawned containers are not.

jupyterhub commands the docker engine itself when it spawns containers - that’s why you bind the docker.sock into the container, but it can not change the configuration of it’s own container.

I have re-added the line. Thanks for the clarification. :slight_smile:

I checked the host jupyterhub container and I can now see the folder ‘user_score’ there as well!

I think this is what I was trying to do :smile:

I would like to thank you both @meyay @rimelek for your help and patience in explaining to me. :slight_smile: