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)
This commit is contained in:
Min RK
2017-08-11 13:32:56 +02:00
parent 93b880cb80
commit c6c1ce4cb0
9 changed files with 87 additions and 43 deletions

View File

@@ -25,13 +25,19 @@ RUN conda install --quiet --yes \
'r-irkernel=0.7*' \ 'r-irkernel=0.7*' \
'r-ggplot2=2.2*' \ 'r-ggplot2=2.2*' \
'r-sparklyr=0.5*' \ 'r-sparklyr=0.5*' \
'r-rcurl=1.95*' && conda clean -tipsy 'r-rcurl=1.95*' && \
conda clean -tipsy && \
fix-permissions $CONDA_DIR
# Apache Toree kernel # Apache Toree kernel
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 RUN pip install --no-cache-dir \
RUN jupyter toree install --sys-prefix https://dist.apache.org/repos/dist/dev/incubator/toree/0.2.0/snapshots/dev1/toree-pip/toree-0.2.0.dev1.tar.gz \
&& \
jupyter toree install --sys-prefix && \
fix-permissions $CONDA_DIR
# Spylon-kernel # Spylon-kernel
RUN conda install --quiet --yes 'spylon-kernel=0.4*' && \ RUN conda install --quiet --yes 'spylon-kernel=0.4*' && \
conda clean -tipsy conda clean -tipsy && \
RUN python -m spylon_kernel install --sys-prefix python -m spylon_kernel install --sys-prefix && \
fix-permissions $CONDA_DIR

View File

@@ -33,25 +33,34 @@ RUN wget --quiet https://github.com/krallin/tini/releases/download/v0.10.0/tini
chmod +x /usr/local/bin/tini chmod +x /usr/local/bin/tini
# Configure environment # Configure environment
ENV CONDA_DIR /opt/conda ENV CONDA_DIR=/opt/conda \
ENV PATH $CONDA_DIR/bin:$PATH SHELL=/bin/bash \
ENV SHELL /bin/bash NB_USER=jovyan \
ENV NB_USER jovyan NB_UID=1000 \
ENV NB_UID 1000 NB_OWNER_GROUP=user-writable \
ENV HOME /home/$NB_USER NB_OWNER_GID=10000 \
ENV LC_ALL en_US.UTF-8 LC_ALL=en_US.UTF-8 \
ENV LANG en_US.UTF-8 LANG=en_US.UTF-8 \
ENV LANGUAGE en_US.UTF-8 LANGUAGE=en_US.UTF-8
ENV PATH=$CONDA_DIR/bin:$PATH \
HOME=/home/$NB_USER
ADD fix-permissions /usr/local/bin/fix-permissions
# Create jovyan user with UID=1000 and in the 'users' group # Create jovyan user with UID=1000 and in the 'users' group
# and the user-writable group, which owns all of the
# files we want users to write (/home/jovyan, packages)
RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \ RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \
mkdir -p $CONDA_DIR && \ mkdir -p $CONDA_DIR && \
chown $NB_USER $CONDA_DIR chown $NB_USER $CONDA_DIR && \
groupadd -g $NB_OWNER_GID $NB_OWNER_GROUP && \
usermod -G $NB_OWNER_GROUP $NB_USER && \
fix-permissions /home/$NB_USER
USER $NB_USER USER $NB_USER
# Setup work directory for backward-compatibility # Setup work directory for backward-compatibility
RUN mkdir /home/$NB_USER/work RUN mkdir /home/$NB_USER/work && \
fix-permissions /home/$NB_USER
# Install conda as jovyan and check the md5 sum provided on the download site # Install conda as jovyan and check the md5 sum provided on the download site
ENV MINICONDA_VERSION 4.3.21 ENV MINICONDA_VERSION 4.3.21
@@ -65,14 +74,16 @@ RUN cd /tmp && \
$CONDA_DIR/bin/conda config --system --set auto_update_conda false && \ $CONDA_DIR/bin/conda config --system --set auto_update_conda false && \
$CONDA_DIR/bin/conda config --system --set show_channel_urls true && \ $CONDA_DIR/bin/conda config --system --set show_channel_urls true && \
$CONDA_DIR/bin/conda update --all && \ $CONDA_DIR/bin/conda update --all && \
conda clean -tipsy conda clean -tipsy && \
fix-permissions $CONDA_DIR
# Install Jupyter Notebook and Hub # Install Jupyter Notebook and Hub
RUN conda install --quiet --yes \ RUN conda install --quiet --yes \
'notebook=5.0.*' \ 'notebook=5.0.*' \
'jupyterhub=0.7.*' \ 'jupyterhub=0.7.*' \
'jupyterlab=0.27.*' \ 'jupyterlab=0.27.*' \
&& conda clean -tipsy && conda clean -tipsy && \
fix-permissions $CONDA_DIR
USER root USER root
@@ -88,7 +99,7 @@ COPY start.sh /usr/local/bin/
COPY start-notebook.sh /usr/local/bin/ COPY start-notebook.sh /usr/local/bin/
COPY start-singleuser.sh /usr/local/bin/ COPY start-singleuser.sh /usr/local/bin/
COPY jupyter_notebook_config.py /etc/jupyter/ COPY jupyter_notebook_config.py /etc/jupyter/
RUN chown -R $NB_USER:users /etc/jupyter/ RUN fix-permissions /etc/jupyter/
# Switch back to jovyan to avoid accidental container runs as root # Switch back to jovyan to avoid accidental container runs as root
USER $NB_USER USER $NB_USER

