diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..cd302faf8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.github +docs +.DS_Store +**/__pycache__/ +**/*.py[cod] +/bin/ +/build*/ +/spades_test/ +*.tar.gz diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 000000000..6b1de6e83 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,89 @@ +name: SPAdes container tests + +on: + workflow_dispatch: + push: + branches: + - master + - main + - next + tags: + - '*' + paths-ignore: + - 'docs/**' + - 'mkdocs.yml' + pull_request: + paths-ignore: + - 'docs/**' + - 'mkdocs.yml' + +permissions: + contents: read + +concurrency: + group: container-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + container: + name: Container (${{ matrix.platform }}) + runs-on: ${{ matrix.runner }} + timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-24.04 + platform: linux/amd64 + architecture: amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + architecture: arm64 + + steps: + - name: Check out SPAdes + uses: actions/checkout@v7 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Build container + uses: docker/build-push-action@v7 + with: + context: . + platforms: ${{ matrix.platform }} + load: true + push: false + tags: spades:ci-${{ matrix.architecture }} + cache-from: type=gha,scope=spades-container-${{ matrix.architecture }} + cache-to: type=gha,mode=max,scope=spades-container-${{ matrix.architecture }} + + - name: Check runtime environment + env: + IMAGE_TAG: spades:ci-${{ matrix.architecture }} + run: | + set -euo pipefail + + expected_version="$(tr -d '\n' < VERSION)" + actual_version="$(docker run --rm "${IMAGE_TAG}" spades.py --version)" + grep -F "${expected_version}" <<< "${actual_version}" + + docker run --rm "${IMAGE_TAG}" bash -euc ' + test "$(id -u)" -ne 0 + touch /work/write-test + rm /work/write-test + command -v spades.py + command -v pigz + ! command -v cmake + ! command -v g++ + pigz --version + ' + + - name: Run SPAdes smoke test + env: + IMAGE_TAG: spades:ci-${{ matrix.architecture }} + run: | + docker run --rm "${IMAGE_TAG}" bash -euc ' + spades.py -t 4 --test + grep -F "Compressing corrected reads (with pigz)" spades_test/spades.log + ' diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..bfbc1ccd9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,54 @@ +FROM ubuntu:24.04 AS builder + +ARG BUILD_JOBS=8 +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update \ + && apt-get install --yes --no-install-recommends \ + build-essential \ + cmake \ + libbz2-dev \ + python3 \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /src +COPY . . + +RUN PREFIX=/opt/spades ./spades_compile.sh \ + -j "${BUILD_JOBS}" \ + -DSPADES_ENABLE_PROJECTS=release \ + -DSPADES_USE_NCBISDK=ON + + +FROM ubuntu:24.04 + +ARG DEBIAN_FRONTEND=noninteractive + +LABEL org.opencontainers.image.title="SPAdes" \ + org.opencontainers.image.description="Genome assembler for isolate, single-cell, metagenomic, and transcriptomic sequencing data" \ + org.opencontainers.image.url="https://ablab.github.io/spades/" \ + org.opencontainers.image.source="https://github.com/ablab/spades" \ + org.opencontainers.image.licenses="GPL-2.0-only" + +RUN apt-get update \ + && apt-get install --yes --no-install-recommends \ + ca-certificates \ + libbz2-1.0 \ + libgomp1 \ + pigz \ + python3 \ + zlib1g \ + && groupadd --gid 1000 spades \ + && useradd --uid 1000 --gid spades --create-home --shell /bin/bash spades \ + && install --directory --owner spades --group spades /work \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /opt/spades /opt/spades + +ENV PATH="/opt/spades/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + +WORKDIR /work +USER spades + +CMD ["/bin/bash"]