1. Building docker images

This section describes how to build the OpenCMISS-Iron docker images.

1.1. Setting up dockerfiles

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

# Modified from Jupyter Docker Stacks base-notebook (Ubuntu 20.04 focal).

# Ubuntu 16.04 (xenial) 
# https://hub.docker.com/_/ubuntu/?tab=tags&name=xenial
# OS/ARCH: linux/amd64
ARG ROOT_CONTAINER=ubuntu:xenial-20200903

ARG BASE_CONTAINER=$ROOT_CONTAINER
FROM $BASE_CONTAINER

LABEL maintainer="OpenCMISS-Iron <psam012@aucklanduni.ac.nz>"
ARG NB_USER="jovyan"
ARG NB_UID="1000"
ARG NB_GID="100"

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

USER root

# Install all OS dependencies for notebook server that starts but lacks all
# features (e.g., download as all possible file formats)
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
 && apt-get install -yq --no-install-recommends \
    wget \
    bzip2 \
    ca-certificates \
    sudo \
    locales \
    fonts-liberation \
    run-one \
 && apt-get clean && rm -rf /var/lib/apt/lists/*

#----------------------------
# Install OpenCMISS dependencies.
RUN apt-get update \
 && apt-get install -yq --no-install-recommends \
    libpthread-stubs0-dev \
    libmpich-dev \
    mpich \
    libmpich12 \
 && apt-get clean && rm -rf /var/lib/apt/lists/*


RUN apt-get update \
 && apt-get install -yq --no-install-recommends \
    gcc \
    gfortran \
    g++ \
    libblas-dev \
    liblapack-dev \
    git \
    make \
    cmake \
    libssl-dev \
    libglew-dev \
    swig \
    sudo \
    cifs-utils \
    systemd \
    openssh-server \
 && apt-get clean && rm -rf /var/lib/apt/lists/*


# Install cmake.
ENV CMAKE_VERSION=3.7.2 \
    CMAKE_DIR=/cmake

RUN wget --quiet https://cmake.org/files/v3.7/cmake-${CMAKE_VERSION}-Linux-x86_64.sh && \
    mkdir $CMAKE_DIR && \
    /bin/bash cmake-${CMAKE_VERSION}-Linux-x86_64.sh --skip-license --prefix=$CMAKE_DIR && \
    rm cmake-${CMAKE_VERSION}-Linux-x86_64.sh
ENV PATH=$CMAKE_DIR/bin:$PATH

#----------------------------

RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen

# Configure environment
ENV CONDA_DIR=/opt/conda \
    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
ENV PATH=$CONDA_DIR/bin:$PATH \
    HOME=/home/$NB_USER

# Copy a script that we will use to correct permissions after running certain commands
COPY fix-permissions /usr/local/bin/fix-permissions
RUN chmod a+rx /usr/local/bin/fix-permissions

# Enable prompt color in the skeleton .bashrc before creating the default NB_USER
RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc

# Create NB_USER with name jovyan user with UID=1000 and in the 'users' group
# and make sure these dirs are writable by the `users` group.
RUN 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 && \
    mkdir -p $CONDA_DIR && \
    chown $NB_USER:$NB_GID $CONDA_DIR && \
    chmod g+w /etc/passwd && \
    fix-permissions $HOME && \
    fix-permissions $CONDA_DIR

USER $NB_UID
WORKDIR $HOME
ARG PYTHON_VERSION=default

# Setup work directory for backward-compatibility
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
ENV MINICONDA_VERSION=4.8.3 \
    MINICONDA_MD5=d63adf39f2c220950a063e0529d4ff74 \
    CONDA_VERSION=4.8.3

WORKDIR /tmp
RUN wget --quiet https://repo.continuum.io/miniconda/Miniconda3-py38_${MINICONDA_VERSION}-Linux-x86_64.sh && \
    echo "${MINICONDA_MD5} *Miniconda3-py38_${MINICONDA_VERSION}-Linux-x86_64.sh" | md5sum -c - && \
    /bin/bash Miniconda3-py38_${MINICONDA_VERSION}-Linux-x86_64.sh -f -b -p $CONDA_DIR && \
    rm Miniconda3-py38_${MINICONDA_VERSION}-Linux-x86_64.sh && \
    echo "conda ${CONDA_VERSION}" >> $CONDA_DIR/conda-meta/pinned && \
    conda config --system --prepend channels conda-forge && \
    conda config --system --set auto_update_conda false && \
    conda config --system --set show_channel_urls true && \
    conda config --system --set channel_priority strict && \
    if [ ! $PYTHON_VERSION = 'default' ]; then conda install --yes python=$PYTHON_VERSION; fi && \
    conda list python | grep '^python ' | tr -s ' ' | cut -d '.' -f 1,2 | sed 's/$/.*/' >> $CONDA_DIR/conda-meta/pinned && \
    conda install --quiet --yes conda && \
    conda install --quiet --yes pip && \
    conda update --all --quiet --yes && \
    conda clean --all -f -y && \
    rm -rf /home/$NB_USER/.cache/yarn && \
    fix-permissions $CONDA_DIR && \
    fix-permissions /home/$NB_USER

