Skip to content

Commit aea389e

Browse files
committed
MNT: Define conda environment, refactor Dockerfile
1 parent df9b596 commit aea389e

File tree

4 files changed

+620
-330
lines changed

4 files changed

+620
-330
lines changed

Dockerfile

Lines changed: 157 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,140 @@
2222
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
# SOFTWARE.
2424

25+
# Ubuntu 22.04 LTS - Jammy
26+
ARG BASE_IMAGE=ubuntu:jammy-20230308
27+
28+
#
29+
# Build wheel
30+
#
2531
FROM python:slim AS src
2632
RUN pip install build
2733
RUN apt-get update && \
2834
apt-get install -y --no-install-recommends git
29-
COPY . /src/niworkflows
30-
RUN python -m build /src/niworkflows
35+
COPY . /src
36+
RUN python -m build /src
3137

32-
FROM nipreps/miniconda:py39_2209.01
38+
#
39+
# Download stages
40+
#
3341

34-
ARG DEBIAN_FRONTEND=noninteractive
35-
ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:${CONDA_PATH}/lib"
42+
# Utilities for downloading packages
43+
FROM ${BASE_IMAGE} as downloader
44+
# Bump the date to current to refresh curl/certificates/etc
45+
RUN echo "2023.12.12"
46+
RUN apt-get update && \
47+
apt-get install -y --no-install-recommends \
48+
binutils \
49+
bzip2 \
50+
ca-certificates \
51+
curl \
52+
unzip && \
53+
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
54+
55+
# FreeSurfer 7.3.2
56+
FROM downloader as freesurfer
57+
COPY docker/files/freesurfer7.3.2-exclude.txt /usr/local/etc/freesurfer7.3.2-exclude.txt
58+
RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/7.3.2/freesurfer-linux-ubuntu22_amd64-7.3.2.tar.gz \
59+
| tar zxv --no-same-owner -C /opt --exclude-from=/usr/local/etc/freesurfer7.3.2-exclude.txt
60+
61+
# AFNI
62+
FROM downloader as afni
63+
# Bump the date to current to update AFNI
64+
RUN echo "2023.07.20"
65+
RUN mkdir -p /opt/afni-latest \
66+
&& curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
67+
| tar -xz -C /opt/afni-latest --strip-components 1 \
68+
--exclude "linux_openmp_64/*.gz" \
69+
--exclude "linux_openmp_64/funstuff" \
70+
--exclude "linux_openmp_64/shiny" \
71+
--exclude "linux_openmp_64/afnipy" \
72+
--exclude "linux_openmp_64/lib/RetroTS" \
73+
--exclude "linux_openmp_64/lib_RetroTS" \
74+
--exclude "linux_openmp_64/meica.libs" \
75+
# Keep only what we use
76+
&& find /opt/afni-latest -type f -not \( \
77+
-name "3dTshift" -or \
78+
-name "3dUnifize" -or \
79+
-name "3dAutomask" -or \
80+
-name "3dvolreg" \) -delete
3681

