From faf323f9396e760a270b25339023a1b7e66bb96d Mon Sep 17 00:00:00 2001 From: robinlovelace Date: Sun, 7 Jun 2026 16:09:52 +0100 Subject: [PATCH 1/6] revert: remove arf (Alternative R Frontend) from all images This reverts the arf integration added in e215b17 / #121. Removed from all active Dockerfiles (minimal, osgeo, pythonr) and their downstream dependents (suggests, buildbook, latest, rocker-rpy, rocker-rpyjl, rust) which inherit the base image: - Drop arf binary installation (no longer ships /usr/local/bin/arf) - Remove system-wide shell alias 'alias R=arf' from /etc/bash.bashrc - Remove devcontainer.metadata setting r.rterm.linux=/usr/local/bin/arf - Strip arf-specific settings from .devcontainer/devcontainer.json - Remove arf documentation from README.Rmd / README.md - Also clean up archived Dockerfiles (binder, geocompy) The default R command now runs the standard R binary. Also bumps pythonr/Dockerfile R_VERSION from 4.5.1 to 4.6.0 to match the R version already shipped by rocker/geospatial:latest. --- .devcontainer/devcontainer.json | 5 ----- README.Rmd | 6 +----- README.md | 15 +-------------- dockerfiles/archive/binder/Dockerfile | 2 -- dockerfiles/archive/geocompy/Dockerfile | 2 -- minimal/Dockerfile | 9 +-------- osgeo/Dockerfile | 11 ----------- pythonr/Dockerfile | 12 +----------- 8 files changed, 4 insertions(+), 58 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d873743..8461dd6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,11 +3,6 @@ "image": "ghcr.io/geocompx/minimal:latest", "customizations": { "vscode": { - "settings": { - "r.rterm.linux": "/usr/local/bin/arf", - "r.rterm.option": [], - "r.bracketedPaste": true - }, "extensions": [ "REditorSupport.r", "quarto.quarto", diff --git a/README.Rmd b/README.Rmd index 4c5bdcc..f856a33 100644 --- a/README.Rmd +++ b/README.Rmd @@ -48,11 +48,7 @@ If not, see documentation on using Docker at websites such as [docker.com](https ## Devcontainers and VS Code support -The R-enabled images in this repository (`latest`, `minimal`, `osgeo`, `pythonr`) fully support VS Code Devcontainers. When you launch a devcontainer using one of these images: - -* **Alternative R Frontend (arf)** is pre-installed system-wide to `/usr/local/bin/arf`, providing a highly improved interactive R shell with bracketed paste, multi-line editing, and syntax highlighting. -* VS Code is automatically configured via container metadata to use `arf` as the default R terminal frontend out-of-the-box. -* For interactive convenience, the `R` command is aliased system-wide (`alias R=arf`) in bash terminals. Typing `R` in an interactive shell automatically routes to the `arf` console. (This is safe as shell aliases only apply in interactive bash shells and do not interfere with standard non-interactive scripts running package installations or build pipelines). +The R-enabled images in this repository (`latest`, `minimal`, `osgeo`, `pythonr`) fully support VS Code Devcontainers. ## Sharing folders with Docker diff --git a/README.md b/README.md index 51ce715..2aa6101 100644 --- a/README.md +++ b/README.md @@ -55,20 +55,7 @@ If not, see documentation on using Docker at websites such as ## Devcontainers and VS Code support The R-enabled images in this repository (`latest`, `minimal`, `osgeo`, -`pythonr`) fully support VS Code Devcontainers. When you launch a -devcontainer using one of these images: - -- **Alternative R Frontend (arf)** is pre-installed system-wide to - `/usr/local/bin/arf`, providing a highly improved interactive R shell - with bracketed paste, multi-line editing, and syntax highlighting. -- VS Code is automatically configured via container metadata to use - `arf` as the default R terminal frontend out-of-the-box. -- For interactive convenience, the `R` command is aliased system-wide - (`alias R=arf`) in bash terminals. Typing `R` in an interactive shell - automatically routes to the `arf` console. (This is safe as shell - aliases only apply in interactive bash shells and do not interfere - with standard non-interactive scripts running package installations or - build pipelines). +`pythonr`) fully support VS Code Devcontainers. ## Sharing folders with Docker diff --git a/dockerfiles/archive/binder/Dockerfile b/dockerfiles/archive/binder/Dockerfile index 6211245..fb8247a 100644 --- a/dockerfiles/archive/binder/Dockerfile +++ b/dockerfiles/archive/binder/Dockerfile @@ -1,6 +1,4 @@ FROM rocker/binder USER root RUN R -e "install.packages('geocompkg', upgrade = TRUE, dependencies = TRUE, force = TRUE, repos = c('https://geocompr.r-universe.dev', 'https://mlr-org.r-universe.dev', 'https://cloud.r-project.org'))" -# Install arf — Alternative R Frontend (https://github.com/eitsupi/arf) -RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/eitsupi/arf/releases/latest/download/arf-console-installer.sh | sh USER $NB_USER \ No newline at end of file diff --git a/dockerfiles/archive/geocompy/Dockerfile b/dockerfiles/archive/geocompy/Dockerfile index a2c936c..6c5c9ba 100644 --- a/dockerfiles/archive/geocompy/Dockerfile +++ b/dockerfiles/archive/geocompy/Dockerfile @@ -1,4 +1,2 @@ FROM glcr.b-data.ch/r/geospatial RUN R -e "if (!requireNamespace('pak', quietly = TRUE)) install.packages('pak', repos = 'https://cloud.r-project.org/'); pak::pak('geocompx/geocompkg', upgrade = TRUE)" -# Install arf — Alternative R Frontend (https://github.com/eitsupi/arf) -RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/eitsupi/arf/releases/latest/download/arf-console-installer.sh | sh diff --git a/minimal/Dockerfile b/minimal/Dockerfile index a79a74a..79c9907 100644 --- a/minimal/Dockerfile +++ b/minimal/Dockerfile @@ -5,14 +5,9 @@ ARG QUARTO_VERSION=1.9.37 # Ship editor defaults with the image so downstream Codespaces/devcontainers # inherit Quarto support even when they only reference the published image. -LABEL devcontainer.metadata='[{"customizations":{"vscode":{"settings":{"r.rterm.linux":"/usr/local/bin/arf","r.bracketedPaste":true},"extensions":["quarto.quarto","REditorSupport.r","ms-python.python","ms-toolsai.jupyter"]}}}]' +LABEL devcontainer.metadata='[{"customizations":{"vscode":{"extensions":["quarto.quarto","REditorSupport.r","ms-python.python","ms-toolsai.jupyter"]}}}]' RUN R -e "if (!requireNamespace('pak', quietly = TRUE)) install.packages('pak', repos = 'https://cloud.r-project.org/'); pak::pak('geocompx/geocompkg', upgrade = TRUE)" -# Install arf — Alternative R Frontend (https://github.com/eitsupi/arf) -RUN export ARF_CONSOLE_INSTALL_DIR=/usr/local ARF_CONSOLE_NO_MODIFY_PATH=1 \ - && wget -qO /tmp/arf-installer.sh https://github.com/eitsupi/arf/releases/download/v0.3.4/arf-console-installer.sh \ - && sh /tmp/arf-installer.sh \ - && rm /tmp/arf-installer.sh # Update quarto to latest stable version: RUN /rocker_scripts/install_quarto.sh ${QUARTO_VERSION} # Set RStudio preferences @@ -21,5 +16,3 @@ RUN echo '{' >> /etc/rstudio/rstudio-prefs.json RUN echo ' "rmd_chunk_output_inline": false' >> /etc/rstudio/rstudio-prefs.json RUN echo '}' >> /etc/rstudio/rstudio-prefs.json -# System-wide shell alias to make 'R' run 'arf' in interactive shells -RUN echo "alias R=arf" >> /etc/bash.bashrc diff --git a/osgeo/Dockerfile b/osgeo/Dockerfile index 85dc0f5..8f3a7f5 100644 --- a/osgeo/Dockerfile +++ b/osgeo/Dockerfile @@ -1,14 +1,5 @@ FROM rocker/geospatial:dev-osgeo RUN R -e "if (!requireNamespace('pak', quietly = TRUE)) install.packages('pak', repos = 'https://cloud.r-project.org/'); pak::pak('geocompx/geocompkg', upgrade = TRUE)" -# Install arf — Alternative R Frontend (https://github.com/eitsupi/arf) -RUN export ARF_CONSOLE_INSTALL_DIR=/usr/local ARF_CONSOLE_NO_MODIFY_PATH=1 \ - && wget -qO /tmp/arf-installer.sh https://github.com/eitsupi/arf/releases/download/v0.3.4/arf-console-installer.sh \ - && sh /tmp/arf-installer.sh \ - && rm /tmp/arf-installer.sh - -# Ship editor defaults with the image so downstream Codespaces/devcontainers -# inherit VS Code R support even when they only reference the published image. -LABEL devcontainer.metadata='[{"customizations":{"vscode":{"settings":{"r.rterm.linux":"/usr/local/bin/arf","r.bracketedPaste":true},"extensions":["quarto.quarto","REditorSupport.r","ms-python.python","ms-toolsai.jupyter"]}}}]' # Set RStudio preferences # No inline code: @@ -16,5 +7,3 @@ RUN echo '{' >> /etc/rstudio/rstudio-prefs.json RUN echo ' "rmd_chunk_output_inline": false' >> /etc/rstudio/rstudio-prefs.json RUN echo '}' >> /etc/rstudio/rstudio-prefs.json -# System-wide shell alias to make 'R' run 'arf' in interactive shells -RUN echo "alias R=arf" >> /etc/bash.bashrc diff --git a/pythonr/Dockerfile b/pythonr/Dockerfile index c437375..6ede3af 100644 --- a/pythonr/Dockerfile +++ b/pythonr/Dockerfile @@ -1,7 +1,5 @@ FROM ghcr.io/geocompx/python -LABEL devcontainer.metadata='[{"customizations":{"vscode":{"settings":{"r.rterm.linux":"/usr/local/bin/arf","r.bracketedPaste":true},"extensions":["quarto.quarto","REditorSupport.r","ms-python.python","ms-toolsai.jupyter"]}}}]' - # Note: previously this image built on Rocker but install_R_ppa.sh fails on Debian RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ @@ -9,7 +7,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ xz-utils \ && rm -rf /var/lib/apt/lists/* # Manual R installation: Download and install R DEB for Debian 12 -ARG R_VERSION=4.5.1 +ARG R_VERSION=4.6.0 RUN curl -O https://cdn.posit.co/r/debian-12/pkgs/r-${R_VERSION}_1_$(dpkg --print-architecture).deb && \ apt-get update && \ apt-get install -y --no-install-recommends ./r-${R_VERSION}_1_$(dpkg --print-architecture).deb && \ @@ -19,12 +17,6 @@ ENV PATH="/opt/R/${R_VERSION}/bin:${PATH}" ENV R_PKG_TYPE=binary ENV RETICULATE_PYTHON="/usr/local/bin/python" -# Install arf — Alternative R Frontend (https://github.com/eitsupi/arf) -RUN export ARF_CONSOLE_INSTALL_DIR=/usr/local ARF_CONSOLE_NO_MODIFY_PATH=1 \ - && wget -qO /tmp/arf-installer.sh https://github.com/eitsupi/arf/releases/download/v0.3.4/arf-console-installer.sh \ - && sh /tmp/arf-installer.sh \ - && rm /tmp/arf-installer.sh - RUN mkdir -p /etc/R && \ echo "options(repos = c(CRAN = 'https://packagemanager.posit.co/cran/__linux__/bookworm/latest'))" > /etc/R/Rprofile.site && \ mkdir -p /root && \ @@ -45,5 +37,3 @@ RUN R -e "install.packages('geocompkg', repos = c('https://geocompx.r-universe.d # rm main.zip # RUN Rscript -e 'bookdown::render_book("geocompr", output_format = "bookdown::gitbook", clean = FALSE)' -# System-wide shell alias to make 'R' run 'arf' in interactive shells -RUN echo "alias R=arf" >> /etc/bash.bashrc From b4b9904d5a747a8f7aec73b22c6c0cace54aadab Mon Sep 17 00:00:00 2001 From: robinlovelace Date: Sun, 7 Jun 2026 20:39:29 +0100 Subject: [PATCH 2/6] ci: build images on PRs but only publish from main - Add pull_request trigger to ci.yml for PRs targeting master/main - Modify build-docker.yml to always build but only push to GHCR on non-PR events (push to main, schedule, workflow_dispatch) - On PRs, build step runs without login/push, verifying Dockerfiles and package installs succeed before merge --- .github/workflows/build-docker.yml | 5 ++--- .github/workflows/ci.yml | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 49d4990..8ae5277 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -38,7 +38,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry - if: github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' + if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ghcr.io @@ -46,12 +46,11 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - if: github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' uses: docker/build-push-action@v6 with: context: . file: ${{ inputs.dockerfile }} - push: true + push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} secrets: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29da0a4..7be4596 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,10 @@ on: branches: - 'master' - 'main' + pull_request: + branches: + - 'master' + - 'main' workflow_dispatch: # Allows manual triggering jobs: From eead560c72db932014dbcdc80d8c5cbe7fb2a405 Mon Sep 17 00:00:00 2001 From: robinlovelace Date: Sun, 7 Jun 2026 20:51:02 +0100 Subject: [PATCH 3/6] fix: remove SAGA NextGen plugin download from qgis image (repo deleted) The north-road/qgis-processing-saga-nextgen repository has been deleted, causing the Docker build to fail. Remove the plugin download, install, and registry lines. SAGA itself remains available via apt, but the QGIS bridge plugin is no longer available. See also PR #126 on the remove-saga-plugin branch. --- qgis/Dockerfile | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/qgis/Dockerfile b/qgis/Dockerfile index a16c21d..57d91db 100644 --- a/qgis/Dockerfile +++ b/qgis/Dockerfile @@ -48,24 +48,11 @@ RUN wget -qO /etc/apt/keyrings/qgis-archive-keyring.gpg https://download.qgis.or RUN apt-get update && apt-get -y --with-new-pkgs upgrade RUN apt-get install -y --no-install-recommends qgis grass qgis-plugin-grass saga -RUN mkdir -p /home/rstudio/.local/share/QGIS/QGIS3/profiles/default/python/plugins \ - && wget -qO sagang_plugin.zip https://github.com/north-road/qgis-processing-saga-nextgen/archive/refs/heads/master.zip \ - && unzip -q sagang_plugin.zip -d /home/rstudio/.local/share/QGIS/QGIS3/profiles/default/python/plugins \ - && mv /home/rstudio/.local/share/QGIS/QGIS3/profiles/default/python/plugins/qgis-processing-saga-nextgen-master /home/rstudio/.local/share/QGIS/QGIS3/profiles/default/python/plugins/processing_saga_nextgen \ - && rm sagang_plugin.zip - -# Outdated: install SAGA next generation plugin with the qgis-plugin-manager ########################################### -# RUN qgis-plugin-manager init -# RUN qgis-plugin-manager update -# install SAGA next generation plugin -# RUN qgis-plugin-manager install 'Processing Saga NextGen Provider' - # the rest is nice to have but not really necessary # RUN qgis_process in a headless state # ENV QT_QPA_PLATFORM=offscreen # enable desired plugins -# RUN qgis_process plugins enable processing_saga_nextgen # RUN qgis_process plugins enable grassprovider USER root From 3f44070d73992b95712da9d64580fc69d3abb57b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Jun 2026 19:51:10 +0000 Subject: [PATCH 4/6] fix: rename step to reflect conditional push behavior --- .github/workflows/build-docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 8ae5277..f66273f 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -45,7 +45,7 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push + - name: Build and push (push skipped on pull_request) uses: docker/build-push-action@v6 with: context: . From 9a920dfb1981411f6e43ac4ed07be0baf6fc6765 Mon Sep 17 00:00:00 2001 From: robinlovelace Date: Sun, 7 Jun 2026 21:17:55 +0100 Subject: [PATCH 5/6] chore: remove saga from qgis apt install SAGA GIS is no longer installed as part of the qgis image, reducing image size and build time. SAGA can still be installed manually with 'apt-get install saga' if needed. --- qgis/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qgis/Dockerfile b/qgis/Dockerfile index 57d91db..072610f 100644 --- a/qgis/Dockerfile +++ b/qgis/Dockerfile @@ -46,7 +46,7 @@ RUN gpg --no-default-keyring --keyring /etc/apt/keyrings/ubuntugis-unstable-arch RUN wget -qO /etc/apt/keyrings/qgis-archive-keyring.gpg https://download.qgis.org/downloads/qgis-archive-keyring.gpg # RUN sh -c 'echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/qgis-archive-keyring.gpg] https://qgis.org/ubuntugis-ltr `lsb_release -c -s` main" > /etc/apt/sources.list.d/qgis.list' RUN apt-get update && apt-get -y --with-new-pkgs upgrade -RUN apt-get install -y --no-install-recommends qgis grass qgis-plugin-grass saga +RUN apt-get install -y --no-install-recommends qgis grass qgis-plugin-grass # the rest is nice to have but not really necessary # RUN qgis_process in a headless state From 69e71f53bd403866118777bf63a18170f4ddd3f6 Mon Sep 17 00:00:00 2001 From: robinlovelace Date: Sun, 7 Jun 2026 21:44:49 +0100 Subject: [PATCH 6/6] perf: compile key spatial R packages from source, rest via pak binaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the geocompkg install in qgis/Dockerfile into two steps: 1. Compile sf, terra, stars, lwgeom from CRAN source — these link against ubuntugis-unstable GDAL/PROJ/GEOS where no CRAN binary is available. 2. Install everything else via pak::pak() which fetches pre-compiled binaries from RSPM for the remaining dependencies. Removes the old single install.packages() call with dependencies=TRUE that was compiling everything from source. --- qgis/Dockerfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qgis/Dockerfile b/qgis/Dockerfile index 072610f..9fba338 100644 --- a/qgis/Dockerfile +++ b/qgis/Dockerfile @@ -57,12 +57,13 @@ RUN apt-get install -y --no-install-recommends qgis grass qgis-plugin-grass USER root # install R packages ################################################################################################## +# Step 1: Compile key spatial C/C++ packages from source so they link against +# the ubuntugis-unstable GDAL/PROJ/GEOS libraries (no CRAN binary available) +RUN R -e "install.packages(c('sf', 'terra', 'stars', 'lwgeom'), repos = c(CRAN = 'https://cloud.r-project.org'), type = 'source')" +# Step 2: Install everything else from RSPM binaries via pak +RUN R -e "install.packages('pak', repos = 'https://cloud.r-project.org'); pak::pak('geocompx/geocompkg', upgrade = TRUE)" # Set the options() for R users: RUN echo 'options(repos = "https://packagemanager.posit.co/cran/latest")' >> /usr/local/lib/R/etc/Rprofile.site -RUN Rscript -e "install.packages('pak', repos = 'https://cloud.r-project.org/')" -# RUN Rscript -e "pak::pak('r-spatial/sf')" -# RUN Rscript -e "pak::pak('rspatial/terra')" -RUN R -e "install.packages('geocompkg', upgrade = TRUE, dependencies = TRUE, force = TRUE, repos = c('https://geocompx.r-universe.dev', 'https://mlr-org.r-universe.dev', options('repos')))"