Skip to content

Commit

Permalink
MNT: Define conda environment, refactor Dockerfile
Browse files Browse the repository at this point in the history
  • Loading branch information
effigies committed Dec 13, 2023
1 parent df9b596 commit aea389e
Show file tree
Hide file tree
Showing 4 changed files with 620 additions and 330 deletions.
265 changes: 157 additions & 108 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,140 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# Ubuntu 22.04 LTS - Jammy
ARG BASE_IMAGE=ubuntu:jammy-20230308

#
# Build wheel
#
FROM python:slim AS src
RUN pip install build
RUN apt-get update && \
apt-get install -y --no-install-recommends git
COPY . /src/niworkflows
RUN python -m build /src/niworkflows
COPY . /src
RUN python -m build /src

FROM nipreps/miniconda:py39_2209.01
#
# Download stages
#

ARG DEBIAN_FRONTEND=noninteractive
ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:${CONDA_PATH}/lib"
# Utilities for downloading packages
FROM ${BASE_IMAGE} as downloader
# Bump the date to current to refresh curl/certificates/etc
RUN echo "2023.12.12"
RUN apt-get update && \
apt-get install -y --no-install-recommends \
binutils \
bzip2 \
ca-certificates \
curl \
unzip && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# FreeSurfer 7.3.2
FROM downloader as freesurfer
COPY docker/files/freesurfer7.3.2-exclude.txt /usr/local/etc/freesurfer7.3.2-exclude.txt
RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/7.3.2/freesurfer-linux-ubuntu22_amd64-7.3.2.tar.gz \
| tar zxv --no-same-owner -C /opt --exclude-from=/usr/local/etc/freesurfer7.3.2-exclude.txt

# AFNI
FROM downloader as afni
# Bump the date to current to update AFNI
RUN echo "2023.07.20"
RUN mkdir -p /opt/afni-latest \
&& curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
| tar -xz -C /opt/afni-latest --strip-components 1 \
--exclude "linux_openmp_64/*.gz" \
--exclude "linux_openmp_64/funstuff" \
--exclude "linux_openmp_64/shiny" \
--exclude "linux_openmp_64/afnipy" \
--exclude "linux_openmp_64/lib/RetroTS" \
--exclude "linux_openmp_64/lib_RetroTS" \
--exclude "linux_openmp_64/meica.libs" \
# Keep only what we use
&& find /opt/afni-latest -type f -not \( \
-name "3dTshift" -or \
-name "3dUnifize" -or \
-name "3dAutomask" -or \
-name "3dvolreg" \) -delete

# Installing freesurfer
COPY docker/files/freesurfer7.2-exclude.txt /usr/local/etc/freesurfer7.2-exclude.txt
RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/7.2.0/freesurfer-linux-ubuntu18_amd64-7.2.0.tar.gz \
| tar zxv --no-same-owner -C /opt --exclude-from=/usr/local/etc/freesurfer7.2-exclude.txt
# Micromamba
FROM downloader as micromamba
WORKDIR /
# Bump the date to current to force update micromamba
RUN echo "2023.04.05"
RUN curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba

ENV MAMBA_ROOT_PREFIX="/opt/conda"
COPY env.yml /tmp/env.yml
COPY requirements.txt /tmp/requirements.txt
WORKDIR /tmp
RUN micromamba create -y -f /tmp/env.yml && \
micromamba clean -y -a

#
# Main stage
#
FROM ${BASE_IMAGE} as main

# Configure apt
ENV DEBIAN_FRONTEND="noninteractive" \
LANG="en_US.UTF-8" \
LC_ALL="en_US.UTF-8"

# Some baseline tools; bc is needed for FreeSurfer, so don't drop it
RUN apt-get update && \
apt-get install -y --no-install-recommends \
bc \
ca-certificates \
curl \
git \
gnupg \
lsb-release \
netbase \
xvfb && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Configure PPAs for libpng12 and libxp6
RUN GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/linuxuprising.gpg --recv 0xEA8CACC073C3DB2A \
&& GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/zeehio.gpg --recv 0xA1301338A3A48C4A \
&& echo "deb [signed-by=/usr/share/keyrings/linuxuprising.gpg] https://ppa.launchpadcontent.net/linuxuprising/libpng12/ubuntu jammy main" > /etc/apt/sources.list.d/linuxuprising.list \
&& echo "deb [signed-by=/usr/share/keyrings/zeehio.gpg] https://ppa.launchpadcontent.net/zeehio/libxp/ubuntu jammy main" > /etc/apt/sources.list.d/zeehio.list

