Skip to content

Commit 422dbbe

Browse files
committed
fix(docker): R installs — lib path, CRAN mirror, fail-fast for toolchain
- mkdir R_LIBS_USER before Rscript; set .libPaths + cloud.r-project.org in install_packages.R - Pre-flight step fails in seconds if cmake or pkg-config missing (avoids 30–60m then fs/rmarkdown/tidyverse verify failure) - Ncpus=1 for R package compiles; realistic time hint for the long CRAN compile step
1 parent c277ca5 commit 422dbbe

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

book/docker/linux/Dockerfile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,9 +469,21 @@ RUN echo "🚀 === STARTING R INSTALLATION ===" && \
469469
duration=$((end_time - start_time)) && \
470470
echo "✅ === R INSTALLATION COMPLETE === (${duration}s)"
471471

472+
# R may omit R_LIBS_USER from .libPaths() if the directory is missing, so install and verify
473+
# can disagree on where packages were written. Create it before any Rscript package step.
474+
RUN mkdir -p $R_LIBS_USER
475+
476+
# Fail fast: building CRAN source packages (e.g. fs → libuv) needs cmake. Without it,
477+
# the R step runs 30–60+ minutes then dies at verify. See e12d7dc4a8.
478+
RUN echo "🔎 Pre-flight: R build toolchain (cmake, pkg-config)…" && \
479+
test -d "$R_LIBS_USER" || { echo "❌ R_LIBS_USER dir missing: $R_LIBS_USER"; exit 1; } && \
480+
command -v cmake >/dev/null 2>&1 || { echo "❌ cmake not in PATH (required for R package fs, needed by rmarkdown/tidyverse)"; exit 1; } && \
481+
command -v pkg-config >/dev/null 2>&1 || { echo "❌ pkg-config not in PATH"; exit 1; } && \
482+
echo "✅ Pre-flight OK"
483+
472484
# === PHASE 7: R PACKAGE INSTALLATION ===
473485
RUN echo "🚀 === STARTING R PACKAGE INSTALLATION ===" && \
474-
echo "⏰ Estimated time: 2-3 minutes" && \
486+
echo "⏰ Cold build: this step compiles many CRAN packages; expect 20–60+ min (cache shortens reruns)" && \
475487
start_time=$(date +%s) && \
476488
\
477489
echo "Running R setup script with the following files:" && \

book/tools/dependencies/install_packages.R

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
# If you need to add a new package, follow the instructions below.
66
# ==============================================================
77

8+
# Docker/CI: R_LIBS_USER is ignored at startup if the path does not exist, so we ensure
9+
# a single target library and pin CRAN (HTTPS) before any install.
10+
lib <- Sys.getenv("R_LIBS_USER", unset = NA_character_)
11+
if (!is.na(lib) && nzchar(lib)) {
12+
dir.create(lib, recursive = TRUE, showWarnings = FALSE)
13+
.libPaths(c(lib, .libPaths()))
14+
}
15+
options(repos = c(CRAN = "https://cloud.r-project.org"))
16+
817
required_packages <- c(
918
"downlit", # Required for code linking in Quarto
1019
"ggplot2", # Visualization package
@@ -24,14 +33,15 @@ required_packages <- c(
2433

2534
install_if_missing <- function(pkg) {
2635
if (!requireNamespace(pkg, quietly = TRUE)) {
27-
install.packages(pkg, repos = "http://cran.rstudio.com")
36+
# Ncpus=1: avoid parallel compiles OOM'ing in Docker/Actions runners
37+
install.packages(pkg, Ncpus = 1L)
2838
}
2939
}
3040

3141
invisible(sapply(required_packages, install_if_missing))
3242

3343
if (!requireNamespace("tinytex", quietly = TRUE)) {
34-
install.packages("tinytex", repos = "http://cran.rstudio.com")
44+
install.packages("tinytex", Ncpus = 1L)
3545
tinytex::install_tinytex()
3646
}
3747

0 commit comments

Comments
 (0)