Skip to content

Commit

Permalink
Merge pull request #1503 from brian-team/docker_images
Browse files Browse the repository at this point in the history
Automatically build docker images for each Brian release
  • Loading branch information
bdevans committed Mar 11, 2024
2 parents deb498f + 6f8a3d8 commit 9872c74
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and publish to TestPyPI or PyPI
name: Build and publish
on: [push, pull_request]

jobs:
Expand Down Expand Up @@ -43,9 +43,9 @@ jobs:
CIBW_TEST_COMMAND: python {project}/dev/continuous-integration/run_simple_test.py
CIBW_TEST_REQUIRES: pytest
- name: store distribution 📦
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: packages
name: packages-${{ matrix.os }}
path: dist

build-linux:
Expand Down Expand Up @@ -86,9 +86,9 @@ jobs:
CIBW_TEST_COMMAND: python {project}/dev/continuous-integration/run_simple_test.py
CIBW_TEST_REQUIRES: pytest
- name: store distribution 📦
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: packages
name: packages-linux-${{ matrix.arch }}
path: dist

deploy_dev:
Expand All @@ -103,9 +103,10 @@ jobs:
- build-linux
steps:
- name: load distribution 📦
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: packages
pattern: packages-*
merge-multiple: true
path: dist/
- name: Publish distribution 📦 to Test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Expand All @@ -124,9 +125,83 @@ jobs:
- build-linux
steps:
- name: load distribution 📦
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: packages
pattern: packages-*
merge-multiple: true
path: dist/
- name: Publish distribution release 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