37-
# Installing freesurfer
38-
COPY docker/files/freesurfer7.2-exclude.txt /usr/local/etc/freesurfer7.2-exclude.txt
39-
RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/7.2.0/freesurfer-linux-ubuntu18_amd64-7.2.0.tar.gz \
40-
| tar zxv --no-same-owner -C /opt --exclude-from=/usr/local/etc/freesurfer7.2-exclude.txt
82+
# Micromamba
83+
FROM downloader as micromamba
84+
WORKDIR /
85+
# Bump the date to current to force update micromamba
86+
RUN echo "2023.04.05"
87+
RUN curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba
88+
89+
ENV MAMBA_ROOT_PREFIX="/opt/conda"
90+
COPY env.yml /tmp/env.yml
91+
COPY requirements.txt /tmp/requirements.txt
92+
WORKDIR /tmp
93+
RUN micromamba create -y -f /tmp/env.yml && \
94+
micromamba clean -y -a
95+
96+
#
97+
# Main stage
98+
#
99+
FROM ${BASE_IMAGE} as main
100+
101+
# Configure apt
102+
ENV DEBIAN_FRONTEND="noninteractive" \
103+
LANG="en_US.UTF-8" \
104+
LC_ALL="en_US.UTF-8"
105+
106+
# Some baseline tools; bc is needed for FreeSurfer, so don't drop it
107+
RUN apt-get update && \
108+
apt-get install -y --no-install-recommends \
109+
bc \
110+
ca-certificates \
111+
curl \
112+
git \
113+
gnupg \
114+
lsb-release \
115+
netbase \
116+
xvfb && \
117+
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
118+
119+
# Configure PPAs for libpng12 and libxp6
120+
RUN GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/linuxuprising.gpg --recv 0xEA8CACC073C3DB2A \
121+
&& GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/zeehio.gpg --recv 0xA1301338A3A48C4A \
122+
&& 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 \
123+
&& 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
124+
125+
# Dependencies for AFNI; requires a discontinued multiarch-support package from bionic (18.04)
126+
RUN apt-get update -qq \
127+
&& apt-get install -y -q --no-install-recommends \
128+
ed \
129+
gsl-bin \
130+
libglib2.0-0 \
131+
libglu1-mesa-dev \
132+
libglw1-mesa \
133+
libgomp1 \
134+
libjpeg62 \
135+
libpng12-0 \
136+
libxm4 \
137+
libxp6 \
138+
netpbm \
139+
tcsh \
140+
xfonts-base \
141+
xvfb \
142+
&& 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 \
143+
&& dpkg -i /tmp/multiarch.deb \
144+
&& rm /tmp/multiarch.deb \
145+
&& apt-get install -f \
146+
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
147+
&& gsl2_path="$(find / -name 'libgsl.so.19' || printf '')" \
148+
&& if [ -n "$gsl2_path" ]; then \
149+
ln -sfv "$gsl2_path" "$(dirname $gsl2_path)/libgsl.so.0"; \
150+
fi \
151+
&& ldconfig
152+
153+
# Install files from stages
154+
COPY --from=freesurfer /opt/freesurfer /opt/freesurfer
155+
COPY --from=afni /opt/afni-latest /opt/afni-latest
41156

42157
# Simulate SetUpFreeSurfer.sh
43-
ENV FSL_DIR="/opt/fsl" \
44-
OS="Linux" \
158+
ENV OS="Linux" \
45159
FS_OVERRIDE=0 \
46160
FIX_VERTEX_AREA="" \
47161
FSF_OUTPUT_FORMAT="nii.gz" \
@@ -55,120 +169,55 @@ ENV SUBJECTS_DIR="$FREESURFER_HOME/subjects" \
55169
MNI_DATAPATH="$FREESURFER_HOME/mni/data"
56170
ENV PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
57171
MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
58-
PATH="$FREESURFER_HOME/bin:$FSFAST_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"
59-
60-
# Install AFNI latest (neurodocker build)
61-
ENV AFNI_DIR="/opt/afni"
62-
RUN echo "Downloading AFNI ..." \
63-
&& mkdir -p ${AFNI_DIR} \
64-
&& curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
65-
| tar -xz -C ${AFNI_DIR} --strip-components 1 \
66-
# Keep only what we use
67-
&& find ${AFNI_DIR} -type f -not \( \
68-
-name "3dTshift" -or \
69-
-name "3dUnifize" -or \
70-
-name "3dAutomask" -or \
71-
-name "3dvolreg" \) -delete
172+
PATH="$FREESURFER_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"
72173

