Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Let Docker image build fail when R package installation returns error

I am trying to create a custom Docker image based on Rocker using Dockerfile. In the Dockerfile I am pulling my own R package from a custom GitLab server using:

RUN R -e "devtools::install_git('[custom gitlab server]', quiet = FALSE)"

Everything usually works, but I have noticed that when the GitLab server is down, or the machine running Docker is low on RAM memory, the package does not install correctly and returns an error message in the R console. This behavior is to be expected. However, Docker does not notice the error produced by R and continues evaluating the rest of the Dockerfile. I would like Docker to fail building the image when this occurs. In that way, I could ultimately prevent automatic deployment of the incomplete Docker container by Kubernetes.

So far I have thought of two potential solutions, but I am struggling with the execution:

  1. R level: Wrap tryCatch() around devtools::install_git to catch the error. But then what? Use stop? Will this cause the Docker building process to stop as well? Could withCallingHandlers() be used?
  2. Dockerfile level: Use a shell command to check for errors? I cannot find the contents of R --help as I do not have a Linux machine at the moment. So I am not sure of what R -e actually does (execute I presume) and which other commands could be passed along with R.

It seems that a similar issue is discussed here and here, but the I do not understand how they have solved it.

Thus how to make sure no Docker image ends up running on the Kubernetes cluster without the custom package?

like image 649
dkreeft Avatar asked Mar 06 '18 11:03

dkreeft


1 Answers

The Docker build process should stop once one of the commands in the Dockerfile returns a non zero status.

install_git doesn't seem to throw an error when the package wasn't installed successfully, so the execution keeps on.

An obvious way to go would be to wrap the installation inside a dedicated R script and throw an error if it didn't finish successfully, which would then stop the build.

So I would suggest something like this ...

Create installation script install_gitlab.R:

### file install_gitlab.R

## change repo- and package name!!

repo <- '[custom gitlab server]'

pkgname <- 'testpackage'

devtools::install_git(repo, quiet = FALSE)

stopifnot(pkgname %in% installed.packages()[,'Package'])

Modify your Dockerfile accordingly (replace the install_git line):

...

Add install_gitlab.R /runscripts/install_gitlab.R

RUN Rscript /runscripts/install_gitlab.R

...

One thing to keep in mind is, this approach assumes the package you're trying to install is NOT installed prior to calling the command.

like image 169
Val Avatar answered Nov 17 '22 22:11

Val