# Dependencies for AFNI; requires a discontinued multiarch-support package from bionic (18.04)
RUN apt-get update -qq \
&& apt-get install -y -q --no-install-recommends \
ed \
gsl-bin \
libglib2.0-0 \
libglu1-mesa-dev \
libglw1-mesa \
libgomp1 \
libjpeg62 \
libpng12-0 \
libxm4 \
libxp6 \
netpbm \
tcsh \
xfonts-base \
xvfb \
&& curl -sSL --retry 5 -o /tmp/multiarch.deb http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/multiarch-support_2.27-3ubuntu1.5_amd64.deb \
&& dpkg -i /tmp/multiarch.deb \
&& rm /tmp/multiarch.deb \
&& apt-get install -f \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& gsl2_path="$(find / -name 'libgsl.so.19' || printf '')" \
&& if [ -n "$gsl2_path" ]; then \
ln -sfv "$gsl2_path" "$(dirname $gsl2_path)/libgsl.so.0"; \
fi \
&& ldconfig

# Install files from stages
COPY --from=freesurfer /opt/freesurfer /opt/freesurfer
COPY --from=afni /opt/afni-latest /opt/afni-latest

# Simulate SetUpFreeSurfer.sh
ENV FSL_DIR="/opt/fsl" \
OS="Linux" \
ENV OS="Linux" \
FS_OVERRIDE=0 \
FIX_VERTEX_AREA="" \
FSF_OUTPUT_FORMAT="nii.gz" \
Expand All @@ -55,120 +169,55 @@ ENV SUBJECTS_DIR="$FREESURFER_HOME/subjects" \
MNI_DATAPATH="$FREESURFER_HOME/mni/data"
ENV PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
PATH="$FREESURFER_HOME/bin:$FSFAST_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"

# Install AFNI latest (neurodocker build)
ENV AFNI_DIR="/opt/afni"
RUN echo "Downloading AFNI ..." \
&& mkdir -p ${AFNI_DIR} \
&& curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
| tar -xz -C ${AFNI_DIR} --strip-components 1 \
# Keep only what we use
&& find ${AFNI_DIR} -type f -not \( \
-name "3dTshift" -or \
-name "3dUnifize" -or \
-name "3dAutomask" -or \
-name "3dvolreg" \) -delete
PATH="$FREESURFER_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"

ENV PATH="${AFNI_DIR}:$PATH" \
# AFNI config
ENV PATH="/opt/afni-latest:$PATH" \
AFNI_IMSAVE_WARNINGS="NO" \
AFNI_MODELPATH="${AFNI_DIR}/models" \
AFNI_TTATLAS_DATASET="${AFNI_DIR}/atlases" \
AFNI_PLUGINPATH="${AFNI_DIR}/plugins"

