11# Dockerfile for a plain Firedrake suitable for testing Firedrake components and applications
2+ # Firedrake is installed as a system package so doesn't require activating a venv.
3+ #
4+ # Three types of build are available:
5+ # 1. A "release" build for a specific version (e.g. 2025.4.2).
6+ # 2. A "release" build with the "release" branch at the latest commit.
7+ # 3. A "developer" build with the "main" branch at the latest commit
8+ #
9+ # A release build will install:
10+ # - Firedrake in editable mode from the specified release tag or branch.
11+ # - PETSc and SLEPc from the corresponding release (specified by firedrake-configure).
12+ # A developer build will install:
13+ # - Firedrake in editable mode from the main branch.
14+ # - PETSc and SLEPc from the main branch.
15+ # - Python dependencies in editable mode that firedrake/main requires the latest main branch for (pyadjoint, ufl, etc).
16+ #
17+ # The two main command line arguments are:
18+ #
19+ # ARCH:
20+ # The `--arch` argument to firedrake-configure, e.g. default, complex
21+ #
22+ # BRANCH:
23+ # Whether to build a release version of Firedrake.
24+ # Options:
25+ # - "release" Build from the latest release branch.
26+ # - <release tag> Build a specific release (e.g. 2025.4.2).
27+ # - "main" Build a developer install from the latest main branch.
28+ #
29+ # Extra apt packages and PETSc configure arguments can also be
30+ # provided with the following command line arguments:
31+ #
32+ # APT_EXTRA_PACKAGES:
33+ # Extra packages to pass to `apt install`
34+ #
35+ # PETSC_EXTRA_ARGS:
36+ # Extra arguments to pass to PETSc's `configure` script
37+ #
38+ # Example usage for a specific firedrake release with complex scalars:
39+ # $ docker build \
40+ # --file=Dockerfile.vanilla \
41+ # --tag=firedrake:2025.4.2-complex \
42+ # --build-arg ARCH=complex \
43+ # --build-arg BRANCH=2025.4.2
44+ #
45+ # Example usage for building from firedrake main with real scalars, ml installed with PETSc, and valgrind installed with apt:
46+ # $ docker build \
47+ # --file=Dockerfile.vanilla \
48+ # --tag=firedrake:main-latest \
49+ # --build-arg ARCH=default \
50+ # --build-arg BRANCH=main \
51+ # --build-arg PETSC_EXTRA_ARGS="--download-ml" \
52+ # --build-arg APT_EXTRA_PACKAGES="valgrind"
253
3- FROM ubuntu:latest
54+ FROM ubuntu:24.04
455
556# Firedrake arch to build
657ARG ARCH="default"
758
59+ # Is this a release build?
60+ ARG BRANCH="release"
61+
62+ # Extra system packages
63+ ARG APT_EXTRA_PACKAGES=
64+
65+ # Extra PETSc configuration options
66+ ARG PETSC_EXTRA_ARGS=
67+
868# Set '-o pipefail' to avoid linter error (https://github.com/hadolint/hadolint/wiki/DL4006)
969SHELL ["/bin/bash", "-o", "pipefail", "-c"]
1070
@@ -18,48 +78,95 @@ ENV TZ=Europe/London
1878
1979# Install 'parallel' because it is needed by 'firedrake-run-split-tests'
2080RUN apt-get update \
21- && apt-get -y install curl parallel python3 python3-pip python3-venv sudo \
81+ && apt-get -y install curl parallel python3 python3-pip python3-venv sudo graphviz graphviz-dev \
2282 && rm -rf /var/lib/apt/lists/*
2383
2484# Allow pip to install into system package locations without prompting
2585ENV PIP_BREAK_SYSTEM_PACKAGES=1
2686ENV OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1
2787
28- # Download firedrake-configure
29- RUN curl -O --output-dir /opt https://raw.githubusercontent.com/firedrakeproject/firedrake/release /scripts/firedrake-configure
88+ # Where to download firedrake-configure from
89+ RUN curl -O --output-dir /opt https://raw.githubusercontent.com/firedrakeproject/firedrake/${BRANCH} /scripts/firedrake-configure
3090
3191# Install system dependencies
3292RUN apt-get update \
3393 && apt-get -y install \
3494 $(python3 /opt/firedrake-configure --arch $ARCH --show-system-packages) \
95+ ${APT_EXTRA_PACKAGES} \
3596 && rm -rf /var/lib/apt/lists/*
3697
3798# OpenMPI will complain if mpiexec is invoked as root unless these are set
3899ENV OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1
39100
40- # Install PETSc. We set the compiler optimisation flags manually here to
41- # remove the default of '-march=native -mtune=native' which is not suitable for Docker images.
42- RUN git clone --depth 1 --branch $(python3 /opt/firedrake-configure --show-petsc-version) https://gitlab.com/petsc/petsc.git /opt/petsc \
101+ # Install PETSc.
102+ # 1. Clone the release tag of PETSc if we're installing a Firedrake release.
103+ # 2. We set the compiler optimisation flags manually here to remove the default
104+ # of '-march=native -mtune=native' which is not suitable for Docker images.
105+ # 3. Remove non-essential files to reduce container size (keep SLEPc for slepc4py).
106+ RUN if [ "${BRANCH}" != "main" ]; then \
107+ CLONE_ARGS="--branch $(python3 /opt/firedrake-configure --show-petsc-version)"; \
108+ fi; \
109+ git clone --depth 1 ${CLONE_ARGS} https://gitlab.com/petsc/petsc.git /opt/petsc \
43110 && cd /opt/petsc \
44111 && python3 /opt/firedrake-configure --arch $ARCH --show-petsc-configure-options | \
45112 sed "s/-march=native -mtune=native/-mtune=generic/g" | \
46- xargs -L1 ./configure --with-make-np=8 --download-slepc \
47- && make \
48- && make check \
49- && rm -rf ./**/externalpackages \
50- && rm -rf ./src/docs \
113+ xargs -L1 ./configure --with-make-np=8 --download-slepc ${PETSC_EXTRA_ARGS} \
114+ && make; \
115+ if [ $? -eq 1 ]; then \
116+ cat configure.log; \
117+ exit; \
118+ fi; \
119+ make check || exit; \
120+ for pkg in $(ls ./arch-firedrake-${ARCH}/externalpackages/); do \
121+ if [ "${pkg}" != "git.slepc" ]; then \
122+ rm -rf ./arch-firedrake-${ARCH}/${pkg} || exit; \
123+ fi; \
124+ done; \
125+ rm -rf ./src/docs \
51126 && rm -f ./src/**/tutorials/output/* \
52127 && rm -f ./src/**/tests/output/* \
53128 && cd - || exit
54129
55130ENV PETSC_DIR=/opt/petsc PETSC_ARCH=arch-firedrake-$ARCH
131+ ENV SLEPC_DIR=$PETSC_DIR/$PETSC_ARCH
56132ENV PATH="$PETSC_DIR/$PETSC_ARCH/bin:$PATH"
57133
58134ENV HDF5_MPI=ON
59135ENV CC=mpicc CXX=mpicxx
60- ENV CFLAGS="-mtune=generic" CPPFLAGS="-mtune=generic"
61136ENV MPICC=$CC
137+ ENV CFLAGS="-O3 -mtune=generic" CPPFLAGS="-O3 -mtune=generic"
62138
63139# Install Firedrake
64- RUN pip install --verbose --no-binary h5py --src /opt \
65- --editable git+https://github.com/firedrakeproject/firedrake.git@release#egg=firedrake[docker]
140+ # - petsc4py and slepc4py are installed from source in PETSc repo.
141+ # - slepc4py is installed without build isolation so it links against
142+ # the correct petsc4py version.
143+ # - Firedrake main branch requires main/master branch of some upstream
144+ # packages. These are installed in editable mode.
145+ # The order these are installed is important, e.g. FIAT must be installed
146+ # before UFL otherwise `pip install fiat` will reinstall pypi ufl.
147+ RUN git clone --branch ${BRANCH} \
148+ https://github.com/firedrakeproject/firedrake.git /opt/firedrake \
149+ && pip cache purge \
150+ && pip install --verbose ${PETSC_DIR}/src/binding/petsc4py \
151+ && pip install --verbose -r /opt/firedrake/requirements-build.txt \
152+ && pip install --verbose --no-build-isolation \
153+ ${SLEPC_DIR}/externalpackages/git.slepc/src/binding/slepc4py \
154+ && pip install --verbose --no-binary h5py --no-build-isolation \
155+ --editable '/opt/firedrake[docker]' || exit; \
156+ if [ ${BRANCH} == "main" ]; then \
157+ for pkg in \
158+ "git+https://github.com/dolfin-adjoint/pyadjoint.git#egg=pyadjoint-ad" \
159+ "git+https://github.com/firedrakeproject/fiat.git#egg=firedrake-fiat" \
160+ "git+https://github.com/FEniCS/ufl.git#egg=fenics-ufl" \
161+ ; do \
162+ pip install --verbose --src /opt --editable ${pkg} || exit; \
163+ done; \
164+ fi
165+
166+ # Force '-mtune=generic' for JIT-ed code
167+ ENV PYOP2_CFLAGS=$CFLAGS
168+
169+ # Run the smoke tests.
170+ RUN cd /opt/firedrake/ \
171+ && firedrake-check \
172+ && firedrake-clean
0 commit comments