mwalib 3.0.0

A library to simplify reading Murchison Widefield Array (MWA) raw visibilities, voltages and metadata.
Documentation
# syntax=docker/dockerfile:1

# --------------------------------------------------------------------------
# Multi-stage build:
#   builder  - has the full toolchain (rustc/cargo, cmake, build-essential,
#              cfitsio -dev headers) needed to compile mwalib, run its tests,
#              and build the python wheel + venv.
#   runtime  - a clean python:3.13-slim-trixie image that copies over only
#              the finished artifacts (venv, compiled cfitsio .so, example
#              binaries) - no compilers, headers, or Rust toolchain.
# Result: a much smaller, lower-attack-surface image; the builder stage is
# discarded entirely except for what's explicitly copied with --from=builder.
# --------------------------------------------------------------------------

# ---------- builder ----------
FROM python:3.13-slim-trixie AS builder
# Compiles everything (rust, cfitsio, python wheel) - discarded except for
# what the runtime stage below copies out with --from=builder.

# suppress perl locale errors
ENV LC_ALL=C
# suppress apt-get prompts (build-time only, not left set in the final image)
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    build-essential \
    cmake \
    pkg-config \
    curl \
    libcurl4-openssl-dev \
    zlib1g-dev \
    && apt-get autoclean \
    && apt-get clean \
    && apt-get autoremove -y \
    && rm -rf /var/lib/apt/lists/*

# install cfitsio into /usr/local
ARG CFITSIO_VERSION=4.6.3
RUN curl -fsSL "https://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio-${CFITSIO_VERSION}.tar.gz" -o /tmp/cfitsio.tar.gz && \
    tar -xf /tmp/cfitsio.tar.gz -C /tmp && \
    rm /tmp/cfitsio.tar.gz && \
    cd /tmp/cfitsio-${CFITSIO_VERSION} && \
    cmake -S . -B build \
        -DCMAKE_INSTALL_PREFIX=/usr/local \
        -DUSE_PTHREADS=ON \
        -DUSE_SSE2=OFF \
        -DUSE_SSSE3=OFF \
        -DUSE_CURL=ON && \
    cmake --build build -j && \
    cmake --install build && \
    ldconfig && \
    rm -rf /tmp/cfitsio-${CFITSIO_VERSION}

# Get Rust
ARG RUST_VERSION=stable
ENV RUSTUP_HOME=/opt/rust CARGO_HOME=/opt/cargo
ENV PATH="${CARGO_HOME}/bin:${PATH}"
RUN mkdir -m755 $RUSTUP_HOME $CARGO_HOME && ( \
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | env RUSTUP_HOME=$RUSTUP_HOME CARGO_HOME=$CARGO_HOME sh -s -- -y \
    --profile=minimal \
    --component llvm-tools \
    --default-toolchain=${RUST_VERSION} \
    )

# isolated venv for the python side, so it's a clean, self-contained thing
# to copy into the runtime stage
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:${PATH}"
RUN pip install --no-cache-dir --upgrade pip

# copy source into /mwalib
COPY . /mwalib
WORKDIR /mwalib

# NB: this intentionally ignores Cargo.lock pins in favour of the newest
# compatible deps. Drop this RUN if you want reproducible builds instead.
RUN cargo update --verbose

# build + test the rust examples
RUN cargo build --features=examples && \
    cargo test --features=examples

# Build and install the python module + its "dev" dependency group straight
# from pyproject.toml:
#   - maturin's version comes from [build-system].requires (maturin>=1.0,<2.0)
#   - the "python"/"pyo3-extension-module" features come from [tool.maturin]
#   - numpy comes along automatically as a declared [project] dependency
#   - pytest/ruff/toml/ty come from the "dev" group under [dependency-groups]
#     (PEP 735 - needs pip>=25.1, hence the upgrade above)
RUN pip install --no-cache-dir . --group dev

RUN pytest


# ---------- runtime ----------
FROM python:3.13-slim-trixie AS runtime
# Clean image: only runtime shared libs + the built venv/binaries from
# `builder` - no compilers or dev headers ship in the final image.

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    libcurl4 \
    zlib1g \
    && apt-get autoclean \
    && apt-get clean \
    && apt-get autoremove -y \
    && rm -rf /var/lib/apt/lists/*

# cfitsio's runtime shared library, built in the builder stage (root, so it
# can update the system linker cache)
COPY --from=builder /usr/local/lib/libcfitsio* /usr/local/lib/
RUN ldconfig

# optional: run as a non-root user now that build tooling is gone.
# Drop these two lines (and the --chown flags below) to keep running as root.
RUN useradd --create-home --shell /bin/bash mwalib
USER mwalib

# the venv with mwalib + numpy already installed
COPY --from=builder --chown=mwalib:mwalib /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:${PATH}"

# source tree + compiled rust example binaries
WORKDIR /mwalib
COPY --chown=mwalib:mwalib . /mwalib
COPY --from=builder --chown=mwalib:mwalib /mwalib/target/debug/examples /mwalib/target/debug/examples

RUN python -c "import sys; print(f'{sys.implementation=}')"