Skip to content

Commit c6c1ce4

Browse files
committed
use groups for managing write-access to files
- any files the user should be able to write should have group `user-permissions` with `g+rwX` - remove `chown` from start.sh because it is no longer needed - add `fix-permissions` script for setting the user-writable permissions on a path - user-permissions group as GID 10000 (is there a reason for it to have a different value?) - containers can set group with `--group-add user-writable` if they want to run with a different uid/gid (without -u root -e NB_UID -e NB_GID, which make this unnecessary)
1 parent 93b880c commit c6c1ce4

File tree

9 files changed

+88
-44
lines changed

9 files changed

+88
-44
lines changed

all-spark-notebook/Dockerfile

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@ RUN conda install --quiet --yes \
2525
'r-irkernel=0.7*' \
2626
'r-ggplot2=2.2*' \
2727
'r-sparklyr=0.5*' \
28-
'r-rcurl=1.95*' && conda clean -tipsy
28+
'r-rcurl=1.95*' && \
29+
conda clean -tipsy && \
30+
fix-permissions $CONDA_DIR
2931

3032
# Apache Toree kernel
31-
RUN pip --no-cache-dir install https://dist.apache.org/repos/dist/dev/incubator/toree/0.2.0/snapshots/dev1/toree-pip/toree-0.2.0.dev1.tar.gz
32-
RUN jupyter toree install --sys-prefix
33+
RUN pip install --no-cache-dir \
34+
https://dist.apache.org/repos/dist/dev/incubator/toree/0.2.0/snapshots/dev1/toree-pip/toree-0.2.0.dev1.tar.gz \
35+
&& \
36+
jupyter toree install --sys-prefix && \
37+
fix-permissions $CONDA_DIR
3338

3439
# Spylon-kernel
3540
RUN conda install --quiet --yes 'spylon-kernel=0.4*' && \
36-
conda clean -tipsy
37-
RUN python -m spylon_kernel install --sys-prefix
41+
conda clean -tipsy && \
42+
python -m spylon_kernel install --sys-prefix && \
43+
fix-permissions $CONDA_DIR

base-notebook/Dockerfile

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,34 @@ RUN wget --quiet https://github.com/krallin/tini/releases/download/v0.10.0/tini
3333
chmod +x /usr/local/bin/tini
3434

3535
# Configure environment
36-
ENV CONDA_DIR /opt/conda
37-
ENV PATH $CONDA_DIR/bin:$PATH
38-
ENV SHELL /bin/bash
39-
ENV NB_USER jovyan
40-
ENV NB_UID 1000
41-
ENV HOME /home/$NB_USER
42-
ENV LC_ALL en_US.UTF-8
43-
ENV LANG en_US.UTF-8
44-
ENV LANGUAGE en_US.UTF-8
45-
36+
ENV CONDA_DIR=/opt/conda \
37+
SHELL=/bin/bash \
38+
NB_USER=jovyan \
39+
NB_UID=1000 \
40+
NB_OWNER_GROUP=user-writable \
41+
NB_OWNER_GID=10000 \
42+
LC_ALL=en_US.UTF-8 \
43+
LANG=en_US.UTF-8 \
44+
LANGUAGE=en_US.UTF-8
45+
ENV PATH=$CONDA_DIR/bin:$PATH \
46+
HOME=/home/$NB_USER
47+
48+
ADD fix-permissions /usr/local/bin/fix-permissions
4649
# Create jovyan user with UID=1000 and in the 'users' group
50+
# and the user-writable group, which owns all of the
51+
# files we want users to write (/home/jovyan, packages)
4752
RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \
4853
mkdir -p $CONDA_DIR && \
49-
chown $NB_USER $CONDA_DIR
54+
chown $NB_USER $CONDA_DIR && \
55+
groupadd -g $NB_OWNER_GID $NB_OWNER_GROUP && \
56+
usermod -G $NB_OWNER_GROUP $NB_USER && \
57+
fix-permissions /home/$NB_USER
5058

5159
USER $NB_USER
5260

5361
# Setup work directory for backward-compatibility
54-
RUN mkdir /home/$NB_USER/work
62+
RUN mkdir /home/$NB_USER/work && \
63+
fix-permissions /home/$NB_USER
5564

