How can I add a custom user-settings to my Dockerfile based on a image of Jupyter Docker Stacks?

Hi! This is my first post here :slight_smile:

I’m trying to create a custom docker image for my developments but I know only basics things about Docker. Currently, my docker file looks like thtat

FROM jupyter/scipy-notebook:619e9cc2fc07
RUN conda install --quiet --yes \
         ** a lot of python packages **
         && \
         conda clean --all -f -y && \
         fix-permissions $CONDA_DIR && \    
         fix-permissions /home/$NB_USER
RUN jupyter labextension install @jupyterlab/shortcutui --no-build && \
    ** other extensions **
    jupyter lab build && \
    jupyter lab clean
ADD ./.jupyter /home/$NB_USER/.jupyter
RUN fix-permissions /home/$NB_USER/

I’ve the following folder structure/file


that I’ve copied from my local jupyter lab installation where I’ve added some shortcuts.

Then, I build this docker image for later run a container. When I try to change any user-setting, like terminal theme it doesn’t work.

I noted that my added folder doesn’t have user permissions

$ ls -l ~/.jupyter/

total 40
-rw-rw-r-- 1 jovyan users 34420 Apr 19 15:10
drwxr-xr-x 3 root   root   4096 Apr 30 02:48 lab

On the other hand, terminal outputs have some warnings/errors:

[W 04:47:23.923 LabApp] 500 PUT /lab/api/workspaces/lab?1588308443914 ( [Errno 13] Permission denied: '/home/jovyan/.jupyter/lab/workspaces'
[W 04:47:23.924 LabApp] [Errno 13] Permission denied: '/home/jovyan/.jupyter/lab/workspaces'
[E 04:47:23.924 LabApp] {
      "Host": "localhost:10000",
      "Connection": "keep-alive",
      "Content-Length": "293",
      "X-Xsrftoken": "2|922ba05c|adde413288ef6f75b392929821ac3cf6|1588212673",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
      "Content-Type": "application/json",
      "Accept": "*/*",
      "Origin": "http://localhost:10000",
      "Sec-Fetch-Site": "same-origin",
      "Sec-Fetch-Mode": "cors",
      "Sec-Fetch-Dest": "empty",
      "Referer": "http://localhost:10000/lab?",
      "Accept-Encoding": "gzip, deflate, br",
      "Accept-Language": "en-US,en;q=0.9,es-US;q=0.8,es;q=0.7",
      "Cookie": "csrftoken=ngCG5HDk47lLsXJ3XXtqfPF1VE78U51DNsp8tLP38Tv0AIGRq6KDpoY58lOGcWsc; _xsrf=2|922ba05c|adde413288ef6f75b392929821ac3cf6|1588212673; username-localhost-1234=\"2|1:0|10:1588234667|23:username-localhost-1234|44:NjUyODM2ZTBlODViNGQ3MTk5YmExNDJkMDJhMTMxZmU=|07d27ebd2ca6d83da3d3f1a1b9bc022c71c209ad32b9a4134bd9e22f45c44c4c\"; username-localhost-8888=\"2|1:0|10:1588282058|23:username-localhost-8888|44:NTc2ZmYyNTY0YmQzNDY2NTliZjRkZjMwN2M5OTkzOTM=|0dbc3451c8033a3389e173e16f6ac087781f66f97a6b4bb12e38bc85e21aa852\""

fix-permission line shouldn’t have given read/write permission to my docker nb_user?

but I’ve been reading documentation and even source code, but as I’m a statician I’m not an expert with this computer errors hahaha.

I haven’t had a chance to try it directly, but it looks like the dockerfile ADD command is adding files as root, but you need them to be NB_USER. (And NB_USER isn’t going to have permissions to fix-permissions on files owned by root which would explain why fix-permissions doesn’t help.)

Maybe try this in your Dockerfile instead, to set the added files as NB_USER:

ADD --chown=$NB_USER:$NB_GID ./.jupyter /home/$NB_USER/.jupyter

Please let us know if this helps!

Hi for your help! But it doesn’t work :grimacing: However, a friend helped me using your answer as basis.

# Add custom user settings
USER root
ADD ./.jupyter /home/$NB_USER/.jupyter
RUN chown -R $NB_UID:$NB_GID /home/$NB_USER/.jupyter

I don’t know if this was the most elegant way to do it, but it works! hahaha.

Thank you!

1 Like

Great to hear you got it working. I think I just gave you the wrong environment variable off the top of my head. In your solution you use NB_UID instead of NB_USER, which is probably just what was needed in my version. So instead I should have said:

ADD --chown=$NB_UID:$NB_GID ./.jupyter /home/$NB_USER/.jupyter

But I think they are fundamentally the same - your solution copies the files and then runs through and changes ownership; my version does this in one step which I guess is more efficient but a bit more ‘Docker specific’.

Anyway, it sounds like you are on your way now!


1 Like