vignettes/containerit.Rmd
containerit.Rmd
## Loading required package: knitr
temp_workspace <- tempfile(pattern = "containerit_temp")
dir.create(temp_workspace)
opts_knit$set(root.dir = temp_workspace)
Even though R is designed for open and reproducible research, users who want to share their work with others are facing challenges. Sharing merely the R script or R Markdown document should warrant reproducibility, but many analyses rely on additional resources and specific third party software as well. An R script may produce unexpected results or errors when executed under a different version of R or another platform. Reproduciblility is only assured by providing complete setup instructions and resources. Long-term reproducibility can be achieved by either regular maintenance of the code, i.e. keeping it always working with the latest package versions from CRAN. It can be supported by packages such as packrat and platforms such as MRAN, which provide means to capture a specific combination of R packages. An alternative to updating or managing packages explicitly is providing the full runtime environment in its original state, using virtual machines or software containers.
The R extension package containerit
aims to facilitate the latter approach by making reproducible and archivable research with containers easier. The development is supported by the DFG-funded project Opening Reproducible Research (o2r, http://o2r.info). containerit
relies on Docker and automatically generates a container manifest, or “recipe”, with setup instructions to recreate a runtime environment based on a given R session, R script, R Markdown file or workspace directory. The resulting Dockerfile
can not only be read and understood by humans, but also be interpreted by the Docker engine to create a software container containing all the R packages and their system dependencies. This way all requirements of an R workflow are packaged in an executable format.
The created Dockerfiles are based on the Rocker project (Rocker on Docker Hub, introduction). Using the stack of version-stable Rocker images, it is possible to match the container’s R version with the local R installation or any R version the user requires. containerit
executes the provided input workspace or file first locally on the host machine in order to detect all dependencies. For determining external software dependencies of attached packages, containerit
relies (a) on the sysreqs database and makes use of the corresponding web API and R package, and (b) on internally defined rule sets for challenging configurations.
The Dockerfile created by containerit
can then be used to build a Docker image. Running the image will start an R session that closely resembles the creating systems runtime environment. The image can be shared and archived and works anywhere with a compatible Docker version.
To build images and run containers, the package integrates with the stevedore package and adds a few convenience functions for interacting with Docker images and containers. For concrete details on reading, loading, or installing the exact versions of R packages including their system dependencies/libraries, this project focuses on the geospatial domain. containerit
uses the package futile.logger
to provide information to the user at a configurable level of detail, see futile.logger documentation.
The related package liftr
creates Dockerfiles for rendering R Markdown documents, but relies on manually created metadata in the document’s YAML header.
In the remainder of this vignette, we first introduce the main usage scenarios for containerit
and document current challenges as well as directions for future work.
The easiest way to generate a Dockerfile is to run an analysis in an interactive R session and create a Dockerfile for this session by loading containerit
and calling the dockerfile()
- method with default parameters. As shown in the example below, the result can be pretty-printed and written to a file. If no file
argument is supplied to write()
, the Dockerfile is written to the current working directory as ./Dockerfile
, following the typical naming convention of Docker.
When packaging any resources, it is essential that the R working directory is the same as the build context, to which the Dockerfile refers. All resources must be located below this directory so that they can be refered to by relative paths (e.g. for copy instructions). This must also be considered when packaging R scripts that use relative paths, e.g. for reading a file or sourcing another R script.
## Registered S3 method overwritten by 'xts':
## method from
## as.zoo.xts zoo
library("sp")
data(meuse)
coordinates(meuse) = ~x+y
data(meuse.grid)
gridded(meuse.grid) = ~x+y
v <- variogram(log(zinc)~1, meuse)
m <- fit.variogram(v, vgm(1, "Sph", 300, 1))
plot(v, model = m)
## INFO [2019-08-20 16:45:18] Going online? TRUE ... to retrieve system dependencies (sysreq-api)
## INFO [2019-08-20 16:45:18] Trying to determine system requirements for the package(s) 'assertthat,backports,commonmark,crayon,curl,desc,digest,evaluate,FNN,formatR,fs,futile.logger,futile.options,gstat,htmltools,httpuv,intervals,jsonlite,knitr,lambda.r,later,lattice,magrittr,MASS,memoise,mime,miniUI,pillar,pkgconfig,pkgdown,promises,R6,Rcpp,rlang,rmarkdown,roxygen2,rprojroot,rstudioapi,semver,shiny,shinyFiles,sp,spacetime,stevedore,stringi,stringr,tibble,versions,xfun,xml2,xtable,xts,yaml,zoo' from sysreqs online DB
## INFO [2019-08-20 16:45:21] Adding CRAN packages: assertthat, backports, commonmark, crayon, curl, desc, digest, evaluate, FNN, formatR, fs, futile.logger, futile.options, gstat, htmltools, httpuv, intervals, jsonlite, knitr, lambda.r, later, lattice, magrittr, MASS, memoise, mime, miniUI, pillar, pkgconfig, pkgdown, promises, R6, Rcpp, rlang, rmarkdown, roxygen2, rprojroot, rstudioapi, semver, shiny, shinyFiles, sp, spacetime, stevedore, stringi, stringr, tibble, versions, xfun, xml2, xtable, xts, yaml, zoo
## INFO [2019-08-20 16:45:21] Created Dockerfile-Object based on sessionInfo
The representation of a Dockerfile in R is an instance of the S4 class Dockerfile
.
## An object of class "Dockerfile"
## Slot "image":
## An object of class "From"
## Slot "image":
## [1] "rocker/r-ver"
##
## Slot "postfix":
## An object of class "Tag"
## [1] "3.6.1"
##
##
## Slot "maintainer":
## An object of class "Label"
## Slot "data":
## $maintainer
## [1] "daniel"
##
##
## Slot "multi_line":
## [1] FALSE
##
##
## Slot "instructions":
## [[1]]
## An object of class "Run_shell"
## Slot "commands":
## [1] "export DEBIAN_FRONTEND=noninteractive; apt-get -y update"
## [2] "apt-get install -y git-core \\\n\tlibcurl4-openssl-dev \\\n\tlibssl-dev \\\n\tlibxml2-dev \\\n\tmake \\\n\tpandoc \\\n\tpandoc-citeproc"
##
##
## [[2]]
## An object of class "Run"
## Slot "exec":
## [1] "install2.r"
##
## Slot "params":
## [1] "assertthat" "backports" "commonmark" "crayon"
## [5] "curl" "desc" "digest" "evaluate"
## [9] "FNN" "formatR" "fs" "futile.logger"
## [13] "futile.options" "gstat" "htmltools" "httpuv"
## [17] "intervals" "jsonlite" "knitr" "lambda.r"
## [21] "later" "lattice" "magrittr" "MASS"
## [25] "memoise" "mime" "miniUI" "pillar"
## [29] "pkgconfig" "pkgdown" "promises" "R6"
## [33] "Rcpp" "rlang" "rmarkdown" "roxygen2"
## [37] "rprojroot" "rstudioapi" "semver" "shiny"
## [41] "shinyFiles" "sp" "spacetime" "stevedore"
## [45] "stringi" "stringr" "tibble" "versions"
## [49] "xfun" "xml2" "xtable" "xts"
## [53] "yaml" "zoo"
##
##
## [[3]]
## An object of class "Workdir"
## Slot "path":
## [1] "/payload/"
##
##
##
## Slot "entrypoint":
## NULL
##
## Slot "cmd":
## An object of class "Cmd"
## Slot "exec":
## [1] "R"
##
## Slot "params":
## [1] NA
##
## Slot "form":
## [1] "exec"
The printout below shows the rendered Dockerfile. Its instructions follow a pre-defined order:
CMD
instruction (final line) defines the default command when running the containerNote that the maintainer label as well as the R version of the base image are detected from the runtime environment, if not set to different values manually.
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y git-core \
libcurl4-openssl-dev \
libssl-dev \
libxml2-dev \
make \
pandoc \
pandoc-citeproc
RUN ["install2.r", "assertthat", "backports", "commonmark", "crayon", "curl", "desc", "digest", "evaluate", "FNN", "formatR", "fs", "futile.logger", "futile.options", "gstat", "htmltools", "httpuv", "intervals", "jsonlite", "knitr", "lambda.r", "later", "lattice", "magrittr", "MASS", "memoise", "mime", "miniUI", "pillar", "pkgconfig", "pkgdown", "promises", "R6", "Rcpp", "rlang", "rmarkdown", "roxygen2", "rprojroot", "rstudioapi", "semver", "shiny", "shinyFiles", "sp", "spacetime", "stevedore", "stringi", "stringr", "tibble", "versions", "xfun", "xml2", "xtable", "xts", "yaml", "zoo"]
WORKDIR /payload/
CMD ["R"]
Instead of printing out to the console, you can also write to a file:
There also is a convenience function to build the Dockerfile
object with stevedore
:
Packaging an interactive session has the disadvantage that unnecessary dependencies might be added to the Dockerfile and subsequently to the container. For instance the package futile.logger
is a dependency of containerit
, and it will be added to the container because it was loaded into the same session were the analyses was executed. It cannot be removed by default, because other packages in the session might use it as well (even unintentionally in case of generic methods). Therefore, it is safer not to tamper with the current session, but to run the analysis in an isolated vanilla session, which does not have containerit
in it. The latter will batch-execute the commands in a seperate instance of R and retrieves an object of class sessionInfo
. The session info is then used as input to dockerfile()
. This is also how dockerfile()
works internally when packaging either expressions, scripts or R markdown files.
The following code creates a Dockerfile for a list of expressions in a vanilla session.
exp <- c(expression(library(sp)),
expression(data(meuse)),
expression(mean(meuse[["zinc"]])))
dockerfile_object <- dockerfile(from = exp)
## INFO [2019-08-20 16:45:22] Creating an R session with the following expressions:
## library(sp), data(meuse), mean(meuse[["zinc"]])
## INFO [2019-08-20 16:45:24] Going online? TRUE ... to retrieve system dependencies (sysreq-api)
## INFO [2019-08-20 16:45:24] Trying to determine system requirements for the package(s) 'assertthat,backports,crayon,curl,desc,digest,formatR,fs,futile.logger,futile.options,htmltools,httpuv,jsonlite,lambda.r,later,lattice,magrittr,mime,miniUI,pillar,pkgconfig,promises,R6,Rcpp,rlang,rprojroot,rstudioapi,semver,shiny,shinyFiles,sp,stevedore,stringi,stringr,tibble,versions,xtable' from sysreqs online DB
## INFO [2019-08-20 16:45:26] Adding CRAN packages: assertthat, backports, crayon, curl, desc, digest, formatR, fs, futile.logger, futile.options, htmltools, httpuv, jsonlite, lambda.r, later, lattice, magrittr, mime, miniUI, pillar, pkgconfig, promises, R6, Rcpp, rlang, rprojroot, rstudioapi, semver, shiny, shinyFiles, sp, stevedore, stringi, stringr, tibble, versions, xtable
## INFO [2019-08-20 16:45:26] Created Dockerfile-Object based on expression
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y libcurl4-openssl-dev \
libssl-dev \
make
RUN ["install2.r", "assertthat", "backports", "crayon", "curl", "desc", "digest", "formatR", "fs", "futile.logger", "futile.options", "htmltools", "httpuv", "jsonlite", "lambda.r", "later", "lattice", "magrittr", "mime", "miniUI", "pillar", "pkgconfig", "promises", "R6", "Rcpp", "rlang", "rprojroot", "rstudioapi", "semver", "shiny", "shinyFiles", "sp", "stevedore", "stringi", "stringr", "tibble", "versions", "xtable"]
WORKDIR /payload/
CMD ["R"]
R scripts are packaged by just supplying the file path or paths to the arguement from
of dockerfile()
. They are automatically copied into the container’s working directory. In order to run the R script on start-up, rather than an interactive R session, a CMD instruction can be added by providing the value of the helper function CMD_Rscript()
as an argument to cmd
.
# create simple script file
scriptFile <- tempfile(pattern = "containerit_", fileext = ".R")
writeLines(c('library(rgdal)',
'nc <- rgdal::readOGR(system.file("shapes/", package="maptools"), "sids", verbose = FALSE)',
'proj4string(nc) <- CRS("+proj=longlat +datum=NAD27")',
'plot(nc)'), scriptFile)
# use a custom startup command
scriptCmd <- CMD_Rscript(basename(scriptFile))
# create Dockerfile for the script
dockerfile_object <- dockerfile(from = scriptFile, silent = TRUE, cmd = scriptCmd)
## Warning in dockerfileFromFile(file = from, dockerfile = the_dockerfile, :
## The given file is not inside the working directory! This may lead to
## incorrect COPY instructions.
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y gdal-bin \
libcurl4-openssl-dev \
libgdal-dev \
libproj-dev \
libssl-dev \
make
RUN ["install2.r", "assertthat", "backports", "crayon", "curl", "desc", "digest", "formatR", "fs", "futile.logger", "futile.options", "htmltools", "httpuv", "jsonlite", "lambda.r", "later", "lattice", "magrittr", "mime", "miniUI", "pillar", "pkgconfig", "promises", "R6", "Rcpp", "rgdal", "rlang", "rprojroot", "rstudioapi", "semver", "shiny", "shinyFiles", "sp", "stevedore", "stringi", "stringr", "tibble", "versions", "xtable"]
WORKDIR /payload/
CMD ["R", "--vanilla", "-f", "containerit_66bb2c4a2589.R"]
Similarly to scripts, R Markdown files can be passed to the from
argument. In the following example, a vignette from the Simple Features package sf
is packaged in a container. To render the document at startup, the Dockerfile’s CMD
instruction must be changed. To do this, the cmd
argument passed to dockerfile()
is constructed using the function CMD_Render
.
file.copy(from = system.file("doc/sf6.Rmd", package = "sf"),
to = file.path(temp_workspace, "sf6.Rmd"),
overwrite = TRUE)
dockerfile_object <- dockerfile(from = file.path(temp_workspace, "sf6.Rmd"),
silent = TRUE,
cmd = CMD_Render("sf6.Rmd"))
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y gdal-bin \
libcurl4-openssl-dev \
libgdal-dev \
libproj-dev \
libssl-dev \
make
RUN ["install2.r", "assertthat", "backports", "crayon", "curl", "desc", "digest", "formatR", "fs", "futile.logger", "futile.options", "htmltools", "httpuv", "jsonlite", "lambda.r", "later", "lattice", "magrittr", "mime", "miniUI", "pillar", "pkgconfig", "promises", "R6", "Rcpp", "rgdal", "rlang", "rprojroot", "rstudioapi", "semver", "shiny", "shinyFiles", "sp", "stevedore", "stringi", "stringr", "tibble", "versions", "xtable"]
WORKDIR /payload/
CMD ["R", "--vanilla", "-f", "containerit_66bb2c4a2589.R"]
A typical case expected to be interesting for containerit
users is packaging a local directory with a collection of data and code files. If providing a directory path to the dockerfile()
function, the package searches for the first occurence of an R script, or otherwise the first occurence of an R markdown file. It then proceeds to package this file along with all other resources in the directory, as shown in the next section.
You can also save your sessionInfo()
into an .RData
file and create a Dockerfile
form it. The sessionInfo
object must have the one of the names sessionInfo
, sessioninfo
, or session_info
. It must be the only object in the .RData
file. This is useful when you want to re-create sessions on different machines.
suppressPackageStartupMessages(library("sf"))
sessionInfo <- sessionInfo()
save(sessionInfo, file = file.path(temp_workspace, "sessionInfo.RData"))
unloadNamespace("sf")
the_dockerfile <- dockerfile(from = file.path(temp_workspace, "sessionInfo.RData"))
print(the_dockerfile)
## FROM rocker/r-ver:3.6.1
## LABEL maintainer="daniel"
## RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
## && apt-get install -y gdal-bin \
## git-core \
## libcurl4-openssl-dev \
## libgdal-dev \
## libgeos-dev \
## libgeos++-dev \
## libssl-dev \
## libudunits2-dev \
## libxml2-dev \
## make \
## pandoc \
## pandoc-citeproc
## RUN ["install2.r", "assertthat", "automagic", "backports", "callr", "class", "classInt", "codetools", "commonmark", "crayon", "curl", "DBI", "desc", "digest", "e1071", "evaluate", "FNN", "formatR", "fs", "futile.logger", "futile.options", "gstat", "htmltools", "httpuv", "intervals", "jsonlite", "KernSmooth", "knitr", "lambda.r", "later", "lattice", "magrittr", "MASS", "memoise", "mime", "miniUI", "pillar", "pkgconfig", "pkgdown", "processx", "promises", "ps", "purrr", "R6", "Rcpp", "rjson", "rlang", "rmarkdown", "roxygen2", "rprojroot", "rstudioapi", "semver", "sf", "shiny", "shinyFiles", "sp", "spacetime", "stevedore", "stringi", "stringr", "tibble", "units", "versions", "xfun", "xml2", "xtable", "xts", "yaml", "zoo"]
## WORKDIR /payload/
## CMD ["R"]
Two alternative packages provide their own version of a session info, both of which are supported as well. The following examples first load the packages fortunes
and remotes
, store session information objects, and then unload the packages again before creating Dockerfile
s from the stored objects.
suppressPackageStartupMessages(library("devtools"))
suppressPackageStartupMessages(library("sessioninfo"))
suppressPackageStartupMessages(library("fortunes"))
suppressPackageStartupMessages(library("remotes"))
session_info <- devtools::session_info()
save(session_info, file = file.path(temp_workspace, "session_info_devtools.RData"))
sessioninfo = sessioninfo::session_info()
save(sessioninfo, file = file.path(temp_workspace, "session_info.RData"))
unloadNamespace("abc")
unloadNamespace("A3")
df_sessioninfo <- dockerfile(from = file.path(temp_workspace, "session_info.RData"))
df_devtools <- dockerfile(from = file.path(temp_workspace, "session_info_devtools.RData"))
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y git-core \
libcurl4-openssl-dev \
libssl-dev \
libudunits2-dev \
libxml2-dev \
make \
pandoc \
pandoc-citeproc
RUN ["install2.r", "assertthat", "automagic", "backports", "callr", "class", "classInt", "cli", "codetools", "commonmark", "crayon", "curl", "DBI", "desc", "devtools", "digest", "e1071", "evaluate", "FNN", "formatR", "fortunes", "fs", "futile.logger", "futile.options", "glue", "gstat", "htmltools", "httpuv", "intervals", "jsonlite", "KernSmooth", "knitr", "lambda.r", "later", "lattice", "magrittr", "MASS", "memoise", "mime", "miniUI", "pillar", "pkgbuild", "pkgconfig", "pkgdown", "pkgload", "prettyunits", "processx", "promises", "ps", "purrr", "R6", "Rcpp", "remotes", "rjson", "rlang", "rmarkdown", "roxygen2", "rprojroot", "rstudioapi", "semver", "sessioninfo", "shiny", "shinyFiles", "sp", "spacetime", "stevedore", "stringi", "stringr", "testthat", "tibble", "units", "usethis", "versions", "withr", "xfun", "xml2", "xtable", "xts", "yaml", "zoo"]
WORKDIR /payload/
CMD ["R"]
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y git-core \
libcurl4-openssl-dev \
libssl-dev \
libudunits2-dev \
libxml2-dev \
make \
pandoc \
pandoc-citeproc
RUN ["install2.r", "assertthat", "automagic", "backports", "callr", "class", "classInt", "cli", "codetools", "commonmark", "crayon", "curl", "DBI", "desc", "devtools", "digest", "e1071", "evaluate", "FNN", "formatR", "fortunes", "fs", "futile.logger", "futile.options", "glue", "gstat", "htmltools", "httpuv", "intervals", "jsonlite", "KernSmooth", "knitr", "lambda.r", "later", "lattice", "magrittr", "MASS", "memoise", "mime", "miniUI", "pillar", "pkgbuild", "pkgconfig", "pkgdown", "pkgload", "prettyunits", "processx", "promises", "ps", "purrr", "R6", "Rcpp", "remotes", "rjson", "rlang", "rmarkdown", "roxygen2", "rprojroot", "rstudioapi", "semver", "sessioninfo", "shiny", "shinyFiles", "sp", "spacetime", "stevedore", "stringi", "stringr", "testthat", "tibble", "units", "usethis", "versions", "withr", "xfun", "xml2", "xtable", "xts", "yaml", "zoo"]
WORKDIR /payload/
CMD ["R"]
DESCRIPTION
file or objectThe DESCRIPTION
file format contains basic information about R extension packages and their dependencies. containerit
can also create Dockerfile
s based on a DESCRIPTION
file or ob description
objects from the desc
package. Unless specified otherwise, it uses the minimal R version mentioned in the Depends
-field for the base image.
FROM rocker/r-ver:3.2.0
LABEL maintainer="daniel"
RUN ["install2.r", "assertthat", "dplyr", "glue", "magrittr", "methods", "pkgconfig", "R6", "Rcpp", "rlang", "tibble", "tidyselect", "utils"]
WORKDIR /payload/
CMD ["R"]
Use this to quickly create a container that contains everything needed to run your package, including system dependencies and installing the actual package in a specific version:
df_description_sf <- dockerfile(from = desc::desc(package = "sf"),
maintainer = "o2r",
versioned_packages = TRUE)
## WARN [2019-08-20 16:45:53] No version information found for packages: classInt, DBI, graphics, grDevices, grid, magrittr, Rcpp, stats, tools, units, utils
FROM rocker/r-ver:3.3.0
LABEL maintainer="o2r"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y gdal-bin \
libgdal-dev \
libgeos-dev \
libgeos++-dev \
libudunits2-dev
RUN ["install2.r", "versions"]
RUN ["install2.r", "classInt", "DBI", "graphics", "grDevices", "grid", "magrittr", "Rcpp", "stats", "tools", "units", "utils"]
RUN ["Rscript", "-e", "versions::install.versions('sf', '0.7.7')"]
WORKDIR /payload/
CMD ["R"]
Analyses in R often rely on external files and resources that are located located in the workspace. When scripts or R markdown files are packaged, they are copied by default into the same location relative to the working directory. The argument copy
influences how dockefile()
behaves in this matter. It can either have the values script
(default behaviour), script_dir
(copies the complete directory in which the input file is located), or a custom list of files and directories inside the current working directory
file.copy(from = system.file("simple_test_script_resources",
package = "containerit"),
to = temp_workspace, recursive = TRUE)
## [1] TRUE
setwd(file.path(temp_workspace, "simple_test_script_resources"))
dockerfile_resources <- dockerfile(from = ".",
copy = "script_dir",
cmd = CMD_Rscript("simple_test.R"))
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y libcurl4-openssl-dev \
libssl-dev \
make
RUN ["install2.r", "assertthat", "backports", "crayon", "curl", "desc", "digest", "formatR", "fs", "futile.logger", "futile.options", "htmltools", "httpuv", "jsonlite", "lambda.r", "later", "magrittr", "mime", "miniUI", "pillar", "pkgconfig", "promises", "R6", "Rcpp", "rlang", "rprojroot", "rstudioapi", "semver", "shiny", "shinyFiles", "stevedore", "stringi", "stringr", "tibble", "versions", "xtable"]
WORKDIR /payload/
COPY ["./", "./"]
CMD ["R", "--vanilla", "-f", "simple_test.R"]
Including R objects works similar to resources, using the argument save_image
. The argument can be set to TRUE
to save all objects of the current workspace to an .RData file, which is then copied to the container’s working directory and loaded on startup (based on save.image()
).
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y git-core \
libcurl4-openssl-dev \
libssl-dev \
libudunits2-dev \
libxml2-dev \
make \
pandoc \
pandoc-citeproc
RUN ["install2.r", "assertthat", "automagic", "backports", "callr", "class", "classInt", "cli", "codetools", "commonmark", "crayon", "curl", "DBI", "desc", "devtools", "digest", "e1071", "evaluate", "FNN", "formatR", "fortunes", "fs", "futile.logger", "futile.options", "glue", "gstat", "htmltools", "httpuv", "intervals", "jsonlite", "KernSmooth", "knitr", "lambda.r", "later", "lattice", "magrittr", "MASS", "memoise", "mime", "miniUI", "pillar", "pkgbuild", "pkgconfig", "pkgdown", "pkgload", "prettyunits", "processx", "promises", "ps", "purrr", "R6", "Rcpp", "remotes", "rjson", "rlang", "rmarkdown", "roxygen2", "rprojroot", "rstudioapi", "semver", "sessioninfo", "shiny", "shinyFiles", "sp", "spacetime", "stevedore", "stringi", "stringr", "testthat", "tibble", "units", "usethis", "versions", "withr", "xfun", "xml2", "xtable", "xts", "yaml", "zoo"]
WORKDIR /payload/
COPY [".RData", ".RData"]
CMD ["R"]
Alternatively, a object names as well as other arguments can be passed as a list, which then are passed to the save()
function.
require("fortunes")
rm(list = ls())
calculation <- 41 + 1
frtn <- fortunes::fortune()
original_sessionInfo <- sessionInfo()
the_dockerfile <- dockerfile(silent = TRUE,
save_image = list("original_sessionInfo", "frtn"))
FROM rocker/r-ver:3.6.1
LABEL maintainer="daniel"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y git-core \
libcurl4-openssl-dev \
libssl-dev \
libudunits2-dev \
libxml2-dev \
make \
pandoc \
pandoc-citeproc
RUN ["install2.r", "assertthat", "automagic", "backports", "callr", "class", "classInt", "cli", "codetools", "commonmark", "crayon", "curl", "DBI", "desc", "devtools", "digest", "e1071", "evaluate", "FNN", "formatR", "fortunes", "fs", "futile.logger", "futile.options", "glue", "gstat", "htmltools", "httpuv", "intervals", "jsonlite", "KernSmooth", "knitr", "lambda.r", "later", "lattice", "magrittr", "MASS", "memoise", "mime", "miniUI", "pillar", "pkgbuild", "pkgconfig", "pkgdown", "pkgload", "prettyunits", "processx", "promises", "ps", "purrr", "R6", "Rcpp", "remotes", "rjson", "rlang", "rmarkdown", "roxygen2", "rprojroot", "rstudioapi", "semver", "sessioninfo", "shiny", "shinyFiles", "sp", "spacetime", "stevedore", "stringi", "stringr", "testthat", "tibble", "units", "usethis", "versions", "withr", "xfun", "xml2", "xtable", "xts", "yaml", "zoo"]
WORKDIR /payload/
COPY [".RData", ".RData"]
CMD ["R"]
Metadata can be added to Docker images using Label instructions. Label instructions are key-value pairs of arbitrary content. A dublicate key overwrites existing ones. Although it is up to the user how many labels are created, it is recommended to bundle them into one Label instruction in the Dockerfile. Each use of the Label()
function creates a seperate instruction in the Dockerfile.
As shown in section 2, the maintainer label is set by default to the top as the dockerfile and contains the username of the current host system. The maintainer can be changed with the maintainer
argument of dockerfile()
:
Labels can be applied to the existing Dockerfile object using the addInstructions()
function, which adds any newly created instructions to the end of the Dockerfile but before the CMD statement. The Label()
constructor can be used for creating labels of arbitrary content and works similar to creating named lists in R.
# A simple label that occupies one line:
label1 <- Label(key1 = "this", key2 = "that", otherKey = "content")
addInstruction(labeled_dockerfile) <- label1
#label with fixed namespace for all keys
label2 <- Label("name"="A name", "description" = "A description", label_ns = "my.label.ns.")
# A multiline label with one key/value pair per line
label3 <- Label("info.o2r.name" = "myProject_ImageName", "org.label-schema.name"="ImageName",
"yet.another_labelname"="true", multi_line = TRUE)
addInstruction(labeled_dockerfile) <- list(label2, label3)
Metadata according to the Label Schema conventions can be created with a function constructed by the helper factory LabelSchemaFactory()
.
Label_LabelSchema <- LabelSchemaFactory()
label <- Label_LabelSchema(name = "ImageName", description = "Description of the image", build_date = Sys.time())
addInstruction(labeled_dockerfile) <- label
You can also put session information, using either base R or devtools
, into a label as plain text or as json:
addInstruction(labeled_dockerfile) <- Label_SessionInfo(session = clean_session())
addInstruction(labeled_dockerfile) <- Label_SessionInfo(session = devtools::session_info(), as_json = TRUE)
The resulting Dockerfile with all the labels:
FROM rocker/r-ver:3.6.1
LABEL maintainer="Jon_Doe@example.com"
RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
&& apt-get install -y libcurl4-openssl-dev \
libssl-dev \
make
RUN ["install2.r", "assertthat", "backports", "crayon", "curl", "desc", "digest", "formatR", "fs", "futile.logger", "futile.options", "htmltools", "httpuv", "jsonlite", "lambda.r", "later", "magrittr", "mime", "miniUI", "pillar", "pkgconfig", "promises", "R6", "Rcpp", "rlang", "rprojroot", "rstudioapi", "semver", "shiny", "shinyFiles", "stevedore", "stringi", "stringr", "tibble", "versions", "xtable"]
WORKDIR /payload/
LABEL key1="this" key2="that" otherKey="content"
LABEL my.label.ns.name="A name" my.label.ns.description="A description"
LABEL info.o2r.name="myProject_ImageName" \
org.label-schema.name="ImageName" \
yet.another_labelname="true"
LABEL org.label-schema.schema-version="1.0.0-rc.1" \
org.label-schema.build-date="2019-08-20T16:46:13+0200" \
org.label-schema.name="ImageName" \
org.label-schema.description="Description of the image"
LABEL R.session-info="R version 3.6.1 (2019-07-05)\nPlatform: x86_64-pc-linux-gnu (64-bit)\nRunning under: Ubuntu 19.04\n\nMatrix products: default\nBLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.8.0\nLAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.8.0\n\nlocale:\n [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C \n [3] LC_TIME=de_DE.UTF-8 LC_COLLATE=en_US.UTF-8 \n [5] LC_MONETARY=de_DE.UTF-8 LC_MESSAGES=en_US.UTF-8 \n [7] LC_PAPER=de_DE.UTF-8 LC_NAME=C \n [9] LC_ADDRESS=C LC_TELEPHONE=C \n[11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C \n\nattached base packages:\n[1] stats graphics grDevices utils datasets methods base \n\nloaded via a namespace (and not attached):\n [1] Rcpp_1.0.2 rstudioapi_0.10 magrittr_1.5 \n [4] containerit_0.5.0 xtable_1.8-4 R6_2.4.0 \n [7] rlang_0.4.0 stringr_1.4.0 versions_0.3 \n[10] tools_3.6.1 stevedore_0.9.1 miniUI_0.1.1.1 \n[13] lambda.r_1.2.3 futile.logger_1.4.3 semver_0.2.0 \n[16] htmltools_0.3.6 shinyFiles_0.7.3 digest_0.6.20 \n[19] assertthat_0.2.1 rprojroot_1.3-2 tibble_2.1.3 \n[22] crayon_1.3.4 shiny_1.3.2 formatR_1.7 \n[25] later_0.8.0 promises_1.0.1 fs_1.3.1 \n[28] futile.options_1.0.1 curl_4.0 mime_0.7 \n[31] stringi_1.4.3 pillar_1.4.2 compiler_3.6.1 \n[34] desc_1.2.0 backports_1.1.4 jsonlite_1.6 \n[37] httpuv_1.5.1 pkgconfig_2.0.2 "
LABEL R.session-info="{\"platform\":{\"version\":\"R version 3.6.1 (2019-07-05)\",\"os\":\"Ubuntu 19.04\",\"system\":\"x86_64, linux-gnu\",\"ui\":\"X11\",\"language\":\"(EN)\",\"collate\":\"en_US.UTF-8\",\"ctype\":\"en_US.UTF-8\",\"tz\":\"Europe/Berlin\",\"date\":\"2019-08-20\"},\"packages\":{\"package\":[\"assertthat\",\"automagic\",\"backports\",\"callr\",\"class\",\"classInt\",\"cli\",\"codetools\",\"commonmark\",\"containerit\",\"crayon\",\"curl\",\"DBI\",\"desc\",\"devtools\",\"digest\",\"e1071\",\"evaluate\",\"FNN\",\"formatR\",\"fortunes\",\"fs\",\"futile.logger\",\"futile.options\",\"glue\",\"gstat\",\"htmltools\",\"httpuv\",\"intervals\",\"jsonlite\",\"KernSmooth\",\"knitr\",\"lambda.r\",\"later\",\"lattice\",\"magrittr\",\"MASS\",\"memoise\",\"mime\",\"miniUI\",\"pillar\",\"pkgbuild\",\"pkgconfig\",\"pkgdown\",\"pkgload\",\"prettyunits\",\"processx\",\"promises\",\"ps\",\"purrr\",\"R6\",\"Rcpp\",\"remotes\",\"rjson\",\"rlang\",\"rmarkdown\",\"roxygen2\",\"rprojroot\",\"rstudioapi\",\"semver\",\"sessioninfo\",\"shiny\",\"shinyFiles\",\"sp\",\"spacetime\",\"stevedore\",\"stringi\",\"stringr\",\"testthat\",\"tibble\",\"units\",\"usethis\",\"versions\",\"withr\",\"xfun\",\"xml2\",\"xtable\",\"xts\",\"yaml\",\"zoo\"],\"ondiskversion\":[\"0.2.1\",\"0.5.1\",\"1.1.4\",\"3.3.1\",\"7.3.15\",\"0.4.1\",\"1.1.0\",\"0.2.16\",\"1.7\",\"0.5.0\",\"1.3.4\",\"4.0\",\"1.0.0\",\"1.2.0\",\"2.1.0\",\"0.6.20\",\"1.7.2\",\"0.14\",\"1.1.3\",\"1.7\",\"1.5.4\",\"1.3.1\",\"1.4.3\",\"1.0.1\",\"1.3.1\",\"2.0.2\",\"0.3.6\",\"1.5.1\",\"0.15.1\",\"1.6\",\"2.23.15\",\"1.24\",\"1.2.3\",\"0.8.0\",\"0.20.38\",\"1.5\",\"7.3.51.4\",\"1.1.0\",\"0.7\",\"0.1.1.1\",\"1.4.2\",\"1.0.4\",\"2.0.2\",\"1.3.0\",\"1.0.2\",\"1.0.2\",\"3.4.1\",\"1.0.1\",\"1.3.0\",\"0.3.2\",\"2.4.0\",\"1.0.2\",\"2.1.0\",\"0.2.20\",\"0.4.0\",\"1.14\",\"6.1.1\",\"1.3.2\",\"0.10\",\"0.2.0\",\"1.1.1\",\"1.3.2\",\"0.7.3\",\"1.3.1\",\"1.2.2\",\"0.9.1\",\"1.4.3\",\"1.4.0\",\"2.2.1\",\"2.1.3\",\"0.6.3\",\"1.5.1\",\"0.3\",\"2.1.2\",\"0.8\",\"1.2.2\",\"1.8.4\",\"0.11.2\",\"2.2.0\",\"1.8.6\"],\"loadedversion\":[\"0.2.1\",\"0.5.1\",\"1.1.4\",\"3.3.1\",\"7.3-15\",\"0.4-1\",\"1.1.0\",\"0.2-16\",\"1.7\",\"0.5.0\",\"1.3.4\",\"4.0\",\"1.0.0\",\"1.2.0\",\"2.1.0\",\"0.6.20\",\"1.7-2\",\"0.14\",\"1.1.3\",\"1.7\",\"1.5-4\",\"1.3.1\",\"1.4.3\",\"1.0.1\",\"1.3.1\",\"2.0-2\",\"0.3.6\",\"1.5.1\",\"0.15.1\",\"1.6\",\"2.23-15\",\"1.24\",\"1.2.3\",\"0.8.0\",\"0.20-38\",\"1.5\",\"7.3-51.4\",\"1.1.0\",\"0.7\",\"0.1.1.1\",\"1.4.2\",\"1.0.4\",\"2.0.2\",\"1.3.0\",\"1.0.2\",\"1.0.2\",\"3.4.1\",\"1.0.1\",\"1.3.0\",\"0.3.2\",\"2.4.0\",\"1.0.2\",\"2.1.0\",\"0.2.20\",\"0.4.0\",\"1.14\",\"6.1.1\",\"1.3-2\",\"0.10\",\"0.2.0\",\"1.1.1\",\"1.3.2\",\"0.7.3\",\"1.3-1\",\"1.2-2\",\"0.9.1\",\"1.4.3\",\"1.4.0\",\"2.2.1\",\"2.1.3\",\"0.6-3\",\"1.5.1\",\"0.3\",\"2.1.2\",\"0.8\",\"1.2.2\",\"1.8-4\",\"0.11-2\",\"2.2.0\",\"1.8-6\"],\"path\":[\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/assertthat\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/automagic\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/backports\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/callr\",\"/usr/lib/R/library/class\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/classInt\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/cli\",\"/usr/lib/R/library/codetools\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/commonmark\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/containerit\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/crayon\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/curl\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/DBI\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/desc\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/devtools\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/digest\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/e1071\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/evaluate\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/FNN\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/formatR\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/fortunes\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/fs\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/futile.logger\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/futile.options\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/glue\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/gstat\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/htmltools\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/httpuv\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/intervals\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/jsonlite\",\"/usr/lib/R/library/KernSmooth\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/knitr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/lambda.r\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/later\",\"/usr/lib/R/library/lattice\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/magrittr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/MASS\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/memoise\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/mime\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/miniUI\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pillar\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgbuild\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgconfig\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgdown\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgload\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/prettyunits\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/processx\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/promises\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/ps\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/purrr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/R6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/Rcpp\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/remotes\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rjson\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rlang\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rmarkdown\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/roxygen2\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rprojroot\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rstudioapi\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/semver\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/sessioninfo\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/shiny\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/shinyFiles\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/sp\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/spacetime\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/stevedore\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/stringi\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/stringr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/testthat\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/tibble\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/units\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/usethis\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/versions\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/withr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xfun\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xml2\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xtable\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xts\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/yaml\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/zoo\"],\"loadedpath\":[\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/assertthat\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/automagic\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/backports\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/callr\",\"/usr/lib/R/library/class\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/classInt\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/cli\",\"/usr/lib/R/library/codetools\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/commonmark\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/containerit\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/crayon\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/curl\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/DBI\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/desc\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/devtools\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/digest\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/e1071\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/evaluate\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/FNN\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/formatR\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/fortunes\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/fs\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/futile.logger\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/futile.options\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/glue\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/gstat\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/htmltools\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/httpuv\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/intervals\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/jsonlite\",\"/usr/lib/R/library/KernSmooth\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/knitr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/lambda.r\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/later\",\"/usr/lib/R/library/lattice\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/magrittr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/MASS\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/memoise\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/mime\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/miniUI\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pillar\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgbuild\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgconfig\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgdown\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/pkgload\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/prettyunits\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/processx\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/promises\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/ps\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/purrr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/R6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/Rcpp\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/remotes\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rjson\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rlang\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rmarkdown\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/roxygen2\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rprojroot\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/rstudioapi\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/semver\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/sessioninfo\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/shiny\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/shinyFiles\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/sp\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/spacetime\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/stevedore\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/stringi\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/stringr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/testthat\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/tibble\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/units\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/usethis\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/versions\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/withr\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xfun\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xml2\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xtable\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/xts\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/yaml\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6/zoo\"],\"attached\":[false,false,false,false,false,false,false,false,false,true,false,false,false,false,true,false,false,false,false,false,true,false,false,false,false,true,false,false,false,false,false,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,true,false,false,true,false,false,false,false,false,false,false,true,false,false,false,false,false,false,false,false],\"is_base\":[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false],\"date\":[\"2019-03-21\",\"2019-03-05\",\"2019-04-10\",\"2019-07-18\",\"2019-01-01\",\"2019-08-06\",\"2019-03-19\",\"2018-12-24\",\"2018-12-01\",\"2019-08-20\",\"2017-09-16\",\"2019-07-22\",\"2018-05-02\",\"2018-05-01\",\"2019-07-06\",\"2019-07-04\",\"2019-06-05\",\"2019-05-28\",\"2019-02-15\",\"2019-06-11\",\"2016-12-29\",\"2019-05-06\",\"2016-07-10\",\"2018-04-20\",\"2019-03-12\",\"2019-05-16\",\"2017-04-28\",\"2019-04-05\",\"2015-08-27\",\"2018-12-07\",\"2015-06-29\",\"2019-08-08\",\"2018-05-17\",\"2019-02-11\",\"2018-11-04\",\"2014-11-22\",\"2019-04-26\",\"2017-04-21\",\"2019-06-11\",\"2018-05-18\",\"2019-06-29\",\"2019-08-05\",\"2018-08-16\",\"2018-12-07\",\"2018-10-29\",\"2015-07-13\",\"2019-07-18\",\"2018-04-13\",\"2018-12-21\",\"2019-03-15\",\"2019-02-14\",\"2019-07-25\",\"2019-06-24\",\"2018-06-08\",\"2019-06-25\",\"2019-07-12\",\"2018-11-07\",\"2018-01-03\",\"2019-03-19\",\"2017-01-06\",\"2018-11-05\",\"2019-04-22\",\"2019-04-30\",\"2018-06-05\",\"2018-07-17\",\"2019-01-02\",\"2019-03-12\",\"2019-02-10\",\"2019-07-25\",\"2019-06-06\",\"2019-05-03\",\"2019-07-04\",\"2016-09-01\",\"2018-03-15\",\"2019-06-25\",\"2019-08-09\",\"2019-04-21\",\"2018-11-05\",\"2018-07-25\",\"2019-05-28\"],\"source\":[\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.0)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.0)\",\"CRAN (R 3.6.1)\",\"local\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.0)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.0)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\",\"CRAN (R 3.6.1)\"],\"md5ok\":[\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\",\"NA\"],\"library\":[\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/usr/lib/R/library\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/usr/lib/R/library\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/usr/lib/R/library\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/usr/lib/R/library\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\",\"/home/daniel/R/x86_64-pc-linux-gnu-library/3.6\"]}}"
CMD ["R"]
If a Dockerfile contains a web service, specific ports of a running container might need to be exposed.
The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. [..] It functions as a type of documentation between the person who builds the image and the person who runs the container, [..] To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports [..] (Docker docs)
dockerfile_with_expose <- dockerfile()
my_port_1 <- Expose(8000)
my_port_2 <- Expose(port = "80/tcp", host = 8080)
addInstruction(dockerfile_with_expose) <- list(my_port_1, my_port_2)
print(dockerfile_with_expose)
## FROM rocker/r-ver:3.6.1
## LABEL maintainer="daniel"
## RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
## && apt-get install -y git-core \
## libcurl4-openssl-dev \
## libssl-dev \
## libudunits2-dev \
## libxml2-dev \
## make \
## pandoc \
## pandoc-citeproc
## RUN ["install2.r", "assertthat", "automagic", "backports", "callr", "class", "classInt", "cli", "codetools", "commonmark", "crayon", "curl", "DBI", "desc", "devtools", "digest", "e1071", "evaluate", "FNN", "formatR", "fortunes", "fs", "futile.logger", "futile.options", "glue", "gstat", "htmltools", "httpuv", "intervals", "jsonlite", "KernSmooth", "knitr", "lambda.r", "later", "lattice", "magrittr", "MASS", "memoise", "mime", "miniUI", "pillar", "pkgbuild", "pkgconfig", "pkgdown", "pkgload", "prettyunits", "processx", "promises", "ps", "purrr", "R6", "Rcpp", "remotes", "rjson", "rlang", "rmarkdown", "roxygen2", "rprojroot", "rstudioapi", "semver", "sessioninfo", "shiny", "shinyFiles", "sp", "spacetime", "stevedore", "stringi", "stringr", "testthat", "tibble", "units", "usethis", "versions", "withr", "xfun", "xml2", "xtable", "xts", "yaml", "zoo"]
## WORKDIR /payload/
## EXPOSE 8000
## EXPOSE 8080 80/tcp
## CMD ["R"]
The ENTRYPOINT
instruction allows using a container like a binary executable. The actually executed command is constructed from both ENTRYPOINT
and CMD
instructions - please check the Docker docs for details. The entrypoint
parameter of the dockerfile()
function supports both “forms” as shown below.
ep_exec <- Entrypoint(program = "R",
params = list(
"-e",
"pr <- plumber::plumb(commandArgs()[4]); pr$run(host='0.0.0.0', port=8080)"),
form = "exec")
dockerfile_with_entrypoint <- dockerfile(from = NULL,
image = "trestletech/plumber",
entrypoint = ep_exec,
cmd = Cmd("schedule.R"))
print(dockerfile_with_entrypoint)
## FROM trestletech/plumber
## LABEL maintainer="daniel"
## WORKDIR /payload/
## ENTRYPOINT ["R", "-e", "pr <- plumber::plumb(commandArgs()[4]); pr$run(host='0.0.0.0', port=8080)"]
## CMD ["schedule.R"]
ep_shell <- Entrypoint(program = "R",
params = list(
"-e",
"pr <- plumber::plumb(commandArgs()[4]); pr$run(host='0.0.0.0', port=8080)"),
form = "shell")
dockerfile_with_entrypoint <- dockerfile(from = NULL,
image = "trestletech/plumber",
entrypoint = ep_shell,
cmd = Cmd("schedule.R", form = "shell"))
print(dockerfile_with_entrypoint)
## FROM trestletech/plumber
## LABEL maintainer="daniel"
## WORKDIR /payload/
## ENTRYPOINT R -e pr <- plumber::plumb(commandArgs()[4]); pr$run(host='0.0.0.0', port=8080)
## CMD schedule.R
The dockerfile()
function allows further customization regarding the R version or the used base image (cf. Rocker stack). Note that while choosing an R version for the Dockerfile explicitly is possible, the session to generate the required information (i.e. which packages are attached etc.) is still running the R version of the generating machine.
The following examples show usage of these options and the respective FROM
statements in the Dockerfile.
df_custom <- dockerfile(from = NULL, image = getImageForVersion("3.3.3"), silent = TRUE)
print(df_custom@image)
FROM rocker/r-ver:3.3.3
df_custom <- dockerfile(from = NULL, image = "rocker/geospatial", silent = TRUE)
print(df_custom@image)
FROM rocker/geospatial
df_custom <- dockerfile(from = NULL, image = "rocker/verse:3.0.0", silent = TRUE)@image
print(df_custom@image)
[1] "rocker/verse"
When you change the base image, you might not want to re-install packages that are already in the base image. The helper function get_installed_packages()
is used internally to filter the installed packages and can be activated with filter_baseimage_pkgs
.
expressions <- c(expression(library("sp")))
session <- clean_session(expressions, echo = TRUE)
df_filtered <- dockerfile(from = session, maintainer = "o2r",
image = "rocker/geospatial:3.4.4",
filter_baseimage_pkgs = TRUE)
Detected API version '1.40' is above max version '1.39'; downgrading
Detected API version '1.40' is above max version '1.39'; downgrading
## FROM rocker/geospatial:3.4.4
## LABEL maintainer="o2r"
## # CRAN packages skipped because they are in the base image: assertthat, backports, crayon, curl, desc, digest, formatR, htmltools, httpuv, jsonlite, later, lattice, magrittr, mime, miniUI, pillar, pkgconfig, promises, R6, Rcpp, rlang, rprojroot, rstudioapi, shiny, sp, stringi, stringr, tibble, xtable
## RUN export DEBIAN_FRONTEND=noninteractive; apt-get -y update \
## && apt-get install -y make
## RUN ["install2.r", "fs", "futile.logger", "futile.options", "lambda.r", "semver", "shinyFiles", "stevedore", "versions"]
## WORKDIR /payload/
## CMD ["R"]
A command line interface to the package functions is also available for Linux based on docopt.R. This allows integration into workflows and tools written in other programming languages than R.
You can make the command containerit
available on your maching by linking the R script file delivered with the package as follows:
ln -s $(Rscript -e "cat(system.file(\"cli/container_it.R\", package=\"containerit\"))") /usr/local/bin/containerit
CLI Examples:
containerit --help
# runs the first R markdown or R script file locally
# prints Dockerfile without writing a file
containerit dir -p --no-write
# Packages R-script
# saves a workspace image (-i parameter)
# Writes Dockerfile (overwrite with -f)
# execute the script on start-up
containerit file -ifp --cmd-R-file path/example.R
# Creates an empty R session with the given R commands
# Set R version of the container to 3.3.0
containerit session -p -e "library(sp)" -e "demo(meuse, ask=FALSE)"
We encountered several challenges during containerit
’s development. First and foremost, a well known limitation is that R packages don’t define system dependencies and do not provide explicit versions for R package dependencies. The sysreqs
package is a promising approach towards handling system requirements, but so far lists package names but does not provide version information. The shinyapps-package-dependencies demonstrate a (currently system dependent) alternative. The high value of R might well lie in the fact that “packages currently on CRAN” should work well with each other.
An unmet challenge so far is the installation of specific versions of external libraries (see issue). A package like sf
relies on well-tested and powerful system libraries, see sf::sf_extSoftVersion()
, which ideally should be matched in the created container.
And of course users may do things that containerit
cannot capture from the session state “after the analysis is completed”, such as detaching packages or removing relevant files, and unknown side-effects might occur.
All software is presumed to be installed and run on the host system. Although it is possible to use deviating versions of R or even create Dockerfiles using sessionInfo-objects created on a different host, this may lead to unexpected errors because the setup cannot be tested locally.
containerit
alows to create and costumize Dockerfiles with minimal effort, which are suitable for packaging R analyses in the persistant runtime environment of a software container. So far, we were able to reproduce complete R sessions regarding loaded and attached packages and mitigate some challenges towards reproducible computational research.
Although we are able to package different versions of R, we still do not fully support the installation of specific versions of R packages and external software libraries, which R itself does not support. This should be tested in the future by evaluating version-stable package repositories like MRAN and GRAN or utility packages such as packrat – see the GitHub issues for the status of these plans or provide your own ideas there.
Related to installing specific versions is support for other package repositories, such as Bioconductor, git, BitBucket, or even local files. For now, it is recommended that users have all software up-to-date when building a software container, as the latest version are installed from CRAN during the image build, to have matching package versions between the creation runtime environment and the container. All Dockerfiles and instructions are adjusted to the Rocker image stack and assume a Debian/Linux operating system. As we are not yet supporting the build of Docker images from scratch, we are restricted to this setup.
The package is a first prototype available via GitHub. While a publication on CRAN is a goal, it should be preceded by feedback from the user community and ideally be accompanied by related packages, such as stevedore
, being available on CRAN, too. The prototype of containerit
was developed and tested only on Ubuntu/Linux, which should be extended before releasing a stable version on CRAN.
As part of the o2r project, it is planned to integrate containerit
in a web service for creating archivable research in form of Executable Research Compendia (ERC). Making containerit
itself easier to use for end-users is a secondary but worthwhile goal, for example by building a graphical user interface for metadata creation. Country locales are also not supported yet. We may want to support other container OS (e.g. windows container or other Linux distributions) or even containerization solutions such as Singularity or the Open Container Initiative’s (OCI) Image Format.
Feedback and contributions are highly welcome on GitHub or o2r_project on Twitter.
## R version 3.6.1 (2019-07-05)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 19.04
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.8.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.8.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=de_DE.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=de_DE.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=de_DE.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] remotes_2.1.0 fortunes_1.5-4 sessioninfo_1.1.1 devtools_2.1.0
## [5] usethis_1.5.1 sp_1.3-1 gstat_2.0-2 containerit_0.6.0
## [9] knitr_1.24
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.2 lattice_0.20-38 FNN_1.1.3
## [4] prettyunits_1.0.2 class_7.3-15 ps_1.3.0
## [7] zoo_1.8-6 assertthat_0.2.1 rprojroot_1.3-2
## [10] digest_0.6.20 mime_0.7 R6_2.4.0
## [13] futile.options_1.0.1 backports_1.1.4 evaluate_0.14
## [16] e1071_1.7-2 pillar_1.4.2 rlang_0.4.0
## [19] curl_4.0 rstudioapi_0.10 miniUI_0.1.1.1
## [22] callr_3.3.1 rmarkdown_1.14 pkgdown_1.3.0
## [25] desc_1.2.0 stringr_1.4.0 shiny_1.3.2
## [28] compiler_3.6.1 httpuv_1.5.1 xfun_0.8
## [31] pkgconfig_2.0.2 versions_0.3 pkgbuild_1.0.4
## [34] stevedore_0.9.1 htmltools_0.3.6 tibble_2.1.3
## [37] roxygen2_6.1.1 intervals_0.15.1 codetools_0.2-16
## [40] spacetime_1.2-2 withr_2.1.2 crayon_1.3.4
## [43] later_0.8.0 MASS_7.3-51.4 commonmark_1.7
## [46] grid_3.6.1 jsonlite_1.6 xtable_1.8-4
## [49] DBI_1.0.0 magrittr_1.5 formatR_1.7
## [52] semver_0.2.0 units_0.6-3 KernSmooth_2.23-15
## [55] cli_1.1.0 stringi_1.4.3 fs_1.3.1
## [58] promises_1.0.1 testthat_2.2.1 xml2_1.2.2
## [61] futile.logger_1.4.3 shinyFiles_0.7.3 xts_0.11-2
## [64] rjson_0.2.20 lambda.r_1.2.3 tools_3.6.1
## [67] glue_1.3.1 purrr_0.3.2 pkgload_1.0.2
## [70] processx_3.4.1 yaml_2.2.0 automagic_0.5.1
## [73] classInt_0.4-1 memoise_1.1.0
4.4 Comments
Comments can be added to a Dockerfile. By default they are the last instruction.