rocker-org / rocker-versioned2

Run current & prior versions of R using docker. rocker/r-ver, rocker/rstudio, rocker/shiny, rocker/tidyverse, and so on.
https://rocker-project.org
GNU General Public License v2.0
420 stars 180 forks source link

Custom definition of `R_LIBS` #857

Open michaelmayer2 opened 2 months ago

michaelmayer2 commented 2 months ago

Container image name

rocker/r-ver:4.4.0

Container image digest

sha256:73adabf378930f8744f56bac1fe5e99870532eb4ced1a15075991bac909d21f3

What operating system related to this question?

Linux

System information

Question

I am curious why you added https://github.com/rocker-org/rocker-versioned2/blob/92e20d2bc2e6aed495a7cc359154627c7a9b048d/scripts/install_R_source.sh#L149 to Renviron.site. According to the R documentation, the presence of site-library in ${R_HOME}/site-library alone will add this to libPaths() (cf. https://stat.ethz.ch/R-manual/R-devel/library/base/html/libPaths.html "First, .Library.site is initialized from R_LIBS_SITE. If this is unset or empty, the ‘site-library’ subdirectory of R_HOME is used. Only directories which exist at the time of initialization are retained. Then, .libPaths() is called...").

I have recently seen a case where the current definition of R_LIBS in Renviron.site in the docker image leads to the behaviour of .libPaths() listing the folders in reverse order (i.e. R_LIBS_USER the last) which makes package installations using install.packages() impossible (unless you really set target .libPaths() manually.

I am sure there is valid reason for your approach to Renviron.site - just curious to understand the history of it.

michaelmayer2 commented 2 months ago

Steps to reproduce:

docker run -ti rocker/r-ver:4.4.0 bash

In container, run

useradd -s /bin/bash -m mm 
su - mm
R

In R console, run

install.packages("SuppDists")
.libPaths()

.libPaths() will report

> .libPaths()
[1] "/usr/local/lib/R/site-library"             
[2] "/usr/local/lib/R/library"                  
[3] "/home/mm/R/x86_64-pc-linux-gnu-library/4.4"

After removing Renviron.site and rerunning a new R session, libPaths() will report

> .libPaths()
[1] "/home/mm/R/x86_64-pc-linux-gnu-library/4.4"
[2] "/usr/local/lib/R/site-library"             
[3] "/usr/local/lib/R/library"  

as expected.

eitsupi commented 1 month ago

@cboettig Any idea?

cboettig commented 1 month ago

Right, so this follows conventions I think Dirk originally established with debian's r-base (Note @eddelbuettel is both rocker maintainer and a debian mantainer), and he can probably explain better.

Note the permissions -- the default user is added to staff group, which is granted write permissions to site-library. I believe the motivation was mostly about space, the user could then upgrade packages in the site library rather than having multiple copies, and in a multi-user environment you didn't end up with each user needing a their own copy of site-library.

Of course users are free to override the R_LIBS env to whatever they want, e.g. in ~/.Renviron.

In containerized setups these days it's also still a common pattern that even user-permission installs go in a system path 'below' home (the Jupyter project uses /srv or /opt). It's also common to mount the user's home with a bind mount that would overwrite the container home directory, so this ensures that packages even if installed by non-root user aren't lost.

eddelbuettel commented 1 month ago

As I read it the issue here seems to be the reordered path, ie why

> .libPaths()
[1] "/usr/local/lib/R/site-library"             
[2] "/usr/local/lib/R/library"                  
[3] "/home/mm/R/x86_64-pc-linux-gnu-library/4.4"

per https://github.com/rocker-org/rocker-versioned2/issues/857#issuecomment-2355087311 by @michaelmayer2 above.

We usually put the user PATH first:

edd@rob:~/git$ docker run --rm -ti rocker/r-base bash
root@57eb7eafca96:/# useradd -s /bin/bash -m dirk
root@57eb7eafca96:/# su - dirk
dirk@57eb7eafca96:~$ Rscript -e '.libPaths()'
[1] "/usr/local/lib/R/site-library" "/usr/lib/R/site-library"      
[3] "/usr/lib/R/library"           
dirk@57eb7eafca96:~$ mkdir -p R/x86_64-pc-linux-gnu-library/4.4
dirk@57eb7eafca96:~$ Rscript -e '.libPaths()'
[1] "/home/dirk/R/x86_64-pc-linux-gnu-library/4.4"
[2] "/usr/local/lib/R/site-library"               
[3] "/usr/lib/R/site-library"                     
[4] "/usr/lib/R/library"                          
dirk@57eb7eafca96:~$ 
michaelmayer2 commented 1 month ago

Thanks @eddelbuettel for your input - So we seem to have a different behaviour when comparing r-ver and r-base containers. For me the behaviour of r-base makes more sense to me and is more appropriate for our use case of running Singularity/Apptainer containers with the R installation baked in and users being able to add packages into R_LIBS_USER as they please.

docker run -ti rocker/r-ver:4.4.0 bash
root@2d5be3fe7143:/# useradd -s /bin/bash -m dirk
root@2d5be3fe7143:/# su - dirk
dirk@2d5be3fe7143:~$ Rscript -e '.libPaths()'
$[1] "/usr/local/lib/R/site-library" "/usr/local/lib/R/library"     
dirk@2d5be3fe7143:~$ mkdir -p R/x86_64-pc-linux-gnu-library/4.4
dirk@2d5be3fe7143:~$ Rscript -e '.libPaths()'
[1] "/usr/local/lib/R/site-library"               
[2] "/usr/local/lib/R/library"                    
[3] "/home/dirk/R/x86_64-pc-linux-gnu-library/4.4"
eitsupi commented 1 month ago

Thank you. Is anyone interested in a fix for this? (I do not intend to do the work as I am not in trouble)

cboettig commented 1 month ago

@michaelmayer2 would you be interested in making a PR for this? matching the r-base behavior makes sense and I think was what was intended here.

michaelmayer2 commented 1 month ago

@cboettig PR https://github.com/rocker-org/rocker-versioned2/pull/866 is there for your review.