Single user startup commands / args / entrypoint

I have a custom image that, by default, spins up containers like so:

# ...
EXPOSE 8888
EXPOSE 8787
ENTRYPOINT ["tini", "-g", "--"]
CMD ["start-notebook.sh"]

Works fine locally. The JupyterLab UI works just fine.

I’m trying to deploy this to K8s. In my KubeSpawner config, I have the following:

c.KubeSpawner.profile_list = [
{
    "display_name": "iLabScientificBase - Spot",
    "description": "iLabScientificBase 1CPU and 2GiRam resource limits. BEWARE! This pod will run on AWS Spot Instances!",
    "kubespawner_override": {
        "image": "registry.gitlab.com/3e/ilab/infrastructure/oss/jupyterhub-images/base:0.2.0",
        "image_pull_secrets": [
            "gitlab-registry",
            "gitlab-bot-creds",
        ],
        "cpu_limit": 1,
        "mem_limit": "2G",
        "cpu_guarantee": 1,
        "mem_guarantee": "2G",
    },
},

In the kubespawner_override I’ve tried a number of combinations using args and cmd, but they all fail with the error:

/usr/local/bin/start.sh: line 148: exec: jupyterhub-singleuser: not found
Executing the command: jupyterhub-singleuser --ip=0.0.0.0 --port=8888

What can I do to start up the Pod with the default Docker config?

I need the Pod to run like docker run -p 8888:8888 mycustomimage.

Jupyterhub requires the singleuser server to run jupyterhub-singleuser or an equivalent application that implements the same interface, sojupyter-notebook won’t work.

If you can show us your full Dockerfile and JupyterHub configuration with secrets redacted we can try and help. Alternatively can you try with one of the standard Docker stack images without any customisations?

I use this Dockerfile:

FROM ubuntu:focal as tmp

ARG NB_USER="jovyan"
ARG NB_UID="1000"
ARG NB_GID="100"
ARG PYTHON_VERSION

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

USER root

RUN apt-get update -y && \
    apt-get upgrade -y && \
    apt-get install software-properties-common -y && \
    add-apt-repository -y main && \
    apt-get install  -y --no-install-recommends \
        tini \
        build-essential \
        wget \
        ca-certificates \
        openssh-client \
        curl \
        bzip2 \
        sudo \
        locales \
        fonts-liberation \
        apt-utils \
        build-essential \
        cmake \
        ftp \
        g++ \
        gcc-multilib \
        gfortran \
        git \
        nano-tiny \
        libatlas-base-dev \
        libgeos-dev \
        liblapack-dev \
        libmagic-dev \
        libproj-dev \
        libudunits2-dev \
        proj-bin \
        unzip \
        vim-tiny \
        liblapack-dev \
        libatlas-base-dev \
        libblas-dev \
        udunits-bin \
        libudunits2-0 \
        libudunits2-dev \
        libhdf5-dev \
        libnetcdf-dev \
        libnetcdff-dev \
        netcdf-bin nco \
        gdal-bin \
        libgdal-dev \
        libgeos-dev \
        libproj-dev \
        inkscape \
        libsm6 \
        libxext-dev \
        libxrender1 \
        lmodern \
        netcat \
        graphviz \
        texlive-xetex \
        texlive-fonts-recommended \
        texlive-plain-generic \
        tzdata && \
    wget https://deb.nodesource.com/setup_16.x && \
    chmod 550 setup_16.x && \
    ./setup_16.x && \
    apt-get install nodejs && \
    apt-get clean && rm -rf /var/lib/apt/lists/* && rm -rf setup_16.x && \
    update-alternatives --install /usr/bin/nano nano /bin/nano-tiny 10 && \
    echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen

RUN apt-get update -y && \
    apt-get upgrade -y && \
    apt-get purge --auto-remove -y \
        python \
        python3 && \
    apt-get install -y --no-install-recommends \
        build-essential \
        zlib1g-dev \
        libncurses5-dev \
        libgdbm-dev \
        libnss3-dev \
        libssl-dev \
        libreadline-dev \
        libffi-dev \
        wget && \
    mkdir /python && \
    cd /python && \
    wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \
    tar -xf Python-${PYTHON_VERSION}.tgz && \
    cd Python-${PYTHON_VERSION} && \
    ./configure --enable-optimizations && \
    make install && \
    mv /python/Python-${PYTHON_VERSION}/python /bin

RUN wget https://bootstrap.pypa.io/get-pip.py && \
    python get-pip.py && \
    # apt-get install -y --no-install-recommends python3-pip && \
    rm -rf /python/Python-${PYTHON_VERSION}.tgz && \
    rm -rf /python/get-pip.py && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

COPY fix-permissions /usr/local/bin/fix-permissions

ENV SHELL=/bin/bash \
    NB_USER=$NB_USER \
    NB_UID=$NB_UID \
    NB_GID=$NB_GID \
    LC_ALL=en_US.UTF-8 \
    LANG=en_US.UTF-8 \
    LANGUAGE=en_US.UTF-8 \
    HOME=/home/$NB_USER

RUN chmod a+rx /usr/local/bin/fix-permissions && \
    sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc && \
    echo "auth requisite pam_deny.so" >> /etc/pam.d/su && \
    sed -i.bak -e 's/^%admin/#%admin/' /etc/sudoers && \
    sed -i.bak -e 's/^%sudo/#%sudo/' /etc/sudoers && \
    useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \
    # echo "${NB_USER}:${NB_USER}" | chpasswd && \
    chmod g+w /etc/passwd && \
    fix-permissions $HOME

USER $NB_UID

ENV PATH=$PATH:~/.local/bin:/home/jovyan/.local/bin

RUN mkdir -p $HOME/work && \
    fix-permissions $HOME/work && \
    pip install --no-cache --upgrade \
        jupyter \
        notebook \
        jupyterhub \
        jupyterlab \
        jupyter_kernel_gateway \
        "dask[complete]" \
        virtualenvwrapper \
        virtualenv \
        jupyter-server-proxy \
        jupyter_contrib_nbextensions \
        bokeh \
        jupyterlab-git

ENV JUPYTER_ENABLE_LAB=yes

COPY start.sh start-notebook.sh start-singleuser.sh /usr/local/bin/
COPY jupyter_notebook_config.py /etc/jupyter/

USER root

RUN sed -re "s/c.NotebookApp/c.ServerApp/g" /etc/jupyter/jupyter_notebook_config.py > /etc/jupyter/jupyter_server_config.py && \
    fix-permissions /etc/jupyter/ && \
    chmod 550 /usr/local/bin/start.sh /usr/local/bin/start-singleuser.sh /usr/local/bin/start-notebook.sh && \
    chown $NB_UID:$NB_GID /usr/local/bin/start.sh /usr/local/bin/start-singleuser.sh /usr/local/bin/start-notebook.sh && \
    mkdir -p /usr/local/etc/jupyter && \
    mkdir -p /usr/share/jupyter && \
    fix-permissions /usr/share/jupyter && \
    fix-permissions /usr/local/etc/jupyter && \
    rm -rf /home/jovyan/.jupyter/* && \
    rm -rf /home/jovyan/.local/share/jupyter/*

USER $NB_UID

RUN jupyter labextension install @jupyterlab/git && \
    jupyter server extension enable --py jupyterlab_git --sys-prefix && \
    jupyter lab build

FROM tmp

WORKDIR $HOME
EXPOSE 8888
EXPOSE 8787
ENTRYPOINT ["tini", "-g", "--"]
CMD ["start-notebook.sh"]

It’s using the files in this repo.

You’ve switched away from root before installing jupyterhub which means pip may install it into a user directory instead of the system path. Can you try installing it as root instead?

1 Like

Thanks! That worked fine!

1 Like