I can not load sf in docker

55 views Asked by At

I'm deploying an application (on docker) that is totally dependent on sf but I'm having trouble loading it into docker :

FROM rocker/shiny

#Make a directory in the container
RUN mkdir /home/shiny-app

RUN R -e "install.packages('sf')"

RUN R -e "library('sf')"

COPY . /home/shiny-app/

This is the error message I received. I have no idea what caused this error. Probably GDAL? I need help to solve this problem.

enter image description here

1

There are 1 answers

1
r2evans On BEST ANSWER

When you want to add R packages to a new OS running R, you need to be aware of any underlying OS packages that are required. In this case, reading sf's DESCRIPTION, we see

SystemRequirements: GDAL (>= 2.0.1), GEOS (>= 3.4.0), PROJ (>= 4.8.0), sqlite3

It's not always intuitive how to know what these labels mean. One place you might look for a hint about this is Posit's Package Manager, which lists the following OS requirements on Ubuntu 22.04 (on which rocker/shiny is based).

apt-get install -y libgdal-dev
apt-get install -y gdal-bin
apt-get install -y libgeos-dev
apt-get install -y libproj-dev
apt-get install -y libsqlite3-dev
apt-get install -y libssl-dev
apt-get install -y libudunits2-dev

Many of those are likely already present.

First, let me reproduce the problem:

$ docker build -t quux .
$ docker run -it --rm quux R --quiet
> library("sf")
Error: package or namespace load failed for ‘sf’ in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/usr/local/lib/R/site-library/units/libs/units.so':
  libudunits2.so.0: cannot open shared object file: No such file or directory

Through experience, I know that Jammy (22.04) needs these packages for R's sf package, add these lines somewhere in your Dockerfile:

# ...
RUN apt-get update && \
  apt-get install -y libproj22 libudunits2-0 libgdal30 && \
  rm -rf /var/lib/apt/lists/*
RUN R -e "install.packages('sf')"

Notes:

  1. Whether or not you join those with previous apt and install.packages(..) commands are up to you.
  2. I encourage you to review https://docs.docker.com/develop/develop-images/instructions/ for "best practices", especially when installing OS-level packages, attempting to balance that with image size (ergo the rm -rf command).

It now works:

$ docker build -t quux .
$ docker run -it --rm quux R --quiet
> library("sf")
Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 8.2.1; sf_use_s2() is TRUE