diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..ec2dcfa9 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,39 @@ +name: docker + +# Build (and smoke-test) the legacy BNG2.pl container image so the Dockerfile +# can't rot silently again (issue #414). Runs on demand and whenever the +# Dockerfile or the dependency set it mirrors changes. +on: + workflow_dispatch: + pull_request: + paths: + - Dockerfile + - pyproject.toml + - .github/workflows/docker.yml + push: + branches: [main] + paths: + - Dockerfile + - pyproject.toml + - .github/workflows/docker.yml + +jobs: + build: + name: docker build (legacy BNG2.pl image) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build image + run: docker build -t pybnf:ci . + + - name: Smoke-test the image + run: | + # PyBNF imports cleanly without bngsim (legacy BNG2.pl backend)... + docker run --rm pybnf:ci python -c "import pybnf; print('pybnf', pybnf.__version__)" + # ...the console script is wired... + docker run --rm pybnf:ci pybnf --help + # ...and BNG2.pl is on PATH via BNGPATH. Use a non-login shell: a + # login shell would re-source /etc/profile and reset PATH, dropping + # the image's BNGPATH entry. + docker run --rm pybnf:ci bash -c 'command -v BNG2.pl' diff --git a/Dockerfile b/Dockerfile index 33f9fc18..b4aa6ce3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,19 @@ # -# To build Docker image, run inside PyBNF directory: -# docker build -t pybnf . +# PyBNF container image -- legacy BNG2.pl backend. +# +# This image bundles BioNetGen's BNG2.pl backend (the open-source rule-based +# modeling engine) together with PyBNF and its public runtime dependencies. # -# If BNGsim is hosted on a private package index, pass the index URL: -# docker build --build-arg PIP_EXTRA_INDEX_URL=https://... -t pybnf . +# It deliberately does NOT install bngsim, PyBNF's modern simulation backend: +# bngsim is a private, macOS-only wheel with no public Linux build, so it cannot +# be installed in a Linux container today (issue #414). PyBNF imports cleanly +# without bngsim and falls back to the legacy BNG2.pl path. When bngsim ships +# public Linux wheels, a bngsim-backed image can replace this one. # -# Run inside PyBNF to mount examples directory inside the image: +# Build (run inside the PyBNF directory): +# docker build -t pybnf . +# +# Run with your examples directory mounted: # docker run -it --rm -v $(pwd)/examples:/project/examples pybnf # # And then inside the image: @@ -13,33 +21,31 @@ # pybnf -c demo_bng.conf # -ARG PYTHON_VERSION=3.12 +ARG PYTHON_VERSION=3.13 ARG BIONETGEN_VERSION=BioNetGen-2.9.3 -### BioNetGen build container -FROM python:${PYTHON_VERSION}-slim AS bionetgen-build - +### BioNetGen: fetch the prebuilt Linux release (no from-source compile) +FROM python:${PYTHON_VERSION}-slim AS bionetgen ARG BIONETGEN_VERSION ENV DEBIAN_FRONTEND=noninteractive -WORKDIR /usr/src RUN apt-get update && apt-get install -y --no-install-recommends \ - autoconf \ - build-essential \ ca-certificates \ - cmake \ - git \ - libtool \ - ninja-build \ - perl && \ + curl && \ rm -rf /var/lib/apt/lists/* -RUN git clone --depth 1 --recurse-submodules --branch "${BIONETGEN_VERSION}" https://github.com/RuleWorld/bionetgen.git - -WORKDIR /usr/src/bionetgen/bng2 -RUN ./make_dist.pl --build +WORKDIR /usr/src +# Use the official prebuilt Linux tarball (BNG2.pl plus its bundled +# run_network/NFsim binaries) instead of compiling from source. This mirrors the +# CI provisioning in .github/actions/setup-pybnf/action.yml and keeps the build +# fast and robust (no autoconf/cmake/ninja toolchain needed). +RUN curl -fsSL \ + "https://github.com/RuleWorld/bionetgen/releases/download/${BIONETGEN_VERSION}/${BIONETGEN_VERSION}-linux.tar.gz" \ + -o bionetgen.tar.gz && \ + tar -xzf bionetgen.tar.gz && \ + rm bionetgen.tar.gz ### PyBNF wheel build container @@ -56,20 +62,34 @@ RUN python -m pip wheel --no-cache-dir --no-deps --wheel-dir /wheels . FROM python:${PYTHON_VERSION}-slim ARG BIONETGEN_VERSION -ARG PIP_EXTRA_INDEX_URL ENV DEBIAN_FRONTEND=noninteractive -ENV PIP_EXTRA_INDEX_URL=${PIP_EXTRA_INDEX_URL} RUN apt-get update && apt-get install -y --no-install-recommends \ libgomp1 \ perl && \ rm -rf /var/lib/apt/lists/* -COPY --from=bionetgen-build /usr/src/bionetgen/bng2/${BIONETGEN_VERSION} /usr/BioNetGen +COPY --from=bionetgen /usr/src/${BIONETGEN_VERSION} /usr/BioNetGen COPY --from=pybnf-build /wheels /tmp/wheels -RUN python -m pip install --no-cache-dir /tmp/wheels/*.whl && \ +# Install PyBNF's PUBLIC runtime dependencies explicitly, then install the wheel +# with --no-deps. We must not let pip re-resolve PyBNF's dependency set here: it +# pins bngsim>=0.5.0,<1, a private macOS-only wheel with no public Linux build, +# which would make the install fail (issue #414). This list mirrors +# pyproject.toml's [project.dependencies] minus bngsim; keep it in sync. +RUN python -m pip install --no-cache-dir \ + 'dask>=2024.1.0' \ + 'distributed>=2024.1.0' \ + 'libroadrunner>=1.6.0' \ + 'msgpack>=0.6.2' \ + 'numpy>=1.24' \ + 'paramiko>=2.7' \ + 'pydantic>=2,<3' \ + 'pyparsing>=2.4,<4' \ + 'scipy>=1.10' \ + 'tornado>=6.1' && \ + python -m pip install --no-cache-dir --no-deps /tmp/wheels/*.whl && \ rm -rf /tmp/wheels ENV BNGPATH=/usr/BioNetGen