I've used renv::isolate() to make a self contained library. To save time and avoid re-downloding and re-building all packages I've tried doing the following in my Dockerfile
# Restore R packages
# Copy renv.lock file
COPY renv.lock /tmp/renv.lock
# Change working directory
WORKDIR /root/project/
# Copy renv directory with project library
COPY ./renv .
# Restore from renv.lock using binaries in the renv library
RUN R -e "renv::restore(lockfile='/tmp/renv.lock', library='/root/project/renv/library/R-4.0/x86_64-pc-linux-gnu')"
Unfortunately, renv still tries to re-download and re-install each package instead of using the library copied into /root/project/renv/
How can I avoid re-downloading and re-building the packages?
Of tangential interest, renv::isolate() does not seem to copy files in the python\conda environment from the cache to the project library. I'm using renv 0.13.2. The R packages all get copied over to the project library but the python files are still soft linked to the cache.
The other potential solution here would be to use RSPM, as that will be able to serve binary copies of packages on Linux -- you'd just need to configure renv / your Dockerfile to use the appropriate repository.
So very embarrassing but but my renv folder was being copied to the wrong location in the Dockerfile. It was being copied to /renv/ instead of /root/project/renv.
Now the Dockerfile build doesn't try to re-download and re-build all the packages when doing RUN R -e "renv::restore(lockfile='/tmp/renv.lock', library='/root/project/renv/library/R-4.0/x86_64-pc-linux-gnu')"
However, R still does not appear to recognize the library as I can't library() any of the packages included in '/root/project/renv/library/R-4.0/x86_64-pc-linux-gnu
I tried setting various environment variables with
ENV RENV_PATHS_ROOT=/root/project/renv
ENV RENV_PATHS_LIBRARY=/root/project/renv/library
RUN echo "RENV_PATHS_ROOT=${RENV_PATHS_ROOT}" >> ${R_HOME}/etc/Renviron
RUN echo "RENV_PATHS_LIBRARY=${RENV_PATHS_LIBRARY}" >> ${R_HOME}/etc/Renviron
but it doesn't seem to help.
Entering the container, running R, and running renv::restore(lockfile='/tmp/renv.lock', library='/root/project/renv/library/R-4.0/x86_64-pc-linux-gnu')
returns The library is already synchronized with the lockfile.
but something like library('Seurat')
returns Error in library("Seurat") : there is no package called ‘Seurat’
seems to allow me to library() most of the packages in /root/project/renv/library/R-4.0/x86_64-pc-linux-gnu/
What's the preferred way to set .libPaths() during initialization of R?
Also, I'm getting an error in the primary package I'm trying to run
library('Seurat')
Error: package or namespace load failed for ‘Seurat’ in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object '/root/project/renv/library/R-4.0/x86_64-pc-linux-gnu/stringi/libs/stringi.so':
libicui18n.so.66: cannot open shared object file: No such file or directory
It was running fine from the cache before I did isolate() and copied the library to the docker container.
You likely need to install the requisite system library (libicu) on your container. Or, if you did install that library, then the issue is most likely that the version used in your container differs from your host machine.
renv::restore() doesn't change the library paths; it only installs packages from a lockfile into the requested library paths. Changing the active library paths for the session is a separate step.