5665
# Install conda as jovyan and check the md5 sum provided on the download site
5766
ENV MINICONDA_VERSION 4.3.21
@@ -65,14 +74,16 @@ RUN cd /tmp && \
6574
$CONDA_DIR/bin/conda config --system --set auto_update_conda false && \
6675
$CONDA_DIR/bin/conda config --system --set show_channel_urls true && \
6776
$CONDA_DIR/bin/conda update --all && \
68-
conda clean -tipsy
77+
conda clean -tipsy && \
78+
fix-permissions $CONDA_DIR
6979

7080
# Install Jupyter Notebook and Hub
7181
RUN conda install --quiet --yes \
7282
'notebook=5.0.*' \
7383
'jupyterhub=0.7.*' \
7484
'jupyterlab=0.27.*' \
75-
&& conda clean -tipsy
85+
&& conda clean -tipsy && \
86+
fix-permissions $CONDA_DIR
7687

7788
USER root
7889

@@ -88,7 +99,7 @@ COPY start.sh /usr/local/bin/
8899
COPY start-notebook.sh /usr/local/bin/
89100
COPY start-singleuser.sh /usr/local/bin/
90101
COPY jupyter_notebook_config.py /etc/jupyter/
91-
RUN chown -R $NB_USER:users /etc/jupyter/
102+
RUN fix-permissions /etc/jupyter/
92103

93104
# Switch back to jovyan to avoid accidental container runs as root
94105
USER $NB_USER

base-notebook/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ You may customize the execution of the Docker container and the command it is ru
5858
* `-e NB_GID=100` - Specify the gid of the `jovyan` user. Useful to mount host volumes with specific file ownership. For this option to take effect, you must run the container with `--user root`. (The `start-notebook.sh` script will `su jovyan` after adjusting the group id.)
5959
* `-e GRANT_SUDO=yes` - Gives the `jovyan` user passwordless `sudo` capability. Useful for installing OS packages. For this option to take effect, you must run the container with `--user root`. (The `start-notebook.sh` script will `su jovyan` after adding `jovyan` to sudoers.) **You should only enable `sudo` if you trust the user or if the container is running on an isolated host.**
6060
* `-v /some/host/folder/for/work:/home/jovyan/work` - Mounts a host machine directory as folder in the container. Useful when you want to preserve notebooks and other work even after the container is destroyed. **You must grant the within-container notebook user or group (`NB_UID` or `NB_GID`) write access to the host directory (e.g., `sudo chown 1000 /some/host/folder/for/work`).**
61+
* `--group-add user-writable` - use this argument if you are also specifying
62+
a specific user id to launch the container (`-u 5000`), rather than launching the container as root and relying on NB_UID and NB_GID to set the user and group.
63+
6164

6265
## SSL Certificates
6366

@@ -111,11 +114,6 @@ conda install some-package
111114
```python
112115
# Spawn user containers from this image
113116
c.DockerSpawner.container_image = 'jupyter/base-notebook'
114-
115-
# Have the Spawner override the Docker run command
116-
c.DockerSpawner.extra_create_kwargs.update({
117-
'command': '/usr/local/bin/start-singleuser.sh'
118-
})
119117
```
120118

121119
### start.sh
@@ -137,3 +135,4 @@ This script is particularly useful when you derive a new Dockerfile from this im
137135
### Others
138136

139137
You can bypass the provided scripts and specify your an arbitrary start command. If you do, keep in mind that certain features documented above will not function (e.g., `GRANT_SUDO`).
138+

base-notebook/fix-permissions

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
# set permissions on a directory
3+
# after any installation, if a directory needs to be (human) user-writable,
4+
# run this script on it.
5+
# It will make everything in the directory owned by the group $NB_OWNER_GROUP
6+
# and writable by that group.
7+
# Deployments that want to set a specific user id can preserve permissions
8+
# by adding the `--group-add user-writable` line to `docker run`.
9+
10+
# uses find to avoid touching files that already have the right permissions,
11+
# which would cause massive image explosion
12+
13+
# right permissions are:
14+
# group=$NB_OWNER_GROUP
15+
# AND permissions include group rwX (directory-execute)
16+
17+
set -e
18+
19+
for d in $@; do
20+
find "$d" \
21+
! \( \
22+
-group $NB_OWNER_GROUP \
23+
-a -perm -g+rwX \
24+
\) \
25+
-exec chgrp $NB_OWNER_GROUP {} \; \
26+
-exec chmod g+rwX {} \;
27+
done