73-
ENV PATH="${AFNI_DIR}:$PATH" \
174+
# AFNI config
175+
ENV PATH="/opt/afni-latest:$PATH" \
74176
AFNI_IMSAVE_WARNINGS="NO" \
75-
AFNI_MODELPATH="${AFNI_DIR}/models" \
76-
AFNI_TTATLAS_DATASET="${AFNI_DIR}/atlases" \
77-
AFNI_PLUGINPATH="${AFNI_DIR}/plugins"
78-
79-
# Install AFNI's dependencies
80-
RUN ${CONDA_PATH}/bin/conda install -c conda-forge -c anaconda \
81-
gsl \
82-
xorg-libxp \
83-
&& sync \
84-
&& ${CONDA_PATH}/bin/conda clean -afy; sync \
85-
&& rm -rf ~/.conda ~/.cache/pip/*; sync \
86-
&& ln -s ${CONDA_PATH}/lib/libgsl.so.25 /usr/lib/x86_64-linux-gnu/libgsl.so.19 \
87-
&& ln -s ${CONDA_PATH}/lib/libgsl.so.25 /usr/lib/x86_64-linux-gnu/libgsl.so.0 \
88-
&& ldconfig
89-
90-
RUN GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/linuxuprising.gpg --recv 0xEA8CACC073C3DB2A \
91-
&& 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
92-
93-
RUN apt-get update \
94-
&& apt-get install -y -q --no-install-recommends \
95-
libcurl4-openssl-dev \
96-
libgdal-dev \
97-
libgfortran-8-dev \
98-
libgfortran4 \
99-
libglw1-mesa \
100-
libgomp1 \
101-
libjpeg62 \
102-
libpng12-0 \
103-
libnode-dev \
104-
libssl-dev \
105-
libudunits2-dev \
106-
libxm4 \
107-
libxml2-dev \
108-
netpbm \
109-
tcsh \
110-
xfonts-base \
111-
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
112-
&& ldconfig
113-
114-
# Installing ANTs 2.3.4 (NeuroDocker build)
115-
ENV ANTSPATH="/opt/ants"
116-
WORKDIR $ANTSPATH
117-
RUN curl -sSL "https://dl.dropbox.com/s/gwf51ykkk5bifyj/ants-Linux-centos6_x86_64-v2.3.4.tar.gz" \
118-
| tar -xzC $ANTSPATH --strip-components 1
119-
ENV PATH="$ANTSPATH:$PATH"
120-
121-
# FSL 6.0.5.1
122-
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 \
123-
--exclude='fsl/doc' \
124-
--exclude='fsl/refdoc' \
125-
--exclude='fsl/python/oxford_asl' \
126-
--exclude='fsl/data/possum' \
127-
--exclude='fsl/data/first' \
128-
--exclude='fsl/data/mist' \
129-
--exclude='fsl/data/atlases' \
130-
--exclude='fsl/data/xtract_data' \
131-
--exclude='fsl/extras/doc' \
132-
--exclude='fsl/extras/man' \
133-
--exclude='fsl/extras/src' \
134-
--exclude='fsl/src' \
135-
--exclude='fsl/tcl'
136-
137-
ENV FSLDIR="/opt/fsl" \
138-
PATH="/opt/fsl/bin:$PATH" \
139-
FSLOUTPUTTYPE="NIFTI_GZ" \
140-
FSLMULTIFILEQUIT="TRUE" \
141-
FSLTCLSH="/opt/fsl/bin/fsltclsh" \
142-
FSLWISH="/opt/fsl/bin/fslwish" \
143-
FSLLOCKDIR="" \
144-
FSLMACHINELIST="" \
145-
FSLREMOTECALL="" \
146-
FSLGECUDAQ="cuda.q" \
147-
POSSUMDIR="/opt/fsl" \
148-
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/opt/fsl"
149-
150-
# Unless otherwise specified each process should only use one thread - nipype
151-
# will handle parallelization
152-
ENV MKL_NUM_THREADS=1 \
153-
OMP_NUM_THREADS=1
177+
AFNI_PLUGINPATH="/opt/afni-latest"
154178

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

185+
COPY --from=micromamba /bin/micromamba /bin/micromamba
186+
COPY --from=micromamba /opt/conda/envs/niworkflows /opt/conda/envs/niworkflows
187+
188+
ENV MAMBA_ROOT_PREFIX="/opt/conda"
189+
RUN micromamba shell init -s bash && \
190+
echo "micromamba activate niworkflows" >> $HOME/.bashrc
191+
ENV PATH="/opt/conda/envs/niworkflows/bin:$PATH" \
192+
CPATH="/opt/conda/envs/niworkflows/include:$CPATH" \
193+
LD_LIBRARY_PATH="/opt/conda/envs/niworkflows/lib:$LD_LIBRARY_PATH"
194+
161195
COPY docker/fetch_templates.py /tmp/fetch_templates.py
162-
RUN python /tmp/fetch_templates.py
196+
RUN python /tmp/fetch_templates.py && \
197+
rm /tmp/fetch_templates.py && \
198+
find $HOME/.cache/templateflow -type d -exec chmod go=u {} + && \
199+
find $HOME/.cache/templateflow -type f -exec chmod go=u {} +
200+
201+
# FSL environment
202+
ENV LANG="C.UTF-8" \
203+
LC_ALL="C.UTF-8" \
204+
PYTHONNOUSERSITE=1 \
205+
FSLDIR="/opt/conda/envs/fmriprep" \
206+
FSLOUTPUTTYPE="NIFTI_GZ" \
207+
FSLMULTIFILEQUIT="TRUE" \
208+
FSLLOCKDIR="" \
209+
FSLMACHINELIST="" \
210+
FSLREMOTECALL="" \
211+
FSLGECUDAQ="cuda.q"
163212

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

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

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

0 commit comments

Comments
 (0)