# Install Tini
RUN conda install --quiet --yes 'tini=0.18.0' && \
    conda list tini | grep tini | tr -s ' ' | cut -d ' ' -f 1,2 >> $CONDA_DIR/conda-meta/pinned && \
    conda clean --all -f -y && \
    fix-permissions $CONDA_DIR && \
    fix-permissions /home/$NB_USER

# Install Jupyter Notebook, Lab, and Hub
# Generate a notebook server config
# Cleanup temporary files
# Correct permissions
# Do all this in a single RUN command to avoid duplicating all of the
# files across image layers when the permissions change
RUN conda install --quiet --yes \
    'numpy' \
    'virtualenv' \
    'notebook=6.1.3' \
    'jupyterhub=1.1.0' \
    'jupyterlab=2.2.5' && \
    conda clean --all -f -y && \
    npm cache clean --force && \
    jupyter notebook --generate-config && \
    rm -rf $CONDA_DIR/share/jupyter/lab/staging && \
    rm -rf /home/$NB_USER/.cache/yarn && \
    fix-permissions $CONDA_DIR && \
    fix-permissions /home/$NB_USER

EXPOSE 8888

# Configure container startup
ENTRYPOINT ["tini", "-g", "--"]
CMD ["start-notebook.sh"]

# Copy local files as late as possible to avoid cache busting
COPY start.sh start-notebook.sh start-singleuser.sh /usr/local/bin/
COPY jupyter_notebook_config.py /etc/jupyter/

# Fix permissions on /etc/jupyter as root
USER root
RUN fix-permissions /etc/jupyter/

# Switch back to jovyan to avoid accidental container runs as root
USER $NB_UID

WORKDIR $HOME

#----------------------------
# Install OpenCMISS

# Make RUN commands use the new miniconda environment:
SHELL ["conda", "run", "/bin/bash", "-o", "pipefail", "-c"]
RUN mkdir /home/$NB_USER/opencmiss-build
WORKDIR /home/$NB_USER/opencmiss-build
RUN mkdir opencmiss && \
    mkdir setup-build && \
    git clone https://github.com/OpenCMISS/setup.git && \
    cd setup-build && \
    cmake -DOPENCMISS_LIBRARIES=iron -DOPENCMISS_ROOT=../opencmiss ../setup && \
    cmake --build . && \
    rm -rf ../opencmiss/build

ENV PYTHONPATH=/home/jovyan/opencmiss-build/opencmiss/install/lib/python3.8/opencmiss.iron:$PYTHONPATH


WORKDIR $HOME

# Jupyter docker-stacks minimal-notebook

USER root

# Install all OS dependencies for fully functional notebook server
RUN apt-get update && apt-get install -yq --no-install-recommends \
    build-essential \
    emacs-nox \
    vim-tiny \
    git \
    inkscape \
    jed \
    libsm6 \
    libxext-dev \
    libxrender1 \
    lmodern \
    netcat \
    python-dev \
    # ---- nbconvert dependencies ----
    texlive-xetex \
    texlive-fonts-recommended \
    texlive-plain-generic \
    # ----
    tzdata \
    unzip \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# Switch back to jovyan to avoid accidental container runs as root
USER $NB_UID


# Jupyter docker-stacks scipy-notebook

USER root

# ffmpeg for matplotlib anim & dvipng+cm-super for latex labels.
RUN apt-get update && \
    apt-get install -y --no-install-recommends ffmpeg dvipng cm-super && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

# Install ssh server.
RUN mkdir /var/run/sshd
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

USER $NB_UID