base-notebook/start.sh

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ if [ $(id -u) == 0 ] ; then
1313
if [ "$NB_UID" != $(id -u $NB_USER) ] ; then
1414
echo "Set user UID to: $NB_UID"
1515
usermod -u $NB_UID $NB_USER
16-
# Careful: $HOME might resolve to /root depending on how the
17-
# container is started. Use the $NB_USER home path explicitly.
18-
for d in "$CONDA_DIR" "$JULIA_PKGDIR" "/home/$NB_USER"; do
19-
if [[ ! -z "$d" && -d "$d" ]]; then
20-
echo "Set ownership to uid $NB_UID: $d"
21-
chown -R $NB_UID "$d"
22-
fi
23-
done
2416
fi
2517

2618
# Change GID of NB_USER to NB_GID if NB_GID is passed as a parameter

datascience-notebook/Dockerfile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ RUN . /etc/os-release && \
3030
echo "push!(Libdl.DL_LOAD_PATH, \"$CONDA_DIR/lib\")" >> /usr/etc/julia/juliarc.jl && \
3131
# Create JULIA_PKGDIR \
3232
mkdir $JULIA_PKGDIR && \
33-
chown -R $NB_USER:users $JULIA_PKGDIR
33+
chown $NB_USER $JULIA_PKGDIR && \
34+
fix-permissions $JULIA_PKGDIR
3435

3536
USER $NB_USER
3637

@@ -52,7 +53,9 @@ RUN conda config --system --add channels r && \
5253
'r-caret=6.0*' \
5354
'r-rcurl=1.95*' \
5455
'r-crayon=1.3*' \
55-
'r-randomforest=4.6*' && conda clean -tipsy
56+
'r-randomforest=4.6*' && \
57+
conda clean -tipsy && \
58+
fix-permissions $CONDA_DIR
5659

5760
# Add Julia packages
5861
# Install IJulia as jovyan and then move the kernelspec out
@@ -72,5 +75,6 @@ RUN julia -e 'Pkg.init()' && \
7275
# move kernelspec out of home \
7376
mv $HOME/.local/share/jupyter/kernels/julia* $CONDA_DIR/share/jupyter/kernels/ && \
7477
chmod -R go+rx $CONDA_DIR/share/jupyter && \
75-
rm -rf $HOME/.local
78+
rm -rf $HOME/.local && \
79+
fix-permissions $JULIA_PKGDIR $CONDA_DIR/share/jupyter
7680

r-notebook/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ RUN conda install --quiet --yes \
3232
'r-caret=6.0*' \
3333
'r-rcurl=1.95*' \
3434
'r-crayon=1.3*' \
35-
'r-randomforest=4.6*' && conda clean -tipsy
35+
'r-randomforest=4.6*' && \
36+
conda clean -tipsy && \
37+
fix-permissions $CONDA_DIR

scipy-notebook/Dockerfile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@ RUN conda install --quiet --yes \
4242
'beautifulsoup4=4.5.*' \
4343
'xlrd' && \
4444
conda remove --quiet --yes --force qt pyqt && \
45-
conda clean -tipsy
46-
47-
# Activate ipywidgets extension in the environment that runs the notebook server
48-
RUN jupyter nbextension enable --py widgetsnbextension --sys-prefix
45+
conda clean -tipsy && \
46+
# Activate ipywidgets extension in the environment that runs the notebook server
47+
jupyter nbextension enable --py widgetsnbextension --sys-prefix && \
48+
fix-permissions $CONDA_DIR
4949

5050
# Import matplotlib the first time to build the font cache.
5151
ENV XDG_CACHE_HOME /home/$NB_USER/.cache/
52-
RUN MPLBACKEND=Agg python -c "import matplotlib.pyplot"
52+
RUN MPLBACKEND=Agg python -c "import matplotlib.pyplot" && \
53+
fix-permissions /home/$NB_USER
5354

5455
USER $NB_USER

tensorflow-notebook/Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ FROM jupyter/scipy-notebook
44

55
MAINTAINER Jupyter Project <[email protected]>
66

7-
# Install Python 3 Tensorflow
8-
RUN conda install --quiet --yes 'tensorflow=1.0*'
7+
# Install Tensorflow
8+
RUN conda install --quiet --yes 'tensorflow=1.0*' && \
9+
conda clean -tipsy && \
10+
fix-permissions $CONDA_DIR

0 commit comments

Comments
 (0)