pracpac

Practical R Packaging with Docker

VP Nagraj

Charlottesville R Users (CRU) Meetup

2025-09-24

Outline

  • Why
    • Motivation
  • What
    • pracpac
  • How
    • The process
    • Next

Motivation


The pattern …


… build a Docker image to execute a pipeline as a container


  • R code (in most cases distributed as a package)
  • Domain-specific tools
  • Some kind of execution script(s)

Motivation

https://github.com/signaturescience/k2v

FROM alpine:3.15

ARG BCFTOOLS_VERSION="1.9"

ADD src /src

WORKDIR /src

RUN apk update && apk add --no-cache gcc g++ make libc-dev ncurses-dev zlib-dev xz-dev bzip2-dev R

RUN tar -xjf bcftools-${BCFTOOLS_VERSION}.tar.bz2 && \
    cd bcftools-${BCFTOOLS_VERSION} && \
    make -j4 && \
    make install && \
    cd /src && \
    rm -rf bcftools-${BCFTOOLS_VERSION} bcftools-${BCFTOOLS_VERSION}.tar.bz2

RUN tar -xjf htslib-${BCFTOOLS_VERSION}.tar.bz2 && \
    cd htslib-${BCFTOOLS_VERSION} && \
    make -j4 && \
    make install && \
    cd /src && \
    rm -rf htslib-${BCFTOOLS_VERSION} htslib-${BCFTOOLS_VERSION}.tar.bz2

ADD assets /assets
ADD testdata /testdata
ADD scripts /scripts

WORKDIR /data

ENTRYPOINT ["/scripts/k2v.sh"]

Motivation

## base image
FROM rocker/r-ver:latest

## install packages
RUN Rscript -e 'install.packages("dplyr")'

Motivation

## base image
FROM rocker/r-ver:latest

## copy the renv.lock (contains dplyr and dependencies)
COPY renv.lock /renv.lock

## install renv
RUN Rscript -e 'install.packages("renv")'

## restore packages from renv.lock
RUN Rscript -e 'renv::restore(lockfile="/renv.lock")'

Motivation

pracpac

pracpac

pracpac

  • use_docker()
    • create_docker_dir()
    • build_pkg()
    • renv_deps()
    • add_dockerfile()
    • add_assets()
  • build_image()

pracpac

pracpac

Advanced usage

  • Configure base image as needed
use_docker(..., base_image = "alpine:latest")
  • Customize CRAN repo used to install packages via renv
use_docker(..., repos = "https://packagemanager.rstudio.com/cran/__linux__/jammy/latest")
  • Use a different directory structure for Docker assets
use_docker(..., img_path = "../")

The process

https://github.com/signaturescience/pracpac/actions/

The process

The process

The process

Next

Limitations

  • Not intended to necessarily write a complete Dockerfile
  • Will not solve all Docker build issues
  • Does not template all system libraries that may be needed

Next

Use-cases to be documented in more detail

  • Shiny Server
  • RStudio Server
  • MLOps
  • {OTHERS?}

Next

https://github.com/signaturescience/pracpac/issues