View File

@@ -58,6 +58,9 @@ You may customize the execution of the Docker container and the command it is ru
* `-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.) * `-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.)
* `-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.** * `-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.**
* `-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`).** * `-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`).**
* `--group-add user-writable` - use this argument if you are also specifying
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.
## SSL Certificates ## SSL Certificates
@@ -111,11 +114,6 @@ conda install some-package
```python ```python
# Spawn user containers from this image # Spawn user containers from this image
c.DockerSpawner.container_image = 'jupyter/base-notebook' c.DockerSpawner.container_image = 'jupyter/base-notebook'
# Have the Spawner override the Docker run command
c.DockerSpawner.extra_create_kwargs.update({
'command': '/usr/local/bin/start-singleuser.sh'
})
``` ```
### start.sh ### start.sh
@@ -137,3 +135,4 @@ This script is particularly useful when you derive a new Dockerfile from this im
### Others ### Others
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`). 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`).

27
base-notebook/fix-permissions Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/bash
# set permissions on a directory
# after any installation, if a directory needs to be (human) user-writable,
# run this script on it.
# It will make everything in the directory owned by the group $NB_OWNER_GROUP
# and writable by that group.
# Deployments that want to set a specific user id can preserve permissions
# by adding the `--group-add user-writable` line to `docker run`.
# uses find to avoid touching files that already have the right permissions,
# which would cause massive image explosion
# right permissions are:
# group=$NB_OWNER_GROUP
# AND permissions include group rwX (directory-execute)
set -e
for d in $@; do
find "$d" \
! \( \
-group $NB_OWNER_GROUP \
-a -perm -g+rwX \
\) \
-exec chgrp $NB_OWNER_GROUP {} \; \
-exec chmod g+rwX {} \;
done

View File

@@ -13,14 +13,6 @@ if [ $(id -u) == 0 ] ; then
if [ "$NB_UID" != $(id -u $NB_USER) ] ; then if [ "$NB_UID" != $(id -u $NB_USER) ] ; then
echo "Set user UID to: $NB_UID" echo "Set user UID to: $NB_UID"
usermod -u $NB_UID $NB_USER usermod -u $NB_UID $NB_USER
# Careful: $HOME might resolve to /root depending on how the
# container is started. Use the $NB_USER home path explicitly.
for d in "$CONDA_DIR" "$JULIA_PKGDIR" "/home/$NB_USER"; do
if [[ ! -z "$d" && -d "$d" ]]; then
echo "Set ownership to uid $NB_UID: $d"
chown -R $NB_UID "$d"
fi
done
fi fi
# Change GID of NB_USER to NB_GID if NB_GID is passed as a parameter # Change GID of NB_USER to NB_GID if NB_GID is passed as a parameter

View File