# Install AFNI's dependencies
RUN ${CONDA_PATH}/bin/conda install -c conda-forge -c anaconda \
gsl \
xorg-libxp \
&& sync \
&& ${CONDA_PATH}/bin/conda clean -afy; sync \
&& rm -rf ~/.conda ~/.cache/pip/*; sync \
&& ln -s ${CONDA_PATH}/lib/libgsl.so.25 /usr/lib/x86_64-linux-gnu/libgsl.so.19 \
&& ln -s ${CONDA_PATH}/lib/libgsl.so.25 /usr/lib/x86_64-linux-gnu/libgsl.so.0 \
&& ldconfig

RUN GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/linuxuprising.gpg --recv 0xEA8CACC073C3DB2A \
&& echo "deb [signed-by=/usr/share/keyrings/linuxuprising.gpg] https://ppa.launchpadcontent.net/linuxuprising/libpng12/ubuntu focal main" > /etc/apt/sources.list.d/linuxuprising.list

RUN apt-get update \
&& apt-get install -y -q --no-install-recommends \
libcurl4-openssl-dev \
libgdal-dev \
libgfortran-8-dev \
libgfortran4 \
libglw1-mesa \
libgomp1 \
libjpeg62 \
libpng12-0 \
libnode-dev \
libssl-dev \
libudunits2-dev \
libxm4 \
libxml2-dev \
netpbm \
tcsh \
xfonts-base \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& ldconfig

# Installing ANTs 2.3.4 (NeuroDocker build)
ENV ANTSPATH="/opt/ants"
WORKDIR $ANTSPATH
RUN curl -sSL "https://dl.dropbox.com/s/gwf51ykkk5bifyj/ants-Linux-centos6_x86_64-v2.3.4.tar.gz" \
| tar -xzC $ANTSPATH --strip-components 1
ENV PATH="$ANTSPATH:$PATH"

# FSL 6.0.5.1
RUN curl -sSL https://fsl.fmrib.ox.ac.uk/fsldownloads/fsl-6.0.5.1-centos7_64.tar.gz | tar zxv --no-same-owner -C /opt \
--exclude='fsl/doc' \
--exclude='fsl/refdoc' \
--exclude='fsl/python/oxford_asl' \
--exclude='fsl/data/possum' \
--exclude='fsl/data/first' \
--exclude='fsl/data/mist' \
--exclude='fsl/data/atlases' \
--exclude='fsl/data/xtract_data' \
--exclude='fsl/extras/doc' \
--exclude='fsl/extras/man' \
--exclude='fsl/extras/src' \
--exclude='fsl/src' \
--exclude='fsl/tcl'

ENV FSLDIR="/opt/fsl" \
PATH="/opt/fsl/bin:$PATH" \
FSLOUTPUTTYPE="NIFTI_GZ" \
FSLMULTIFILEQUIT="TRUE" \
FSLTCLSH="/opt/fsl/bin/fsltclsh" \
FSLWISH="/opt/fsl/bin/fslwish" \
FSLLOCKDIR="" \
FSLMACHINELIST="" \
FSLREMOTECALL="" \
FSLGECUDAQ="cuda.q" \
POSSUMDIR="/opt/fsl" \
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/opt/fsl"

# Unless otherwise specified each process should only use one thread - nipype
# will handle parallelization
ENV MKL_NUM_THREADS=1 \
OMP_NUM_THREADS=1
AFNI_PLUGINPATH="/opt/afni-latest"

# Create a shared $HOME directory
RUN useradd -m -s /bin/bash -G users niworkflows
WORKDIR /home/niworkflows
ENV HOME="/home/niworkflows" \
LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"

COPY --from=micromamba /bin/micromamba /bin/micromamba
COPY --from=micromamba /opt/conda/envs/niworkflows /opt/conda/envs/niworkflows

ENV MAMBA_ROOT_PREFIX="/opt/conda"
RUN micromamba shell init -s bash && \
echo "micromamba activate niworkflows" >> $HOME/.bashrc
ENV PATH="/opt/conda/envs/niworkflows/bin:$PATH" \
CPATH="/opt/conda/envs/niworkflows/include:$CPATH" \
LD_LIBRARY_PATH="/opt/conda/envs/niworkflows/lib:$LD_LIBRARY_PATH"

COPY docker/fetch_templates.py /tmp/fetch_templates.py
RUN python /tmp/fetch_templates.py
RUN python /tmp/fetch_templates.py && \
rm /tmp/fetch_templates.py && \
find $HOME/.cache/templateflow -type d -exec chmod go=u {} + && \
find $HOME/.cache/templateflow -type f -exec chmod go=u {} +

# FSL environment
ENV LANG="C.UTF-8" \
LC_ALL="C.UTF-8" \
PYTHONNOUSERSITE=1 \
FSLDIR="/opt/conda/envs/fmriprep" \
FSLOUTPUTTYPE="NIFTI_GZ" \
FSLMULTIFILEQUIT="TRUE" \
FSLLOCKDIR="" \
FSLMACHINELIST="" \
FSLREMOTECALL="" \
FSLGECUDAQ="cuda.q"

# Unless otherwise specified each process should only use one thread - nipype
# will handle parallelization
ENV MKL_NUM_THREADS=1 \
OMP_NUM_THREADS=1

# Installing niworkflows
COPY --from=src /src/niworkflows/dist/*.whl .
RUN /opt/conda/bin/python -m pip install --no-cache-dir $( ls *.whl )[all]
COPY --from=src /src/dist/*.whl .
RUN pip install --no-cache-dir $( ls *.whl )[all]

COPY docker/files/nipype.cfg /home/niworkflows/.nipype/nipype.cfg

Expand Down
Loading

0 comments on commit aea389e

Please sign in to comment.