11# Ubuntu 22.04 LTS - Jammy
2- ARG BASE_IMAGE=ubuntu:jammy-20240125
2+ ARG BASE_IMAGE=ubuntu:jammy-20250730
33
44#
55# Build wheel
66#
7- FROM python:slim AS src
8- RUN pip install build
9- RUN apt-get update && \
10- apt-get install -y --no-install-recommends git
7+ FROM ghcr.io/astral-sh/uv:python3.13-alpine AS src
8+ RUN apk add git
119COPY . /src
12- RUN python -m build /src
10+ RUN uv build --wheel /src
1311
1412#
1513# Download stages
1614#
1715
1816# Utilities for downloading packages
19- FROM ${BASE_IMAGE} as downloader
17+ FROM ${BASE_IMAGE} AS downloader
2018# Bump the date to current to refresh curl/certificates/etc
21- RUN echo "2023.07.20 "
19+ RUN echo "2025.09.25 "
2220RUN apt-get update && \
2321 apt-get install -y --no-install-recommends \
2422 binutils \
@@ -30,159 +28,79 @@ RUN apt-get update && \
3028
3129RUN update-ca-certificates -f
3230
33- # FreeSurfer 7.3.2
34- FROM downloader as freesurfer
35- COPY docker/files/freesurfer7.3.2-exclude.txt /usr/local/etc/freesurfer7.3.2-exclude.txt
36- COPY docker/files/fs-cert.pem /usr/local/etc/fs-cert.pem
37- RUN curl --cacert /usr/local/etc/fs-cert.pem \
38- -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/7.3.2/freesurfer-linux-ubuntu22_amd64-7.3.2.tar.gz \
39- | tar zxv --no-same-owner -C /opt --exclude-from=/usr/local/etc/freesurfer7.3.2-exclude.txt
40-
41- # AFNI
42- FROM downloader as afni
43- # Bump the date to current to update AFNI
44- RUN echo "2023.07.20"
45- RUN mkdir -p /opt/afni-latest \
46- && curl -fsSL --retry 5 https://afni.nimh.nih.gov/pub/dist/tgz/linux_openmp_64.tgz \
47- | tar -xz -C /opt/afni-latest --strip-components 1 \
48- --exclude "linux_openmp_64/*.gz" \
49- --exclude "linux_openmp_64/funstuff" \
50- --exclude "linux_openmp_64/shiny" \
51- --exclude "linux_openmp_64/afnipy" \
52- --exclude "linux_openmp_64/lib/RetroTS" \
53- --exclude "linux_openmp_64/lib_RetroTS" \
54- --exclude "linux_openmp_64/meica.libs" \
55- # Keep only what we use
56- && find /opt/afni-latest -type f -not \( \
57- -name "3dTshift" -or \
58- -name "3dUnifize" -or \
59- -name "3dAutomask" -or \
60- -name "3dvolreg" -or \
61- -name "3dNwarpApply" \
62- \) -delete
63-
6431# Micromamba
65- FROM downloader as micromamba
66-
67- # Install a C compiler to build extensions when needed.
68- # traits<6.4 wheels are not available for Python 3.11+, but build easily.
69- RUN apt-get update && \
70- apt-get install -y --no-install-recommends build-essential && \
71- apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
32+ FROM downloader AS micromamba
7233
7334WORKDIR /
7435# Bump the date to current to force update micromamba
75- RUN echo "2024.02.06 "
36+ RUN echo "2025.09.05 "
7637RUN curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba
7738
7839ENV MAMBA_ROOT_PREFIX="/opt/conda"
7940COPY env.yml /tmp/env.yml
80- # COPY requirements.txt /tmp/requirements.txt
8141WORKDIR /tmp
8242RUN micromamba create -y -f /tmp/env.yml && \
8343 micromamba clean -y -a
8444
8545#
8646# Main stage
8747#
88- FROM ${BASE_IMAGE} as nitransforms
48+ FROM ${BASE_IMAGE} AS nitransforms
8949
9050# Configure apt
9151ENV DEBIAN_FRONTEND="noninteractive" \
9252 LANG="en_US.UTF-8" \
9353 LC_ALL="en_US.UTF-8"
9454
95- # Some baseline tools; bc is needed for FreeSurfer, so don't drop it
9655RUN apt-get update && \
9756 apt-get install -y --no-install-recommends \
98- bc \
99- ca-certificates \
100- curl \
101- git \
102- gnupg \
103- lsb-release \
104- netbase \
105- xvfb && \
57+ libexpat1 \
58+ libgomp1 \
59+ && \
10660 apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
10761
108- # Configure PPAs for libpng12 and libxp6
109- RUN GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/linuxuprising.gpg --recv 0xEA8CACC073C3DB2A \
110- && GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/zeehio.gpg --recv 0xA1301338A3A48C4A \
111- && 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 \
112- && 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
113-
114- # Dependencies for AFNI; requires a discontinued multiarch-support package from bionic (18.04)
115- RUN apt-get update -qq \
116- && apt-get install -y -q --no-install-recommends \
117- ed \
118- gsl-bin \
119- libglib2.0-0 \
120- libglu1-mesa-dev \
121- libglw1-mesa \
122- libgomp1 \
123- libjpeg62 \
124- libpng12-0 \
125- libxm4 \
126- libxp6 \
127- netpbm \
128- tcsh \
129- xfonts-base \
130- xvfb \
131- && 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 \
132- && dpkg -i /tmp/multiarch.deb \
133- && rm /tmp/multiarch.deb \
134- && apt-get install -f \
135- && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
136- && gsl2_path="$(find / -name 'libgsl.so.19' || printf '')" \
137- && if [ -n "$gsl2_path" ]; then \
138- ln -sfv "$gsl2_path" "$(dirname $gsl2_path)/libgsl.so.0" ; \
139- fi \
140- && ldconfig
141-
142- # Install files from stages
143- COPY --from=freesurfer /opt/freesurfer /opt/freesurfer
144- COPY --from=afni /opt/afni-latest /opt/afni-latest
62+ # Install FreeSurfer and AFNI bins from images
63+ COPY --from=freesurfer/freesurfer:7.4.1 \
64+ /usr/local/freesurfer/bin/mri_vol2vol \
65+ /usr/local/freesurfer/bin/
66+ COPY --from=afni/afni_make_build:AFNI_25.2.09 \
67+ /opt/afni/install/libf2c.so \
68+ /opt/afni/install/libmri.so \
69+ /usr/local/lib/
70+ COPY --from=afni/afni_make_build:AFNI_25.2.09 \
71+ /opt/afni/install/3dAllineate \
72+ /opt/afni/install/3dNwarpApply \
73+ /opt/afni/install/3dWarp \
74+ /opt/afni/install/3drefit \
75+ /opt/afni/install/3dvolreg \
76+ /usr/local/bin/
14577
14678# Simulate SetUpFreeSurfer.sh
14779ENV OS="Linux" \
14880 FS_OVERRIDE=0 \
14981 FIX_VERTEX_AREA="" \
15082 FSF_OUTPUT_FORMAT="nii.gz" \
151- FREESURFER_HOME="/opt /freesurfer"
83+ FREESURFER_HOME="/usr/local /freesurfer"
15284ENV SUBJECTS_DIR="$FREESURFER_HOME/subjects" \
15385 FUNCTIONALS_DIR="$FREESURFER_HOME/sessions" \
154- MNI_DIR="$FREESURFER_HOME/mni" \
15586 LOCAL_DIR="$FREESURFER_HOME/local" \
156- MINC_BIN_DIR="$FREESURFER_HOME/mni/bin" \
157- MINC_LIB_DIR="$FREESURFER_HOME/mni/lib" \
158- MNI_DATAPATH="$FREESURFER_HOME/mni/data"
159- ENV PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
160- MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
161- PATH="$FREESURFER_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"
87+ PATH="$FREESURFER_HOME/bin:$PATH"
16288
16389# AFNI config
164- ENV PATH="/opt/afni-latest:$PATH" \
165- AFNI_IMSAVE_WARNINGS="NO" \
166- AFNI_PLUGINPATH="/opt/afni-latest"
167-
168- # Workbench config
169- ENV PATH="/opt/workbench/bin_linux64:$PATH"
90+ ENV AFNI_IMSAVE_WARNINGS="NO"
17091
17192# Create a shared $HOME directory
17293RUN useradd -m -s /bin/bash -G users neuro
17394WORKDIR /home/neuro
174- ENV HOME="/home/neuro" \
175- LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
95+ ENV HOME="/home/neuro"
17696
17797COPY --from=micromamba /bin/micromamba /bin/micromamba
17898COPY --from=micromamba /opt/conda/envs/nitransforms /opt/conda/envs/nitransforms
17999
180100ENV MAMBA_ROOT_PREFIX="/opt/conda"
181101RUN micromamba shell init -s bash && \
182102 echo "micromamba activate nitransforms" >> $HOME/.bashrc
183- ENV PATH="/opt/conda/envs/nitransforms/bin:$PATH" \
184- CPATH="/opt/conda/envs/nitransforms/include:$CPATH" \
185- LD_LIBRARY_PATH="/opt/conda/envs/nitransforms/lib:$LD_LIBRARY_PATH"
103+ ENV PATH="/opt/conda/envs/nitransforms/bin:$PATH"
186104
187105# FSL environment
188106ENV LANG="C.UTF-8" \
@@ -196,22 +114,10 @@ ENV LANG="C.UTF-8" \
196114 FSLREMOTECALL="" \
197115 FSLGECUDAQ="cuda.q"
198116
199- # Unless otherwise specified each process should only use one thread - nipype
200- # will handle parallelization
201- ENV MKL_NUM_THREADS=1 \
202- OMP_NUM_THREADS=1
203-
204117# Install package
205- # CRITICAL: Make sure python setup.py --version has been run at least once
206- # outside the container, with access to the git history.
207118COPY --from=src /src/dist/*.whl .
208119RUN python -m pip install --no-cache-dir $( ls *.whl )[all]
209120
210-
211- RUN find $HOME -type d -exec chmod go=u {} + && \
212- find $HOME -type f -exec chmod go=u {} + && \
213- rm -rf $HOME/.npm $HOME/.conda $HOME/.empty
214-
215121RUN ldconfig
216122WORKDIR /tmp/
217123
0 commit comments