@@ -30,7 +30,8 @@ RUN . /etc/os-release && \
echo "push!(Libdl.DL_LOAD_PATH, \"$CONDA_DIR/lib\")" >> /usr/etc/julia/juliarc.jl && \ echo "push!(Libdl.DL_LOAD_PATH, \"$CONDA_DIR/lib\")" >> /usr/etc/julia/juliarc.jl && \
# Create JULIA_PKGDIR \ # Create JULIA_PKGDIR \
mkdir $JULIA_PKGDIR && \ mkdir $JULIA_PKGDIR && \
chown -R $NB_USER:users $JULIA_PKGDIR chown $NB_USER $JULIA_PKGDIR && \
fix-permissions $JULIA_PKGDIR
USER $NB_USER USER $NB_USER
@@ -52,7 +53,9 @@ RUN conda config --system --add channels r && \
'r-caret=6.0*' \ 'r-caret=6.0*' \
'r-rcurl=1.95*' \ 'r-rcurl=1.95*' \
'r-crayon=1.3*' \ 'r-crayon=1.3*' \
'r-randomforest=4.6*' && conda clean -tipsy 'r-randomforest=4.6*' && \
conda clean -tipsy && \
fix-permissions $CONDA_DIR
# Add Julia packages # Add Julia packages
# Install IJulia as jovyan and then move the kernelspec out # Install IJulia as jovyan and then move the kernelspec out
@@ -72,5 +75,6 @@ RUN julia -e 'Pkg.init()' && \
# move kernelspec out of home \ # move kernelspec out of home \
mv $HOME/.local/share/jupyter/kernels/julia* $CONDA_DIR/share/jupyter/kernels/ && \ mv $HOME/.local/share/jupyter/kernels/julia* $CONDA_DIR/share/jupyter/kernels/ && \
chmod -R go+rx $CONDA_DIR/share/jupyter && \ chmod -R go+rx $CONDA_DIR/share/jupyter && \
rm -rf $HOME/.local rm -rf $HOME/.local && \
fix-permissions $JULIA_PKGDIR $CONDA_DIR/share/jupyter

View File

@@ -32,4 +32,6 @@ RUN conda install --quiet --yes \
'r-caret=6.0*' \ 'r-caret=6.0*' \
'r-rcurl=1.95*' \ 'r-rcurl=1.95*' \
'r-crayon=1.3*' \ 'r-crayon=1.3*' \
'r-randomforest=4.6*' && conda clean -tipsy 'r-randomforest=4.6*' && \
conda clean -tipsy && \
fix-permissions $CONDA_DIR

View File

@@ -42,13 +42,14 @@ RUN conda install --quiet --yes \
'beautifulsoup4=4.5.*' \ 'beautifulsoup4=4.5.*' \
'xlrd' && \ 'xlrd' && \
conda remove --quiet --yes --force qt pyqt && \ conda remove --quiet --yes --force qt pyqt && \
conda clean -tipsy conda clean -tipsy && \
# Activate ipywidgets extension in the environment that runs the notebook server
# Activate ipywidgets extension in the environment that runs the notebook server jupyter nbextension enable --py widgetsnbextension --sys-prefix && \
RUN jupyter nbextension enable --py widgetsnbextension --sys-prefix fix-permissions $CONDA_DIR
# Import matplotlib the first time to build the font cache. # Import matplotlib the first time to build the font cache.
ENV XDG_CACHE_HOME /home/$NB_USER/.cache/ ENV XDG_CACHE_HOME /home/$NB_USER/.cache/
RUN MPLBACKEND=Agg python -c "import matplotlib.pyplot" RUN MPLBACKEND=Agg python -c "import matplotlib.pyplot" && \
fix-permissions /home/$NB_USER
USER $NB_USER USER $NB_USER

View File

@@ -4,5 +4,7 @@ FROM jupyter/scipy-notebook
MAINTAINER Jupyter Project <jupyter@googlegroups.com> MAINTAINER Jupyter Project <jupyter@googlegroups.com>
# Install Python 3 Tensorflow # Install Tensorflow
RUN conda install --quiet --yes 'tensorflow=1.0*' RUN conda install --quiet --yes 'tensorflow=1.0*' && \
conda clean -tipsy && \
fix-permissions $CONDA_DIR