- The vendored copy of
{renv}(~30,000 lines underinst/vendor/) is removed. Lockfiles are now parsed withjsonlite::read_json()(already in Imports). The exporteddockerfiler::renvsymbol is removed: it was a public-API surface only because the vendor pattern required it. The fallbackrenv_versionvalue, when both the user argument is missing and the lockfile does not pin renv, is nowNULL(install the latest renv from the configured repos), aligned with the existingrenv_version = NULLbehaviour. Closes #94. dock_from_renv()now defaults to running the runtime container as therstudiouser (previously root). The generated Dockerfile gains a defensiveRUN id -u rstudio || useradd -m -d /home/rstudio -s /bin/bash rstudioearly so the user is created if the FROM image does not already ship one (no-op on rocker/* images, realuseraddonr-base,ubuntu:*,debian:*). The renv cache is auto-derived to/home/<user>/.cache/R/renvand chowned to<user>before theUSERdirective drops privilege; theUSERdirective itself is emitted right before therenv::restore()cache-mount RUN, so every step that needs root (apt-get, R installs) still runs as root. Passuser = NULLto opt out and keep the previous root behaviour. debian/ubuntu only; for alpine-based images you must passuser = NULLand create the user yourself. Closes #100.dock_from_renv()defaultFROMflips from"rocker/r-base"(amd64-only) to"rocker/r-ver"(multi-arch: linux/amd64 + linux/arm64), and the R version from therenv.lockfile is now appended at codegen time (e.g.rocker/r-ver:4.5.0). Apple Silicon and ARM Linux hosts (Ampere, AWS Graviton) now build natively without Rosetta. Pass the legacyFROM = "rocker/r-base"to opt out. Closes #47.dock_from_renv()defaultreposflips from"https://cran.rstudio.com/"(source-only CRAN mirror) to"https://p3m.dev/cran/latest"(Posit Public Package Manager), with automatic rewrite to the__linux__/$VERSION_CODENAME/shape at codegen time so the build pulls pre-compiled Linux binaries instead of compiling from source. Build time on packages with C/C++ deps drops from minutes to seconds. The PPM rewrite logic now matches all three Posit-managed PPM hosts:packagemanager.posit.co,packagemanager.rstudio.com, andp3m.dev. Pass the legacyrepos = c(CRAN = "https://cran.rstudio.com/")to opt out. Closes #57.
dock_from_desc()anddock_from_renv()now validate every user-supplied parameter that flows into a Dockerfile shell context (FROM,AS,reposvalues and names,extra_sysreqs,renv_version,renv_paths_cache,lockfilebasename,use_pak,strict_install, plusr_versionread from the lockfile). Inputs that contain shell metacharacters, newlines, or do not match the documented format raise an explicit error at function entry, rather than silently producing a malformed Dockerfile or one that executes attacker-controlled commands atdocker buildtime. This closes the post-#106 audit follow-up for all five sites surfaced by Copilot review.
dock$ARG()and the internaladd_arg()helper gain adefaultparameter to emitARG <name>=<default>instead ofARG <name>. Closes #8.dock_from_desc()anddock_from_renv()gain agithub_patparameter (default"none") controlling how a GitHub PAT is provided toremotes::install_github()/remotes::install_local()/renv::restore()for private dependency repositories. Set to"build_arg"to emitARG GITHUB_PAT+ENVpropagation (passed via--build-arg GITHUB_PAT=$GITHUB_PAT), or"secret"to use BuildKit secret mounts (the PAT is never persisted in image metadata; recommended for published images). Closes #18.dock_from_renv()gains arenv_paths_cacheparameter that controls theRENV_PATHS_CACHEbuild-arg default, the propagatedENVvalue, and the cache mount target. WhenNULL(the default), the path is auto-derived fromuser:/root/.cache/R/renvforuser = NULL, and/home/<user>/.cache/R/renvotherwise. Users can override the renv cache location at image build time with--build-arg RENV_PATHS_CACHE=...without regenerating the Dockerfile.dock_from_desc()gains astrict_installparameter (defaultTRUE). WhenTRUE, every install RUN in the generated Dockerfile is prefixed withoptions(warn = 2);so any R warning during install (missing CRAN package, partial download, archived package, 404 on a remote) becomes a hard error and aborts the docker build. This is a behaviour change for users regenerating their Dockerfile: install RUNs now refuse to silently swallow warnings. Passstrict_install = FALSEif your build environment routinely emits benign warnings (locale defaulting, NTP time-verification, ABI-version notices) that you do not want to fail the build. Closes #9.
r()no longer silently rewrites user code. The previous implementation calledgsub(" [2,]", " ", code)(a typo for{2,}) which deleted any digit2or comma preceded by a space:r(c(1, 2, 3))returnedR -e 'c(1, , 3)'. The replacement approach (gsub("[ ]{2,}", " ", code)) still collapsed runs of spaces inside string literals (r(cat("a b"))would emitR -e 'cat("a b")'). The fix usestrimws()on eachdeparse()line thenpaste(collapse = " "): only the line-wrap indentation added bydeparse()is removed, internal whitespace is preserved. Closes #95.r()now wraps the deparsed R expression withshQuote(., type = "sh")instead of inlining it inside a hand-rolled single-quoted shell string. Apostrophes inside string literals no longer break the emitted command:r(message("don't"))used to emitR -e 'message("don't")', which the shell refuses to parse (unterminated quoted string). The new wrapping is shell-safe by construction.dock_from_desc(build_from_source = FALSE)no longer carries a dead-code branch (if (missing(out))) on the locally-assigned result ofpkgbuild::build().missing()only reports unsupplied function arguments, so the branch was unreachable; the success path always ran whenbuild()returned. The branch is removed; failures ofpkgbuild::build()propagate normally viastop(). Closes #98.- Small polish bundle (no behavioural changes for end users): fix two
length(x > 0)typos indock_from_desc()(intent waslength(x) > 0); drop a duplicate@exporttag indockerignore.R; use the newdock$ARG(name, default = ...)form internally instead of inlining the=; tighten a previously brittle regression test that checked for any occurrence of"remotes"in the generated Dockerfile.
dock_from_renv()now auto-configures the generated Dockerfile to fetch Linux binaries from Posit Package Manager whenreposis a single CRAN-keyed PPM URL. Four things happen: the PPM URL is rewritten to include__linux__/$VERSION_CODENAME/(resolved at image build time from/etc/os-release) when it wascranorcran/latest;HTTPUserAgentis set to the strict format PPM requires;renv.config.repos.overrideis set so thatrenv::restore()uses PPM instead of the lockfile's repo URL; and the RUN is prefixed with. /etc/os-release &&when the line uses$VERSION_CODENAME. User-pinned codenames and snapshot-date URLs (e.g.cran/2024-01-15) are preserved as-is. The user's PPM scheme and host (so apackagemanager.rstudio.comURL stays on rstudio.com) are preserved on rewrite. Non-PPM repos (including internal mirrors not on the official PPM hosts) and multi-entryreposvectors are left untouched.dock_from_renv()no longer installsremoteswhenrenv_version = NULL, sinceremoteswas only needed for theinstall_version()path.
- feat: allow multistage dockerfile creation
- feat: COPY function can now specify a stage to copy from.
- feat: add dedicated cache for
renv::restore - feat: add COMMENT function to add comment in Dockerfile thanks to @jcrodriguez1989
- remove native pipe thanks to @HenningLorenzen-ext-bayer, this enable to use of older R versions
- update
dock_from_renv()test to catch all output lines
- remove sysreqs.r-hub.io to use {pak} instead for system requirement detection
- move from
pak::pkg_system_requirementstopak::pkg_sysreqs()thanks to @B0ydT dock_from_renvallow to specify user to use in Dockerfile- the
dependenciesparameter indock_from_renvif set toTRUEwill install required dependencies plus optional and development dependencies. defaut isNAonly required (hard) dependencies, - Set the minimum version of the {pak} package to 0.6.0.
- Parameterize the
sysreqs_platformused to find system dependencies in pkg_sysreqs (only debian/ubuntu based images are supported)
-
fix : create a
use_pakparameters indock_from_renvto setrenv.config.pak.enabled = FALSEinstead ofrenv.config.pak.enabled = TRUEto avoid issues with {pak} duringrenv::restore() -
feat: use of {memoise} to cache call to
pak::pkg_system_requirements -
fix : dont depend anymore to {renv} use an internalised {renv} version (1.0.3)
-
fix : remove
renv:::lockfileand uselockfile_readinstead -
feat: Added
dock_from_renv(), to create a Dockerfile from a renv.lock file (@JosiahParry, @statnmap) -
feat: Added
parse_dockerfile(), to Create a Dockerfile object from a Dockerfile file (@JosiahParry) -
feat: Added
renv_versionparameter todock_from_renvto be able to fix the renv version to use duringrenv::restore()(@campbead)
-
fix: graceful failing in case no internet
-
fix: the dedicated
compact_sysreqsfunction allow to deal with 'complex' sysreqs, such as chromimum installation -
feat: add jammy ubuntu distro in available distro
- new version of
dock_from_desc()
- Corrected bug in
rthis()
- Added the
add_after()R6 method - Added
dock_from_desc(), to create a Dockerfile from a DESCRIPTION