├── user.Dockerfile ├── apt_setup.sh ├── README.md └── .github └── workflows └── build_ghcr.yaml /user.Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=ubuntu 2 | ARG UBUNTU_TAG=jammy 3 | FROM ${BASE_IMAGE}:${UBUNTU_TAG} AS base 4 | ARG BIOC_VERSION=3.19 5 | USER root 6 | COPY apt_setup.sh /bioc_scripts/apt_setup.sh 7 | RUN bash /bioc_scripts/apt_setup.sh $BIOC_VERSION 8 | -------------------------------------------------------------------------------- /apt_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | BIOC_VERSION=${1:-"3.19"} 3 | export UBUNTU_CODENAME=$(grep '^VERSION_CODENAME=' /etc/os-release | cut -d= -f2) 4 | apt update -qq 5 | apt install -y --no-install-recommends curl ca-certificates 6 | curl -O https://raw.githubusercontent.com/eddelbuettel/r2u/master/inst/scripts/add_cranapt_$UBUNTU_CODENAME.sh 7 | bash add_cranapt_$UBUNTU_CODENAME.sh 8 | rm add_cranapt_$UBUNTU_CODENAME.sh 9 | curl -o /etc/apt/trusted.gpg.d/bioc2u_key.asc https://mghp.osn.xsede.org/bir190004-bucket01/bioc2u/bioc2u_key.asc 10 | echo "deb https://mghp.osn.xsede.org/bir190004-bucket01/bioc2u/ $UBUNTU_CODENAME release" | tee -a /etc/apt/sources.list.d/bioc2u.list > /dev/null 11 | echo "Package: *" > /etc/apt/preferences.d/prefbioc2u 12 | echo "Pin: origin mghp.osn.xsede.org" >> /etc/apt/preferences.d/prefbioc2u 13 | echo "Pin-Priority: 800" >> /etc/apt/preferences.d/prefbioc2u 14 | apt update -qq 15 | DEBIAN_FRONTEND=noninteractive apt install -y r-base-core r-cran-biocmanager r-cran-bspm 16 | Rscript -e "BiocManager::install(version='$BIOC_VERSION', update=TRUE, ask=FALSE)" 17 | Rscript -e "BiocManager::install(c('devtools'))" 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Bioc2u (beta): Ubuntu Binaries for Bioconductor packages 2 | 3 | This project aims to extend [r2u][r2u], 4 | in hopes of providing a repository of Ubuntu binaries via `apt` for all Bioconductor packages. 5 | 6 | **Bioc2u is currently available for Ubuntu Jammy (22.04) and Noble (24.04) and is still in beta development.** 7 | 8 | ### Container Images 9 | 10 | We provide two types of container images for different use cases: 11 | 12 | - **User containers** (`bioc2u-user`): Minimal environment built on `ubuntu:jammy` or `ubuntu:noble` with R, BiocManager, and bioc2u/r2u repositories pre-configured 13 | - **Builder containers** (`bioc2u-builder`): Extended environment based on [r2u][r2u] containers with additional build tools for package development 14 | 15 | #### Available Tags 16 | 17 | Container images are available with multiple tagging formats: 18 | 19 | - **Ubuntu version**: `jammy`, `noble` 20 | - **Ubuntu version with R**: `jammy-r-4.4.2`, `noble-r-4.4.2` 21 | - **Ubuntu version with Bioconductor**: `jammy-bioc-3.21`, `noble-bioc-3.21` 22 | - **Full version**: `jammy-bioc-3.21-r-4.5.1`, `noble-bioc-3.21-r-4.5.0` 23 | - **OS version**: `22.04`, `24.04` (corresponding to Ubuntu versions) 24 | - **OS version with R/Bioc**: eg `22.04-r-4.5.1`, `24.04-bioc-3.21`, `24.04-bioc-3.21-r-4.5.1` 25 | 26 | #### Version Strategy and Backward Compatibility 27 | 28 | This design allows for old versions to remain accessible by default, under the full tags. For example: when R 4.5.1 comes out, the containers tagged simply `jammy-bioc-3.21` become `jammy-bioc-3.21-r-4.5.1` but the previous container remains accessible under `jammy-bioc-3.21-r-4.5.0`. When containers get rebuilt within the same version, old containers can still be used via their hash in the `ghcr.io/bioconductor/bioc2u-user@sha256:[hash]` format. 29 | 30 | This ensures reproducibility by allowing users to pin to specific versions or use the latest versions through the shorter tag names. 31 | 32 | ### Getting started 33 | 34 | #### Using Docker containers 35 | 36 | For a minimal R environment with bioc2u pre-configured: 37 | ```bash 38 | # Ubuntu Jammy (22.04) - latest versions 39 | docker run --rm -it ghcr.io/bioconductor/bioc2u-user:jammy 40 | 41 | # Ubuntu Noble (24.04) - latest versions 42 | docker run --rm -it ghcr.io/bioconductor/bioc2u-user:noble 43 | 44 | # Specific Bioconductor/R versions for reproducibility 45 | docker run --rm -it ghcr.io/bioconductor/bioc2u-user:jammy-bioc-3.21-r-4.5.0 46 | ``` 47 | 48 | For package development with build tools: 49 | ```bash 50 | # Builder container with development tools 51 | docker run --rm -it ghcr.io/bioconductor/bioc2u-builder:jammy 52 | ``` 53 | 54 | #### Local installation 55 | 56 | In an Ubuntu environment (eg in containers based on `ubuntu:jammy` and `ubuntu:noble`), you may use the [`apt_setup.sh`](https://github.com/Bioconductor/bioc2u/blob/devel/apt_setup.sh) 57 | script which will set up the Bioc2u `apt` repository and install R, and basic packages such as BiocManager. This script leverages the [r2u][r2u] setup scripts from the [r2u repository](https://github.com/eddelbuettel/r2u/blob/master/inst/scripts/) to configure the CRAN apt repository. 58 | 59 | ```bash 60 | # Install curl if missing 61 | apt update -qq 62 | apt install -y --no-install-recommends curl ca-certificates 63 | # Run apt script with specific Bioconductor version 64 | curl https://raw.githubusercontent.com/Bioconductor/bioc2u/devel/apt_setup.sh | sudo bash -s 3.21 65 | ``` 66 | 67 | After the initial setup, you may use `apt` or `install.packages()` freely. Installing packages through `apt` can be done in any shell session, by using the 68 | `r-bioc-` prefix and the all-lowercase name of the package, eg `apt install -y r-bioc-genomicranges`. You may alternatively continue to use R traditionally, as you would in any other environment, and observe the speedup resulting from R using the `apt` package manager under the hood. 69 | 70 | ### Automated Builds 71 | 72 | Container images are automatically built every 2 days and pushed to GitHub Container Registry (GHCR). The build process: 73 | 74 | - Builds both user and builder containers for Ubuntu Jammy and Noble 75 | - Supports linux/amd64 platform 76 | - Automatically extracts R and OS version information for comprehensive tagging 77 | - Creates multi-platform manifests with various tag combinations 78 | 79 | ### Acknowledgments 80 | 81 | This project builds upon and extends the [r2u][r2u] project. Our `apt_setup.sh` script directly uses the [r2u setup scripts](https://github.com/eddelbuettel/r2u/blob/master/inst/scripts/) to configure the CRAN apt repository, and our builder containers are based on the [r2u][r2u] containers. 82 | 83 | [r2u]: https://eddelbuettel.github.io/r2u 84 | -------------------------------------------------------------------------------- /.github/workflows/build_ghcr.yaml: -------------------------------------------------------------------------------- 1 | name: Build Container Images 2 | on: 3 | workflow_dispatch: 4 | push: 5 | paths: 6 | - "**/Dockerfile" 7 | schedule: 8 | - cron: '0 0 */2 * *' 9 | # Avoids Github UI bugs https://github.com/orgs/community/discussions/45969 10 | env: 11 | BUILDX_NO_DEFAULT_ATTESTATIONS: 1 12 | jobs: 13 | ghcrbuild: 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | include: 18 | - ubuntu: jammy 19 | platform: linux/amd64 20 | runner: ubuntu-latest 21 | type: builder 22 | biocversion: '3.22' 23 | - ubuntu: jammy 24 | platform: linux/amd64 25 | runner: ubuntu-latest 26 | type: user 27 | biocversion: '3.22' 28 | - ubuntu: noble 29 | platform: linux/amd64 30 | runner: ubuntu-latest 31 | type: builder 32 | biocversion: '3.22' 33 | - ubuntu: noble 34 | platform: linux/amd64 35 | runner: ubuntu-latest 36 | type: user 37 | biocversion: '3.22' 38 | - ubuntu: noble 39 | platform: linux/arm64 40 | runner: ubuntu-latest-arm64 41 | type: builder 42 | biocversion: '3.22' 43 | - ubuntu: noble 44 | platform: linux/arm64 45 | runner: ubuntu-latest-arm64 46 | type: user 47 | biocversion: '3.22' 48 | 49 | name: Build ${{ matrix.ubuntu }} (${{ matrix.platform }}) ${{ matrix.type }} for GHCR 50 | runs-on: ${{ matrix.runner }} 51 | steps: 52 | - name: Checkout 53 | uses: actions/checkout@v4 54 | 55 | - name: Extract metadata for container image 56 | id: meta 57 | uses: docker/metadata-action@v5 58 | with: 59 | images: ghcr.io/${{ github.repository }}-${{ matrix.type }} 60 | tags: | 61 | type=raw,value=${{ matrix.ubuntu }} 62 | 63 | - name: Extract container name without tag 64 | id: vars 65 | run: | 66 | echo container=$(echo '${{ steps.meta.outputs.tags }}' | awk -F':' '{print $1}') >> $GITHUB_OUTPUT 67 | 68 | - name: Set up Docker Buildx 69 | uses: docker/setup-buildx-action@v3 70 | 71 | - name: Login to GHCR 72 | uses: docker/login-action@v3 73 | with: 74 | registry: ghcr.io 75 | username: ${{ github.repository_owner }} 76 | password: ${{ secrets.GITHUB_TOKEN }} 77 | 78 | - name: Build and push container image to ghcr 79 | id: build 80 | uses: docker/build-push-action@v6 81 | with: 82 | build-args: | 83 | UBUNTU_TAG=${{matrix.ubuntu}} 84 | BIOC_VERSION=${{matrix.biocversion}} 85 | file: ${{ matrix.type }}.Dockerfile 86 | labels: ${{ steps.meta.outputs.labels }} 87 | outputs: type=image,name=${{ steps.vars.outputs.container }},push-by-digest=true,name-canonical=true,push=true 88 | platforms: ${{matrix.platform}} 89 | provenance: false 90 | 91 | - name: Prepare Dockerfile to extract R version with emulator 92 | run: | 93 | mkdir -p ${{matrix.ubuntu}}-${{matrix.platform}} 94 | cat << "EOF" > ${{matrix.ubuntu}}-${{matrix.platform}}-r.Dockerfile 95 | FROM ${{ steps.vars.outputs.container }}@${{ steps.build.outputs.digest }} as extract 96 | RUN mkdir /r2utmp && R --version > /r2utmp/rver && cat /etc/os-release > /r2utmp/os-release 97 | FROM scratch as export 98 | COPY --from=extract /r2utmp/* / 99 | EOF 100 | 101 | - name: Build and push container image to ghcr 102 | uses: docker/build-push-action@v6 103 | with: 104 | file: ${{matrix.ubuntu}}-${{matrix.platform}}-r.Dockerfile 105 | context: . 106 | push: false 107 | load: false 108 | provenance: false 109 | outputs: type=tar,dest=${{matrix.ubuntu}}-${{matrix.platform}}/r.tar 110 | tags: ${{ steps.meta.outputs.tags }}-r 111 | platforms: ${{ matrix.platform }} 112 | 113 | - name: Extract rversion 114 | id: versions 115 | run: | 116 | cd ${{matrix.ubuntu}}-${{matrix.platform}} 117 | tar -xvf r.tar 118 | echo rver=$(cat rver | awk 'NR==1{print $3}') >> $GITHUB_OUTPUT 119 | echo osver=$(awk -F= '/VERSION_ID/ {gsub("\"", "", $2); print $2}' os-release) >> $GITHUB_OUTPUT 120 | 121 | - name: Set platform name for artifact 122 | id: platform 123 | run: echo "name=$(echo '${{matrix.platform}}' | sed 's/\//-/g')" >> $GITHUB_OUTPUT 124 | 125 | - name: Export digest by ubuntu, r, and bioc versions 126 | run: | 127 | digest="${{ steps.build.outputs.digest }}" 128 | mkdir -p /tmp/digests/${{matrix.type}}/${{matrix.ubuntu}} 129 | touch "/tmp/digests/${{matrix.type}}/${{matrix.ubuntu}}/${digest#sha256:}" 130 | mkdir -p /tmp/digests/${{matrix.type}}/${{matrix.ubuntu}}-r-${{steps.versions.outputs.rver}} 131 | touch "/tmp/digests/${{matrix.type}}/${{matrix.ubuntu}}-r-${{steps.versions.outputs.rver}}/${digest#sha256:}" 132 | mkdir -p /tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}} 133 | touch "/tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}}/${digest#sha256:}" 134 | mkdir -p /tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}}-r-${{steps.versions.outputs.rver}} 135 | touch "/tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}}-r-${{steps.versions.outputs.rver}}/${digest#sha256:}" 136 | 137 | mkdir -p /tmp/digests/${{matrix.type}}/${{matrix.ubuntu}}-bioc-${{matrix.biocversion}} 138 | touch "/tmp/digests/${{matrix.type}}/${{matrix.ubuntu}}-bioc-${{matrix.biocversion}}/${digest#sha256:}" 139 | mkdir -p /tmp/digests/${{matrix.type}}/${{matrix.ubuntu}}-bioc-${{matrix.biocversion}}-r-${{steps.versions.outputs.rver}} 140 | touch "/tmp/digests/${{matrix.type}}/${{matrix.ubuntu}}-bioc-${{matrix.biocversion}}-r-${{steps.versions.outputs.rver}}/${digest#sha256:}" 141 | mkdir -p /tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}}-bioc-${{matrix.biocversion}} 142 | touch "/tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}}-bioc-${{matrix.biocversion}}/${digest#sha256:}" 143 | mkdir -p /tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}}-bioc-${{matrix.biocversion}}-r-${{steps.versions.outputs.rver}} 144 | touch "/tmp/digests/${{matrix.type}}/${{steps.versions.outputs.osver}}-bioc-${{matrix.biocversion}}-r-${{steps.versions.outputs.rver}}/${digest#sha256:}" 145 | 146 | 147 | - name: Upload digests 148 | uses: actions/upload-artifact@v4 149 | with: 150 | name: bioc2udigests-${{matrix.ubuntu}}-${{matrix.type}}-${{steps.platform.outputs.name}}-${{ github.run_id }} 151 | path: /tmp/digests/** 152 | if-no-files-found: error 153 | retention-days: 1 154 | 155 | merge: 156 | runs-on: ubuntu-latest 157 | needs: 158 | - ghcrbuild 159 | if: always() 160 | strategy: 161 | fail-fast: false 162 | matrix: 163 | ubuntu: [noble, jammy] 164 | type: [builder, user] 165 | steps: 166 | - name: Download amd64 digests 167 | uses: actions/download-artifact@v4 168 | with: 169 | name: bioc2udigests-${{matrix.ubuntu}}-${{matrix.type}}-linux-amd64-${{ github.run_id }} 170 | path: /tmp/digests 171 | 172 | - name: Download arm64 digests 173 | uses: actions/download-artifact@v4 174 | with: 175 | name: bioc2udigests-${{matrix.ubuntu}}-${{matrix.type}}-linux-arm64-${{ github.run_id }} 176 | path: /tmp/digests 177 | continue-on-error: true 178 | if: matrix.ubuntu == 'noble' 179 | 180 | - name: Set up Docker Buildx 181 | uses: docker/setup-buildx-action@v3 182 | 183 | - name: Login to GHCR 184 | uses: docker/login-action@v3 185 | with: 186 | registry: ghcr.io 187 | username: ${{ github.repository_owner }} 188 | password: ${{ secrets.GITHUB_TOKEN }} 189 | 190 | - name: Extract metadata for container image 191 | id: meta 192 | uses: docker/metadata-action@v5 193 | with: 194 | images: ghcr.io/${{ github.repository }}-${{ matrix.type }} 195 | tags: | 196 | type=raw,value=${{ matrix.ubuntu }} 197 | 198 | - name: Extract container name without tag 199 | id: vars 200 | run: | 201 | echo container=$(echo '${{ steps.meta.outputs.tags }}' | awk -F':' '{print $1}') >> $GITHUB_OUTPUT 202 | 203 | - name: Create manifest list and push 204 | run: | 205 | cd /tmp/digests/${{matrix.type}} 206 | ls --hide=digestdirs > digestdirs 207 | cat digestdirs | xargs -i bash -c 'docker buildx imagetools create -t ${{steps.vars.outputs.container}}:{} $(for f in {}/*; do basename "$f"; done | xargs printf "${{steps.vars.outputs.container}}@sha256:%s ")' 208 | --------------------------------------------------------------------------------