diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8255b60 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: build + +on: + push: + branches: [ main ] + # Run when container or environment is changed + paths: + - 'jukes-micromamba/Dockerfile' + # Allows workflow to be manually triggered + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: 'Checkout' + uses: actions/checkout@main + + - name: 'Login to GitHub Container Registry' + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{github.actor}} + password: ${{secrets.GITHUB_TOKEN}} + + - name: 'Build Inventory Image' + run: | + docker build ./jukes-micromamba/ --tag ghcr.io/bsurc/jukes-micromamba:latest + docker push ghcr.io/bsurc/jukes-micromamba:latest diff --git a/.gitignore b/.gitignore index 94f373d..11abff0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,10 @@ # alpine minirootfs *alpine-minirootfs-*.tar.gz* + +# tar and zip files +*.tar* +*.zip + +# guix to squashfs output +*guix.out diff --git a/README.md b/README.md index 8c9b47c..9f5d764 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,15 @@ To add the testing repository to `apk` after switching to `edge`: ### R +R packages can be difficult to build, especially with dependencies on various +systems. Posit (creators of RStudio) have ppa repositories to help with some of +these dependencies, and handles them especially well in conjuction with RStudio +server. See the `r-spatial` build for an example. + +Another option that appears to work well is using `guix` to create a squashfs +image directly. There is an HPC/cran channel for guix that mirrors R packages. +See the `peregrine` build for an example. + #### Issues on Alpine If you are getting `iconv` translation errors, set `LC_ALL=en_US.UTF-8`. @@ -47,3 +56,33 @@ text libraries: Also, the `linux-headers` package is frequently needed for packages: apk add linux-headers + +### GUIX + +In order to use a `guix` based build, the user should test the environment using +`guix shell`, then dump the channel configuration to a `channels.scm` file +using: + + guix describe --format=channels > channels.scm + +Then `guix time-machine` to build the environment/squashfs. The full process +may look like: + + $ # optional + $ guix pull + $ guix shell bash go + $ # test environment... + $ guix shell --export-manifest shell bash go > manifest.scm + $ # export the current channel definition + $ guix describe --format=channels > channels.scm + $ # test + $ guix time-machine -C channels.scm -- shell -m manifest + $ # build squashfs + $ guix time-machine -C channels.scm -- pack -f squashfs -m manifest.scm + +To build a container from the squashfs, simply use the squashfs as the source: + + appatiner build --fakeroot x.sif /gnu/store/${guixhash}.squashfs + +For simple examples of adding metadata to the container, see +`peregrine/Makefile` diff --git a/codeserver/codeserver.def b/codeserver/codeserver.def new file mode 100644 index 0000000..9a64c02 --- /dev/null +++ b/codeserver/codeserver.def @@ -0,0 +1,14 @@ +bootstrap: docker +from: debian:bookworm + +%environment + export LC_ALL=C + export PATH=/opt/code-server-4.22.1-linux-amd64/bin:$PATH + +%post + apt update + apt install -y curl tar + cd /opt + export VERSION=4.22.1 + curl -fL https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-linux-amd64.tar.gz | \ + tar -xz -C /opt diff --git a/jukes-micromamba/Dockerfile b/jukes-micromamba/Dockerfile new file mode 100644 index 0000000..4c6ee2a --- /dev/null +++ b/jukes-micromamba/Dockerfile @@ -0,0 +1,18 @@ +FROM mambaorg/micromamba:1.5.8-bookworm-slim + +USER root +RUN apt update && \ + apt install -y libgl1 && \ + apt clean +USER $MAMBA_USER +RUN micromamba create -n cautorift -c conda-forge python autorift=1.1.0 \ + notebook matplotlib pandas opencv rasterio && \ + micromamba clean --all --yes +RUN export SITEPACKAGES=`micromamba run -n cautorift python -m site | \ + grep -m 1 site-packages | sed "s/[,']//g"` && \ + export AUTORIFT=${SITEPACKAGES}/autoRIFT/autoRIFT.py && \ + sed -i 's/np.bool/bool/g' $AUTORIFT && \ + sed -i 's/np.int/int/g' $AUTORIFT + +ENV MAMBA_DOCKERFILE_ACTIVATE=1 +ENV ENV_NAME=cautorift diff --git a/jukes-micromamba/micromamba.def b/jukes-micromamba/micromamba.def new file mode 100644 index 0000000..6f53220 --- /dev/null +++ b/jukes-micromamba/micromamba.def @@ -0,0 +1,18 @@ +bootstrap: docker +from: mambaorg/micromamba:1.5.8-bookworm-slim + +%environment + export MAMBA_DOCKERFILE_ACTIVATE=1 + export ENV_NAME=cautorift + +%post + apt update && apt install -y libgl1 libegl1 libopengl0 + apt clean + micromamba create -n cautorift -c conda-forge python autorift=1.1.0 \ + notebook matplotlib pandas opencv rasterio + micromamba clean --all --yes + export SITEPACKAGES=`micromamba run -n cautorift python -m site \ + | grep -m 1 site-packages | sed "s/[,']//g"` #' + export AUTORIFT=${SITEPACKAGES}/autoRIFT/autoRIFT.py + sed -i 's/np.bool/bool/g' $AUTORIFT + sed -i 's/np.int/int/g' $AUTORIFT diff --git a/peregrine/Makefile b/peregrine/Makefile index e9a0072..302ef53 100644 --- a/peregrine/Makefile +++ b/peregrine/Makefile @@ -1,11 +1,11 @@ GIT_REV = $(shell git rev-parse --short=16 HEAD) -peregrine.sif: peregrine.def peregrine-guix.out - apptainer build -F --fakeroot --build-arg GIT_REV=$(GIT_REV) --build-arg GUIX_SQUASHFS=$$(tail -1 peregrine-guix.out) peregrine.sif peregrine.def +peregrine.sif: peregrine.def guix.out + apptainer build -F --fakeroot --build-arg GIT_REV=$(GIT_REV) --build-arg GUIX_SQUASHFS=$$(tail -1 guix.out) peregrine.sif peregrine.def -peregrine-guix.out: channels.scm manifest.scm - guix time-machine -C channels.scm -- pack -f squashfs -m manifest.scm | tee peregrine-guix.out +guix.out: channels.scm manifest.scm + guix time-machine -C channels.scm -- pack -f squashfs -m manifest.scm | tee guix.out .PHONY: clean clean: - rm -f *.sif - rm -f peregrine-guix.out + rm -f peregrine.sif + rm -f guix.out diff --git a/r-mollyastell/Makefile b/r-mollyastell/Makefile new file mode 100644 index 0000000..7307a73 --- /dev/null +++ b/r-mollyastell/Makefile @@ -0,0 +1,11 @@ +GIT_REV = $(shell git rev-parse --short=16 HEAD) +r-mollyastell.sif: r-mollyastell.def r-mollyastell-guix.out + apptainer build -F --fakeroot --build-arg GIT_REV=$(GIT_REV) --build-arg GUIX_SQUASHFS=$$(tail -1 r-mollyastell-guix.out) r-mollyastell.sif r-mollyastell.def + +r-mollyastell-guix.out: channels.scm manifest.scm + guix time-machine -C channels.scm -- pack -f squashfs -m manifest.scm | tee r-mollyastell-guix.out + +.PHONY: clean +clean: + rm -f *.sif + rm -f r-mollyastell-guix.out diff --git a/r-mollyastell/channels.scm b/r-mollyastell/channels.scm new file mode 100644 index 0000000..1020dfe --- /dev/null +++ b/r-mollyastell/channels.scm @@ -0,0 +1,28 @@ +(list (channel + (name 'guix-cran) + (url "https://github.com/guix-science/guix-cran.git") + (branch "master") + (commit + "466d876bcc15a1a6c2053eb150548f7f471f75b7")) + (channel + (name 'guix-science) + (url "https://github.com/guix-science/guix-science.git") + (branch "master") + (commit + "7c6ca7e1c19c92bfe5e6add688662e08b07db2bf") + (introduction + (make-channel-introduction + "b1fe5aaff3ab48e798a4cce02f0212bc91f423dc" + (openpgp-fingerprint + "CA4F 8CF4 37D7 478F DA05 5FD4 4213 7701 1A37 8446")))) + (channel + (name 'guix) + (url "https://git.savannah.gnu.org/git/guix.git") + (branch "master") + (commit + "d616e85ac8a380d5126da3184f7037c20866c884") + (introduction + (make-channel-introduction + "9edb3f66fd807b096b48283debdcddccfea34bad" + (openpgp-fingerprint + "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) diff --git a/r-mollyastell/manifest.scm b/r-mollyastell/manifest.scm new file mode 100644 index 0000000..e69ac3e --- /dev/null +++ b/r-mollyastell/manifest.scm @@ -0,0 +1,41 @@ +(specifications->manifest (list + ;; base packages + "bash-minimal" + "glibc-locales" + "nss-certs" + ;; Common command line tools lest the container is too empty. + "coreutils" + "grep" + "which" + "wget" + "sed" + ;; Toolchain and common libraries for "install.packages" + "gcc-toolchain@10" + "gfortran-toolchain" + "gawk" + "tar" + "gzip" + "unzip" + "make" + "cmake" + "pkg-config" + "cairo" + "libxt" + "openssl" + "curl" + "zlib" + ;; gdal + "gdal" + ;; r stuff + "r" + "r-tidyverse" + "r-mgcv" + "r-plotly" + "r-patchwork" + "r-lubridate" + "r-iranges" + "r-data-table" + "r-brms" + "r-tidybayes" + "r-broom" + )) diff --git a/r-mollyastell/r-mollyastell-guix.out b/r-mollyastell/r-mollyastell-guix.out new file mode 100644 index 0000000..7c55dca --- /dev/null +++ b/r-mollyastell/r-mollyastell-guix.out @@ -0,0 +1 @@ +/gnu/store/ql301y556rlgyg40p6adwsxm60m68ya2-bash-minimal-glibc-locales-nss-certs-squashfs-pack.gz.squashfs diff --git a/r-mollyastell/r-mollyastell.def b/r-mollyastell/r-mollyastell.def new file mode 100644 index 0000000..1a6fd87 --- /dev/null +++ b/r-mollyastell/r-mollyastell.def @@ -0,0 +1,6 @@ +Bootstrap: localimage +From: {{GUIX_SQUASHFS}} + +%labels +author Kyle Shannon +github.com/bsurc/container git rev={{GIT_REV}} diff --git a/rstudio/Dockerfile b/r-spatial/Dockerfile similarity index 100% rename from rstudio/Dockerfile rename to r-spatial/Dockerfile diff --git a/rstudio/pword.tcl b/r-spatial/pword.tcl similarity index 100% rename from rstudio/pword.tcl rename to r-spatial/pword.tcl diff --git a/rstudio-server/rstudio.def b/rstudio-server/rstudio.def new file mode 100644 index 0000000..4d7001b --- /dev/null +++ b/rstudio-server/rstudio.def @@ -0,0 +1,22 @@ +bootstrap: docker +From: ubuntu:jammy + +%environment + export LC_ALL=C + export PATH=/usr/lib/rstudio-server/bin:$PATH + +%post + export LC_ALL=C + + apt update + DEBIAN_FRONTEND=NONINTERACTIVE apt install -y \ + gdebi-core \ + libreadline-dev \ + wget + apt clean all + cd /lib/x86_64-linux-gnu/ + ln -s libreadline.so.8 libreadline.so.6 + + wget https://download2.rstudio.org/server/jammy/amd64/rstudio-server-2023.12.1-402-amd64.deb + gdebi --n rstudio-server-2023.12.1-402-amd64.deb + rm rstudio-server-2023.12.1-402-amd64.deb diff --git a/rstudio/Makefile b/rstudio/Makefile new file mode 100644 index 0000000..66c18fb --- /dev/null +++ b/rstudio/Makefile @@ -0,0 +1,11 @@ +GIT_REV = $(shell git rev-parse --short=16 HEAD) +rstudio.sif: rstudio.def guix.out + apptainer build -F --fakeroot --build-arg GIT_REV=$(GIT_REV) --build-arg GUIX_SQUASHFS=$$(tail -1 guix.out) rstudio.sif rstudio.def + +guix.out: channels.scm manifest.scm + guix time-machine -C channels.scm -- pack -f squashfs -m manifest.scm | tee guix.out + +.PHONY: clean +clean: + rm -f rstudio.sif + rm -f guix.out diff --git a/rstudio/channels.scm b/rstudio/channels.scm new file mode 100644 index 0000000..1020dfe --- /dev/null +++ b/rstudio/channels.scm @@ -0,0 +1,28 @@ +(list (channel + (name 'guix-cran) + (url "https://github.com/guix-science/guix-cran.git") + (branch "master") + (commit + "466d876bcc15a1a6c2053eb150548f7f471f75b7")) + (channel + (name 'guix-science) + (url "https://github.com/guix-science/guix-science.git") + (branch "master") + (commit + "7c6ca7e1c19c92bfe5e6add688662e08b07db2bf") + (introduction + (make-channel-introduction + "b1fe5aaff3ab48e798a4cce02f0212bc91f423dc" + (openpgp-fingerprint + "CA4F 8CF4 37D7 478F DA05 5FD4 4213 7701 1A37 8446")))) + (channel + (name 'guix) + (url "https://git.savannah.gnu.org/git/guix.git") + (branch "master") + (commit + "d616e85ac8a380d5126da3184f7037c20866c884") + (introduction + (make-channel-introduction + "9edb3f66fd807b096b48283debdcddccfea34bad" + (openpgp-fingerprint + "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) diff --git a/rstudio/manifest.scm b/rstudio/manifest.scm new file mode 100644 index 0000000..bf757f5 --- /dev/null +++ b/rstudio/manifest.scm @@ -0,0 +1,42 @@ +(specifications->manifest (list + ;; base packages + ;;"bash-minimal" + "bash" + "bash-completion" + "glibc-locales" + "nss-certs" + ;; Common command line tools lest the container is too empty. + "coreutils" + "curl" + "grep" + "sed" + "wget" + "which" + ;; Toolchain and common libraries for "install.packages" + "cairo" + "cmake" + "gcc-toolchain@10" + "gfortran-toolchain" + "gawk" + "gzip" + "libxt" + "make" + "openssl" + "pkg-config" + "r" + "rstudio" + "rstudio-server" + "tar" + "tcl" + "unzip" + "zlib" + ;; GIS/Geospatial crap + "gdal" + "libspatialite" + "proj" + ;; common dependencies for r + "fontconfig" + "fribidi" + "harfbuzz" + "libxml2" + )) diff --git a/rstudio/rstudio.def b/rstudio/rstudio.def new file mode 100644 index 0000000..1a6fd87 --- /dev/null +++ b/rstudio/rstudio.def @@ -0,0 +1,6 @@ +Bootstrap: localimage +From: {{GUIX_SQUASHFS}} + +%labels +author Kyle Shannon +github.com/bsurc/container git rev={{GIT_REV}}