| Title: | Containerize Your 'R' Project |
|---|---|
| Description: | Provides tools for containerizing 'R' projects. Reads an 'renv' lock file, generates a ready-to-use 'Dockerfile', builds the container image, and pushes it to a registry. Generated 'COPY' instructions preserve the local directory structure inside the container. Cross-platform builds are supported via 'Docker' buildx for targeting 'linux/amd64' from ARM hosts. Designed to help researchers build portable, reproducible workflows that can be reliably shared, archived, and rerun across systems. See R Core Team (2025) <https://www.R-project.org/>, Ushey et al. (2025) <https://CRAN.R-project.org/package=renv>, and Docker Inc. (2025) <https://www.docker.com/>. |
| Authors: | Erwin Lares [aut, cre] (ORCID: <https://orcid.org/0000-0002-3284-828X>) |
| Maintainer: | Erwin Lares <[email protected]> |
| License: | Apache License (>= 2) |
| Version: | 0.1.3.9000 |
| Built: | 2026-05-20 19:25:21 UTC |
| Source: | https://github.com/erwinlares/containr |
build_image() builds a container image from a Dockerfile using either
podman or docker. It auto-detects which tool is available on the system
unless tool is specified explicitly. Use dry_run = TRUE to preview the
exact command that would be run without executing it.
build_image( dockerfile = "Dockerfile", tag = NULL, platform = "linux/amd64", tool = NULL, dry_run = FALSE, verbose = FALSE, comments = FALSE )build_image( dockerfile = "Dockerfile", tag = NULL, platform = "linux/amd64", tool = NULL, dry_run = FALSE, verbose = FALSE, comments = FALSE )
dockerfile |
A character string. Path to the |
tag |
A character string or |
platform |
A character string or |
tool |
A character string or |
dry_run |
Logical. If |
verbose |
Logical. If |
comments |
Logical. If |
When the target platform differs from the host architecture (e.g.
building linux/amd64 on an Apple Silicon Mac), build_image()
automatically uses docker buildx build instead of docker build, and
includes --load to ensure the image is available in the local store.
For podman, --platform is passed directly to podman build.
Called for its side effects. Returns invisible(NULL).
Before calling build_image(), ensure the following are in place:
A Dockerfile exists at dockerfile. Use
generate_dockerfile() to create one if needed.
An renv.lock file is present in the build context – the generated
Dockerfile uses it to restore the R package environment inside the
container.
Either podman or docker is installed and the daemon (for docker)
or the Podman service is running. Verify with podman info or
docker info in a terminal.
Building for a different architecture than the host requires emulation.
On Apple Silicon Macs, building linux/amd64 images uses QEMU emulation
under Podman, which can be slow and unstable. Docker Desktop handles
cross-platform builds more reliably via buildx and Rosetta 2.
If builds fail with QEMU segfaults, consider:
Using Docker Desktop instead of Podman (tool = "docker")
Building on a native x86_64 machine (e.g. via GitHub Actions)
Building directly on the target cluster if it supports container builds
For UW-Madison CHTC, the full tag format is:
registry.doit.wisc.edu/<netid>/<image-name>:<version>
For example: registry.doit.wisc.edu/erwin.lares/my-analysis:1.0.0
The version tag defaults to latest if omitted. Using explicit version
tags (e.g. 1.0.0) is recommended for reproducibility – latest will
be overwritten each time you push.
## Not run: # Build for linux/amd64 (default) with auto-detected tool build_image() # Build and tag for CHTC registry build_image(tag = "registry.doit.wisc.edu/netid/my-analysis:1.0.0") # Build for the host architecture (no --platform flag) build_image(platform = NULL) # Build for ARM64 (e.g. local use on Apple Silicon) build_image(platform = "linux/arm64") # Preview the build command without running it build_image( tag = "registry.doit.wisc.edu/netid/my-analysis:1.0.0", dry_run = TRUE ) # Guided build for first-time users build_image( tag = "registry.doit.wisc.edu/netid/my-analysis:1.0.0", verbose = TRUE, comments = TRUE ) ## End(Not run)## Not run: # Build for linux/amd64 (default) with auto-detected tool build_image() # Build and tag for CHTC registry build_image(tag = "registry.doit.wisc.edu/netid/my-analysis:1.0.0") # Build for the host architecture (no --platform flag) build_image(platform = NULL) # Build for ARM64 (e.g. local use on Apple Silicon) build_image(platform = "linux/arm64") # Preview the build command without running it build_image( tag = "registry.doit.wisc.edu/netid/my-analysis:1.0.0", dry_run = TRUE ) # Guided build for first-time users build_image( tag = "registry.doit.wisc.edu/netid/my-analysis:1.0.0", verbose = TRUE, comments = TRUE ) ## End(Not run)
generate_dockerfile() inspects an R project's dependencies via an renv
lockfile and writes a ready-to-use Dockerfile to the specified output
directory. It supports multiple Rocker base images, automatic system
library detection, Quarto installation, file copying, user creation, and
inline documentation comments.
generate_dockerfile( r_version = "current", r_mode = "base", auto_syslibs = TRUE, install_syslibs = NULL, output = tempdir(), data_file = NULL, code_file = NULL, misc_file = NULL, add_user = NULL, home_dir = "/home", expose_port = "8787", install_quarto = FALSE, comments = FALSE, verbose = FALSE )generate_dockerfile( r_version = "current", r_mode = "base", auto_syslibs = TRUE, install_syslibs = NULL, output = tempdir(), data_file = NULL, code_file = NULL, misc_file = NULL, add_user = NULL, home_dir = "/home", expose_port = "8787", install_quarto = FALSE, comments = FALSE, verbose = FALSE )
r_version |
A character string specifying the R version to use, e.g.
|
r_mode |
A character string selecting the Rocker base image. Inspired
by the Rocker Project. One of |
auto_syslibs |
Logical. If |
install_syslibs |
A character vector or |
output |
A character string. Directory path where the |
data_file |
A character string or |
code_file |
A character string or |
misc_file |
A character string or |
add_user |
A character string. Name of a Linux user to create inside
the container with sudo access. Defaults to |
home_dir |
A character string. The working directory set inside the
container via |
expose_port |
A character string. The port to expose when |
install_quarto |
Logical. If |
comments |
Logical. If |
verbose |
Logical. If |
Called for its side effects. Writes a Dockerfile to output.
Returns invisible(NULL).
generate_dockerfile() requires an renv.lock file in the current working
directory. Create one with renv::snapshot() before calling this function.
If the lock file is out of sync with your project library, a warning is
issued – run renv::snapshot() to update it before building the image.
## Not run: # Requires renv.lock in the current working directory. # Run renv::snapshot() first if you don't have one. # Generate a minimal Dockerfile using a pinned R version generate_dockerfile(r_version = "4.4.0", output = tempdir()) # Pin a specific R version with the tidyverse image generate_dockerfile(r_version = "4.3.0", r_mode = "tidyverse", output = tempdir()) # Add extra system libraries on top of auto-detected ones generate_dockerfile( r_version = "4.4.0", install_syslibs = c("libuv1-dev", "libwebp-dev"), output = "." ) # Include a data file -- directory structure is preserved in the container generate_dockerfile( r_version = "4.3.0", data_file = "data-raw/penguins.csv", code_file = "analysis.R", comments = TRUE, output = "." ) ## End(Not run)## Not run: # Requires renv.lock in the current working directory. # Run renv::snapshot() first if you don't have one. # Generate a minimal Dockerfile using a pinned R version generate_dockerfile(r_version = "4.4.0", output = tempdir()) # Pin a specific R version with the tidyverse image generate_dockerfile(r_version = "4.3.0", r_mode = "tidyverse", output = tempdir()) # Add extra system libraries on top of auto-detected ones generate_dockerfile( r_version = "4.4.0", install_syslibs = c("libuv1-dev", "libwebp-dev"), output = "." ) # Include a data file -- directory structure is preserved in the container generate_dockerfile( r_version = "4.3.0", data_file = "data-raw/penguins.csv", code_file = "analysis.R", comments = TRUE, output = "." ) ## End(Not run)
list_images() returns a data frame of container images currently stored
in the local image store, as reported by podman image ls or
docker image ls. This is useful for finding the image ID to pass to
push_image() after building an image with build_image().
list_images(tool = NULL, verbose = FALSE)list_images(tool = NULL, verbose = FALSE)
tool |
A character string or |
verbose |
Logical. If |
A data frame with five columns: repository, tag, image_id,
created, and size. Rows where both repository and tag are
<none> correspond to untagged images produced by build_image() when
no tag argument was supplied. The data frame is also printed to the
console. Returns an empty data frame if no images are found.
After calling build_image(), run list_images() to find the image ID
of the image you just built. Untagged images appear with <none> in the
repository and tag columns – the image_id column contains the hash
you need to pass to push_image():
imgs <- list_images() push_image( image_id = imgs$image_id[1], netid = "erwin.lares", project = "container-registry" )
## Not run: # List all local images list_images() # Capture the result for programmatic use imgs <- list_images() imgs$image_id[1] ## End(Not run)## Not run: # List all local images list_images() # Capture the result for programmatic use imgs <- list_images() imgs$image_id[1] ## End(Not run)
push_image() tags a locally built container image with a full registry
path and pushes it to a container registry. It handles both the
podman tag and podman push steps in a single call. Auto-detects
which container tool is available unless tool is specified explicitly.
Use dry_run = TRUE to preview the exact commands without executing them.
The format for the is registry.doit.wisc.edu/
push_image( image_id = NULL, netid = NULL, project = NULL, tag = "latest", registry = "registry.doit.wisc.edu", tool = NULL, check_login = TRUE, dry_run = FALSE, verbose = FALSE, comments = FALSE )push_image( image_id = NULL, netid = NULL, project = NULL, tag = "latest", registry = "registry.doit.wisc.edu", tool = NULL, check_login = TRUE, dry_run = FALSE, verbose = FALSE, comments = FALSE )
image_id |
A character string. The local image ID or name to push,
as shown in |
netid |
A character string. Your UW-Madison NetID, used to construct
the full registry path, e.g. |
project |
A character string. The GitLab project name that hosts the
container registry, e.g. |
tag |
A character string. The version tag to assign to the image.
Defaults to |
registry |
A character string. The registry hostname. Defaults to
|
tool |
A character string or |
check_login |
Logical. If |
dry_run |
Logical. If |
verbose |
Logical. If |
comments |
Logical. If |
Called for its side effects. Returns invisible(NULL).
Before calling push_image(), ensure the following are in place:
The image has been built locally with build_image(). Run
podman image ls to find the image ID.
You have a GitLab account at git.doit.wisc.edu and a project with
the container registry enabled.
You have a Personal Access Token (PAT) with read_registry and
write_registry scopes. Create one at:
https://git.doit.wisc.edu/-/user_settings/personal_access_tokens
You are logged in to the registry. Authenticate once in a terminal:
podman login registry.doit.wisc.edu
Enter your NetID as the username and your PAT as the password.
The GitLab container registry requires authentication before pushing.
Use a Personal Access Token (PAT) rather than your NetID password –
PATs can be scoped to registry access only and revoked independently.
Authentication is cached by podman or docker after the first login,
so you only need to run podman login once per machine per session.
Note that GitLab Self-Managed authentication tokens expire after five
minutes by default. If you see an unauthorized: authentication required
error mid-push on a large image, re-authenticate and push again.
## Not run: # Tag and push an image to the CHTC registry push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry" ) # Push with an explicit version tag push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry", tag = "1.0.0" ) # Preview the commands without running them push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry", dry_run = TRUE ) # Guided push for first-time users push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry", verbose = TRUE, comments = TRUE ) ## End(Not run)## Not run: # Tag and push an image to the CHTC registry push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry" ) # Push with an explicit version tag push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry", tag = "1.0.0" ) # Preview the commands without running them push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry", dry_run = TRUE ) # Guided push for first-time users push_image( image_id = "974123909a36", netid = "erwin.lares", project = "container-registry", verbose = TRUE, comments = TRUE ) ## End(Not run)