# Install Python 3 packages
RUN conda install --quiet --yes \
    'conda-forge::blas=*=openblas' \
    'ipympl=0.5.*'\
    'ipywidgets=7.5.*' \
    'matplotlib-base=3.3.*' \
    'widgetsnbextension=3.5.*'\
    'pythreejs' \
    'k3d' \
    'xeus-python' \
    'pytables' \
    && \
    conda clean --all -f -y && \
    # Activate ipywidgets extension in the environment that runs the notebook server
    jupyter nbextension enable --py widgetsnbextension --sys-prefix && \
    # Also activate ipywidgets extension for JupyterLab
    # Check this URL for most recent compatibilities
    # https://github.com/jupyter-widgets/ipywidgets/tree/master/packages/jupyterlab-manager
    jupyter labextension install @jupyter-widgets/jupyterlab-manager@^2.0.0 --no-build && \
    jupyter labextension install @bokeh/jupyter_bokeh@^2.0.0 --no-build && \
    jupyter labextension install jupyter-matplotlib@^0.7.2 --no-build && \
    jupyter labextension install @jupyterlab/debugger --no-build && \
    jupyter lab build -y && \
    jupyter lab clean -y && \
    npm cache clean --force && \
    rm -rf "/home/${NB_USER}/.cache/yarn" && \
    rm -rf "/home/${NB_USER}/.node-gyp" && \
    fix-permissions "${CONDA_DIR}" && \
    fix-permissions "/home/${NB_USER}"

# Install facets which does not have a pip or conda package at the moment
WORKDIR /tmp
RUN git clone https://github.com/PAIR-code/facets.git && \
    jupyter nbextension install facets/facets-dist/ --sys-prefix && \
    rm -rf /tmp/facets && \
    fix-permissions "${CONDA_DIR}" && \
    fix-permissions "/home/${NB_USER}"

# Import matplotlib the first time to build the font cache.
ENV XDG_CACHE_HOME="/home/${NB_USER}/.cache/"

RUN MPLBACKEND=Agg python -c "import matplotlib.pyplot" && \
    fix-permissions "/home/${NB_USER}"

RUN jupyter labextension install jupyter-threejs && \
    jupyter lab clean -y && \
    npm cache clean --force && \
    rm -rf "/home/${NB_USER}/.cache/yarn" && \
    rm -rf "/home/${NB_USER}/.node-gyp" && \
    fix-permissions "${CONDA_DIR}" && \
    fix-permissions "/home/${NB_USER}"

ENV JUPYTER_ALLOW_INSECURE_WRITES=true

ENV PATH="/home/${NB_USER}/.local/bin":$PATH

USER root

# Pycharm dependencies
RUN apt-get update && apt-get install --no-install-recommends -y \
  less \
  libxtst-dev libxext-dev libxrender-dev libfreetype6-dev \
  libfontconfig1 libgtk2.0-0 libxslt1.1 libxxf86vm1 \
  && apt-get clean && rm -rf /var/lib/apt/lists/*

# Visual studio code dependencies 
RUN apt-get update && apt-get install --no-install-recommends -y \
  libc6-dev libgtk2.0-0 libgtk-3-0 libpango-1.0-0 libcairo2 \
  libfontconfig1 libgconf2-4 libnss3 libasound2 libxtst6 unzip \
  libglib2.0-bin libcanberra-gtk-module libgl1-mesa-glx curl \
  build-essential gettext libstdc++6 software-properties-common \
  wget git xterm automake libtool autogen nodejs libnotify-bin \
  aspell aspell-en htop git mono-complete gvfs-bin libxss1 \
  rxvt-unicode-256color x11-xserver-utils sudo vim libxkbfile1 libnss3 \
  && apt-get clean && rm -rf /var/lib/apt/lists/*

USER $NB_UID

WORKDIR $HOME

# Expose multiple ports (Jupiter notebook and ssh).
EXPOSE 8888 22

1.2. Building images

docker build –progress plain -t opencmis-iron:1.0-minimal-ssh .

1.3. SSH into running docker container

echo 'jovyan:opencmiss' | chpasswd
# Start ssh server
sudo /usr/sbin/sshd -D

ssh jovyan@localhost -p 1000

1.4. Run conda python from an ssh shell

/opt/conda/bin/python

1.5. Install python packages

/opt/conda/bin/pip install --user seaborn

1.6. Pycharm Environmental variables

PYTHONUNBUFFERED=1;PYTHONPATH=/home/jovyan/opencmiss-build/opencmiss/install/lib/python3.8/opencmiss.iron:/home/jovyan/work/mesh-tools:/home/jovyan/work/morphic

1.7. Loading private docker images

cd path/to/dockerfile
docker build --progress plain -t opencmis-iron:1.0-minimal-ssh .
docker save -o opencmis-iron:1.0-minimal-ssh.tar opencmis-iron:1.0-minimal-ssh

Enter the following command:

docker load --input "Z:\Software\Dockers\Saved images\opencmis-iron:1.0-minimal-ssh.tar"

replacing `Z:\` in the above command with the drive letter of your mounted eResearch drive.

Note

This step will take some time.