Type: | Package |
Title: | Execute R in a 'Docker' Context |
Version: | 0.2.1 |
Description: | The goal of 'jetty' is to execute R functions and code snippets in an isolated R subprocess within a 'Docker' container and return the evaluated results to the local R session. 'jetty' can install necessary packages at runtime and seamlessly propagates errors and outputs from the 'Docker' subprocess back to the main session. 'jetty' is primarily designed for sandboxed testing and quick execution of example code. |
License: | GPL (≥ 3) |
Encoding: | UTF-8 |
Imports: | renv (≥ 1.0.0), rlang |
Suggests: | here, Matrix, ggplot2, testthat (≥ 3.0.0) |
RoxygenNote: | 7.3.2 |
Config/testthat/edition: | 3 |
URL: | https://github.com/dmolitor/jetty, http://www.dmolitor.com/jetty/ |
BugReports: | https://github.com/dmolitor/jetty/issues |
NeedsCompilation: | no |
Packaged: | 2025-04-14 20:02:32 UTC; dmolitor |
Author: | Daniel Molitor [aut, cph, cre] |
Maintainer: | Daniel Molitor <molitdj97@gmail.com> |
Repository: | CRAN |
Date/Publication: | 2025-04-14 22:40:06 UTC |
jetty: Execute R in a 'Docker' Context
Description
The goal of 'jetty' is to execute R functions and code snippets in an isolated R subprocess within a 'Docker' container and return the evaluated results to the local R session. 'jetty' can install necessary packages at runtime and seamlessly propagates errors and outputs from the 'Docker' subprocess back to the main session. 'jetty' is primarily designed for sandboxed testing and quick execution of example code.
Author(s)
Maintainer: Daniel Molitor molitdj97@gmail.com [copyright holder]
See Also
Useful links:
Report bugs at https://github.com/dmolitor/jetty/issues
Execute an R expression inside a Docker container
Description
This function is somewhat similar in spirit to
callr::r()
in that the user can pass
a function (or a code block) to be evaluated. This code will
be executed within the context of a Docker container and the result will be
returned within the local R session.
Usage
run(
func,
args = list(),
image = paste0("r-base:", r_version()),
stdout = "",
stderr = "",
install_dependencies = FALSE,
r_profile = jetty_r_profile(),
r_environ = jetty_r_environ(),
debug = FALSE
)
Arguments
func |
Function object or code block to be executed in the R session
within the Docker container. It is best to reference package functions using
the |
args |
Arguments to pass to the function. Must be a list. |
image |
A string in the |
stdout , stderr |
where output to ‘stdout’ or ‘stderr’ should be sent.
Possible values are "", to the R console (the default), NULL
(discard output), FALSE (discard output), TRUE
(capture the output silently and then discard), or a
character string naming a file. See |
install_dependencies |
A boolean indicating whether jetty should discover packages used in your code and try to install them in the Docker container prior to executing the provided function/expression. In general, things will work better if the Docker image already has all necessary packages installed. |
r_profile , r_environ |
Paths specifying where jetty should search for
the .Rprofile and .Renviron files to transfer to the Docker sub-process.
By default jetty will look for files called ".Rprofile" and ".Renviron"
in the current working directory. If either file is found, they will be
transferred to the Docker sub-process and loaded before executing any
R commands. To explicitly exclude either file, set the value to
|
debug |
A boolean indicating whether to print out the commands that are being executed via the shell. This is mostly helpful to see what is happening when things start to error. |
Value
Value of the evaluated expression.
Side effects
It is important to note that some side effects, e.g. plotting, may be lost since these are being screamed into the void of the Docker container. However, the user has full control over the 'stdterr' and 'stdout' of the R sub-process running in the Docker container, and so side effects such as messages, warnings, and printed output can be directed to the console or captured by the user.
It is also crucial to note that actions on the local file system will not work with jetty sub-processes. For example, reading or writing files to/from the local file system will fail since the R sub-process within the Docker container does not have access to the local file system.
Error handling
jetty will propagate errors from the Docker process to the main process.
That is, if an error is thrown in the Docker process, an error with the same
message will be thrown in the main process. However, because of the
somewhat isolated nature of the local process and the Docker process,
calling functions such as base::traceback()
and rlang::last_trace()
will
not print the callstack of the uncaught error as that has
(in its current form) been lost in the Docker void.
Examples
## Not run:
run(
{
mtcars <- mtcars |>
transform(cyl = as.factor(cyl))
model <- lm(mpg ~ ., data = mtcars)
model
}
)
# A code snippet that requires packages to be installed
run(
{
mtcars <- mtcars |>
dplyr::mutate(cyl = as.factor(cyl))
model <- lm(mpg ~ ., data = mtcars)
model
},
install_dependencies = TRUE
)
# This will error since the `praise` package is not installed
run(function() praise::praise())
# Explicitly tell jetty to ignore an existing .Rprofile
run(function() summary(cars), r_profile = NULL)
## End(Not run)
Execute an R script inside a Docker container
Description
This function is somewhat similar in spirit to
callr::rscript()
in that the user can specify
an R script to be executed within the context of a Docker container.
Usage
run_script(
file,
...,
context = dirname(file),
image = paste0("r-base:", r_version()),
stdout = "",
stderr = "",
install_dependencies = FALSE,
r_profile = jetty_r_profile(),
r_environ = jetty_r_environ(),
debug = FALSE
)
Arguments
file |
A character string giving the pathname of the file to read from. |
... |
Additional arguments to be passed directly to |
context |
The pathname of the directory to serve as the execution context.
This directory will be mounted to the Docker container, which
means that the script will have access to all files/directories that are
within the context directory. The context will also serve as the working
directory from which the script is executed. It is crucial to note that the
script will NOT be able to access any files/directories that are outside the
scope of the context directory. The default value is the directory that
|
image |
A string in the |
stdout , stderr |
where output to ‘stdout’ or ‘stderr’ should be sent.
Possible values are "", to the R console (the default), NULL
(discard output), FALSE (discard output), TRUE
(capture the output silently and then discard), or a
character string naming a file. See |
install_dependencies |
A boolean indicating whether jetty should discover packages used in your code and try to install them in the Docker container prior to executing the provided function/expression. In general, things will work better if the Docker image already has all necessary packages installed. |
r_profile , r_environ |
Paths specifying where jetty should search for
the .Rprofile and .Renviron files to transfer to the Docker sub-process.
By default jetty will look for files called ".Rprofile" and ".Renviron"
in the current working directory. If either file is found, they will be
transferred to the Docker sub-process and loaded before executing any
R commands. To explicitly exclude either file, set the value to
|
debug |
A boolean indicating whether to print out the commands that are being executed via the shell. This is mostly helpful to see what is happening when things start to error. |
Details
NOTE: this feature is still fairly experimental. It will NOT work on Windows. It is only made to be compatible with MacOS and Linux.
Value
The value of the last evaluated expression in the script.
Interaction with the local file system
The user will be asked to specify a context
(local directory)
for executing the R script. jetty mounts this directory to the Docker
container, allowing the script to interact with files within it
(read/write). Attempts to access files outside the context directory
will cause the script to fail. Ensure the context directory includes
all files needed for the script to run.
Error handling
run_script
will handle errors using the same mechanism as
run
. See that documentation for more details.
Examples
## Not run:
# Execute a simple script that has no package dependencies
run_script(file = here::here("code/analysis_script.R"))
# Execute a script that needs access to the entire analysis directory
run_script(
file = here::here("code/analysis_script.R"),
context = here::here()
)
# Execute a script that needs access to the entire analysis directory
# and relies on external packages
run_script(
file = here::here("code/analysis_script.R"),
context = here::here(),
install_dependencies = TRUE
)
# Execute a script and explicitly ignore an existing .Rprofile
run_script(
file = here::here("code/analysis_script.R"),
r_profile = NULL
)
## End(Not run)