Agent-almanac create-r-dockerfile
git clone https://github.com/pjt222/agent-almanac
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/wenyan/skills/create-r-dockerfile" ~/.claude/skills/pjt222-agent-almanac-create-r-dockerfile-ba53d8 && rm -rf "$T"
i18n/wenyan/skills/create-r-dockerfile/SKILL.mdCreate R Dockerfile
Build a Dockerfile for R projects using rocker base images with proper dependency management.
When to Use
- Containerizing an R application or analysis
- Creating reproducible R environments
- Deploying R-based services (Shiny, Plumber, MCP server)
- Setting up consistent development environments
Inputs
- Required: R project with dependencies (DESCRIPTION or renv.lock)
- Required: Purpose (development, production, or service)
- Optional: R version (default: latest stable)
- Optional: Additional system libraries needed
Procedure
Step 1: Choose Base Image
| Use Case | Base Image | Size |
|---|---|---|
| Minimal R runtime | | ~800MB |
| With tidyverse | | ~1.8GB |
| With RStudio Server | | ~1.9GB |
| Shiny server | | ~2GB |
Expected: A base image is selected that matches the project's requirements without unnecessary bloat.
On failure: If unsure which image to use, start with
rocker/r-ver (minimal) and add packages as needed. Check rocker-org for the full image catalog.
Step 2: Write Dockerfile
FROM rocker/r-ver:4.5.0 # Install system dependencies # Group by purpose for clarity RUN apt-get update && apt-get install -y \ # HTTP/SSL libcurl4-openssl-dev \ libssl-dev \ # XML processing libxml2-dev \ # Git integration libgit2-dev \ libssh2-1-dev \ # Graphics libfontconfig1-dev \ libharfbuzz-dev \ libfribidi-dev \ libfreetype6-dev \ libpng-dev \ libtiff5-dev \ libjpeg-dev \ # Utilities git \ curl \ && rm -rf /var/lib/apt/lists/* # Install R packages # Order: least-changing first for cache efficiency RUN R -e "install.packages(c( \ 'remotes', \ 'devtools', \ 'renv' \ ), repos='https://cloud.r-project.org/')" # Set working directory WORKDIR /workspace # Copy renv files first (cache layer) COPY renv.lock renv.lock COPY renv/activate.R renv/activate.R # Restore packages from lockfile RUN R -e "renv::restore()" # Copy project files COPY . . # Default command CMD ["R"]
Expected: Dockerfile builds successfully with
docker build -t myproject .
On failure: If the build fails during
apt-get install, check package names for the target distro (Debian). If renv::restore() fails, ensure renv.lock and renv/activate.R are copied before the restore step.
Step 3: Create .dockerignore
.git .Rproj.user .Rhistory .RData renv/library renv/cache renv/staging docs/ *.tar.gz
Expected:
.dockerignore excludes Git history, IDE files, local renv library, and build artifacts from the Docker context.
On failure: If the Docker build still copies unwanted files, verify
.dockerignore is in the same directory as the Dockerfile and uses correct glob patterns.
Step 4: Build and Test
docker build -t r-project:latest . docker run --rm -it r-project:latest R -e "sessionInfo()"
Expected: Container starts with correct R version and all packages available.
sessionInfo() output confirms the expected R version.
On failure: Check build logs for system dependency errors. Add missing
-dev packages to the apt-get install layer.
Step 5: Optimize for Production
For production deployments, use multi-stage builds:
# Build stage FROM rocker/r-ver:4.5.0 AS builder RUN apt-get update && apt-get install -y libcurl4-openssl-dev libssl-dev COPY renv.lock . RUN R -e "install.packages('renv'); renv::restore()" # Runtime stage FROM rocker/r-ver:4.5.0 COPY --from=builder /usr/local/lib/R/site-library /usr/local/lib/R/site-library COPY . /app WORKDIR /app CMD ["Rscript", "main.R"]
Expected: Multi-stage build produces a smaller final image. Runtime stage contains only compiled R packages, not build tools.
On failure: If packages fail to load in the runtime stage, ensure the library path in
COPY --from=builder matches where R installed packages. Check with R -e ".libPaths()" in both stages.
Validation
-
completes without errorsdocker build - Container starts and R session works
- All required packages are available
-
excludes unnecessary files.dockerignore - Image size is reasonable for the use case
- Rebuilds are fast when only code changes (layer caching works)
Common Pitfalls
- Missing system dependencies: R packages with compiled code need
libraries. Check error messages during-devinstall.packages() - Layer cache invalidation: Copying all files before installing packages invalidates cache on every code change. Copy lockfile first.
- Large images: Use
afterrm -rf /var/lib/apt/lists/*
. Consider multi-stage builds.apt-get install - Timezone issues: Add
or installENV TZ=UTC
for timezone-aware operationstzdata - Running as root: Add a non-root user for production:
RUN useradd -m appuser && USER appuser
Examples
# Development container with mounted source docker run --rm -it -v $(pwd):/workspace r-project:latest R # Plumber API service docker run -d -p 8000:8000 r-api:latest # Shiny app docker run -d -p 3838:3838 r-shiny:latest
Related Skills
- orchestrate multiple containerssetup-docker-compose
- special case for MCP R serverscontainerize-mcp-server
- advanced caching strategiesoptimize-docker-build-cache
- renv.lock feeds into Docker buildsmanage-renv-dependencies