build-docker:
name: Build docker image
runs-on: ubuntu-latest
needs: build-linux
steps:
- name: Checkout repository
uses: actions/checkout@v4
# https://github.com/actions/checkout/
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
# https://github.com/docker/metadata-action
with:
images: |
briansimulator/brian
flavor: latest=true
tags: |
# type=semver,pattern={{raw}}
type=ref,event=tag
labels: |
org.opencontainers.image.title="Brian Docker Image"
org.opencontainers.image.description="Docker image for Brian - a free, open source simulator for spiking neural networks"
org.opencontainers.image.url=https://hub.docker.com/r/briansimulator/brian
org.opencontainers.image.source=https://github.com/brian-team/brian2
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# https://github.com/docker/setup-qemu-action
with:
platforms: 'amd64,arm64'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# https://github.com/docker/setup-buildx-action
- name: Login to DockerHub
uses: docker/login-action@v3
# https://github.com/docker/login-action
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: load Linux x86 distribution 📦
uses: actions/download-artifact@v4
with:
pattern: packages-linux-*
merge-multiple: true
path: packages
- run: |
mkdir dist
cp packages/Brian2*cp312-manylinux*_x86_64.whl dist
cp packages/Brian2*cp312-manylinux*_aarch64.whl dist
- name: Build (and potentially push) the Docker image
uses: docker/build-push-action@v5
# https://github.com/docker/build-push-action
with:
context: .
file: docker/Dockerfile
build-args: |
'BASE_IMAGE_TAG=3.12-bookworm'
platforms: 'amd64,arm64'
push: ${{ github.repository == 'brian-team/brian2' && startsWith(github.ref, 'refs/tags') }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Push docker image to dev repository
if: ${{ github.repository == 'brian-team/brian2' && github.event_name == 'push' && !startsWith(github.ref, 'refs/tags') }}
uses: docker/build-push-action@v5
with:
context: .
file: docker/Dockerfile
build-args: |
'BASE_IMAGE_TAG=3.12-bookworm'
platforms: 'amd64,arm64'
push: true
tags: briansimulator/brian-dev:dev-${{ github.ref_name }}
labels: ${{ steps.meta.outputs.labels }}
8 changes: 7 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Stimberg, M, Brette, R, Goodman, DFM. “Brian 2, an Intuitive and Efficient Neu
.. image:: https://img.shields.io/conda/vn/conda-forge/brian2.svg
:target: https://anaconda.org/conda-forge/brian2


.. image:: https://img.shields.io/debian/v/python3-brian/testing
:alt: Debian package
:target: https://packages.debian.org/testing/python3-brian
Expand All @@ -40,6 +39,13 @@ Stimberg, M, Brette, R, Goodman, DFM. “Brian 2, an Intuitive and Efficient Neu
:alt: AUR version
:target: https://aur.archlinux.org/packages/python-brian2

.. image:: https://github.com/brian-team/brian2/actions/workflows/publish.yml/badge.svg
:target: https://github.com/brian-team/brian2/actions/workflows/publish.yml
:alt: Publish status on GitHub Actions

.. image:: https://img.shields.io/docker/pulls/briansimulator/brian
:alt: Docker Pulls


.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.8099373.svg
:target: https://doi.org/10.5281/zenodo.8099373
Expand Down
61 changes: 61 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# docker buildx build --push --platform linux/amd64,linux/arm64/v8 -o type=image -t briansimulator/brian -f docker/Dockerfile .
# docker run -it --init --rm -p 8888:8888 briansimulator/brian

ARG BASE_IMAGE_TAG=3.12-slim-bookworm
FROM python:${BASE_IMAGE_TAG}

LABEL maintainer="Ben Evans <B.D.Evans@sussex.ac.uk>" \
org.opencontainers.image.vendor="The Brian Development Team" \
org.opencontainers.image.licenses="CeCILL 2.1" \
org.opencontainers.image.title="Brian Docker Image" \
org.opencontainers.image.description="Docker image for Brian - a free, open source simulator for spiking neural networks" \
org.opencontainers.image.homepage="https://briansimulator.org" \
org.opencontainers.image.url="https://hub.docker.com/r/briansimulator/brian" \
org.opencontainers.image.source="https://github.com/brian-team/brian2" \
org.opencontainers.image.documentation="https://brian2.readthedocs.io/"

# Install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
g++ \
git \
libgsl-dev \
sudo \
&& rm -rf /var/lib/apt/lists/*

# Copy wheels into the image
COPY dist /tmp/dist

# Install Brian2 and recommended packages
RUN python -m pip install --no-cache-dir --only-binary=:all: \
scipy \
matplotlib \
jupyterlab \
pytest \
pytest-xdist \
&& python -m pip install /tmp/dist/Brian2*_$(uname -m).whl brian2tools \
&& rm -rf /tmp/dist

# Create a non-root user
ARG USER="monty" \
GROUP="monty" \
PASSWORD="monty"
RUN groupadd ${GROUP} && \
useradd -ms /bin/bash -g ${GROUP} -G sudo ${USER} && \
echo "${USER}:${PASSWORD}" | chpasswd
ENV HOME="/home/${USER}"
RUN chown -R ${USER}:${USER} ${HOME}
USER ${USER}

# Copy tutorial notebooks and example scripts to home directory
WORKDIR ${HOME}
RUN git clone https://github.com/brian-team/brian2.git \
&& mv brian2/examples examples \
&& mv brian2/tutorials tutorials \
&& chmod -R +x tutorials \
&& chmod -R +x examples \
&& find . -name '*.ipynb' -exec jupyter trust {} \; \
&& rm -rf brian2

EXPOSE 8888
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--no-browser"]
72 changes: 72 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Docker instructions

## Run docker image
To run the docker image, you can use

`docker run -it --init -p 8888:8888 briansimulator/brian`

This will start a JupyterLab instance inside the container, which you can access from your local browser via the last link
printed to the terminal (`http://127.0.0.1:8888/lab?token=…`)

Or if you prefer a simple `bash` terminal rather than JupyterLab:

`docker run -it --init briansimulator/brian /bin/bash`

Or to run the tests:

`docker run -it --init --rm briansimulator/brian python -c 'import brian2; brian2.test(test_standalone="cpp_standalone")'`

## Build docker image
To build the docker image locally, follow the following instructions:

### Build package wheel
You need to first build the package wheel(s) for linux using [`cibuildwheel`](https://cibuildwheel.readthedocs.io). Install it via
`pip install cibuildwheel` (or use `pipx`)

#### Build wheel for local architecture
Run `cibuildwheel` to build a package for your architecture:
```
export CIBW_BUILD='cp312-manylinux*'
cibuildwheel --platform linux --arch auto64 --output-dir dist
```

#### Build multi-arch wheel
First install `qemu` for cross-compilation, e.g. on Debian/Ubuntu:

`sudo apt install qemu-user-static`

Then, run
```
export CIBW_BUILD='cp312-manylinux*'
cibuildwheel --platform linux --arch auto64,aarch64 --output-dir dist
```

### Build docker image

You can then build the docker image via

`docker build -t briansimulator/brian -f docker/Dockerfile .`

Alternatively, to test multi-architecture builds and push to docker hub, first login:

`docker login`

Create a new builder that uses the docker-container driver (only needed once):
```
docker buildx create \
--name container \
--driver=docker-container \
default
```
Then execute:

```
docker buildx build \
--builder=container \
--push \
--platform linux/amd64,linux/arm64/v8 \
-o type=image \
-t briansimulator/brian \
-f docker/Dockerfile \
.
```

0 comments on commit 9872c74

Please sign in to comment.