R con Apptainer
R es uno de los entornos más utilizados para análisis estadístico, filogenética, transcriptómica, visualización de datos y bioinformática. En BEAGLE, R debe utilizarse dentro de contenedores con Apptainer, de la misma forma que cualquier otro software especializado.
La ventaja de usar R dentro de un contenedor es que podemos mantener una versión definida de:
- R
- paquetes de R
- bibliotecas del sistema
- compiladores
- dependencias externas
sin modificar el sistema operativo del clúster.
En esta sección se muestran distintas estrategias para trabajar con R y mantener actualizado un contenedor.
Imagen base de R
Podemos partir de una imagen existente de R y convertirla a formato .sif.
Por ejemplo:
apptainer pull docker://r-base:4.6.1Esto generará una imagen similar a:
r-base_4.6.1.sif
Podemos comprobar la versión de R:
apptainer exec r-base_4.6.1.sif R --versionTambién podemos revisar qué distribución Linux utiliza la imagen:
apptainer exec r-base_4.6.1.sif cat /etc/os-releasePor ejemplo, una imagen puede mostrar:
PRETTY_NAME="Debian GNU/Linux forky/sid"
NAME="Debian GNU/Linux"
VERSION_CODENAME=forky
ID=debian
Esto es importante porque las dependencias del sistema deben instalarse utilizando el gestor de paquetes correspondiente.
En Debian y Ubuntu se utiliza:
aptEjecutar R dentro del contenedor
Para abrir una sesión interactiva:
apptainer shell r-base_4.6.1.sifDentro del contenedor:
RTambién podemos ejecutar directamente un script:
apptainer exec r-base_4.6.1.sif Rscript analisis.RO ejecutar una instrucción sencilla:
apptainer exec r-base_4.6.1.sif \
Rscript -e 'sessionInfo()'¿Dónde instalar los paquetes de R?
Una imagen .sif está diseñada para ser inmutable.
Esto significa que normalmente no podemos hacer:
install.packages("ape")y esperar que el paquete quede guardado permanentemente dentro del .sif.
Existen varias estrategias para mantener paquetes adicionales:
- montar una biblioteca externa con
--bind - utilizar un overlay persistente
- convertir temporalmente el
.sifa un sandbox - reconstruir el
.sifdespués de instalar nuevos paquetes
Cada estrategia tiene ventajas diferentes.
Opción 1: biblioteca de R externa con --bind
Una estrategia sencilla consiste en guardar los paquetes de R fuera del contenedor.
Primero creamos una carpeta:
mkdir -p ~/R/libraryDespués la montamos dentro del contenedor:
apptainer exec \
--bind ~/R/library:/R-library \
r-base_4.6.1.sif \
Rscript -e '
.libPaths(c("/R-library", .libPaths()))
install.packages(
"ape",
repos="https://cloud.r-project.org"
)
'El paquete queda almacenado físicamente en:
~/R/library
y no dentro del .sif.
Para usarlo posteriormente:
apptainer exec \
--bind ~/R/library:/R-library \
r-base_4.6.1.sif \
Rscript -e '
.libPaths(c("/R-library", .libPaths()))
library(ape)
packageVersion("ape")
'Ventajas
- no es necesario reconstruir la imagen
- los paquetes se pueden actualizar rápidamente
- cada proyecto puede tener su propia biblioteca
- funciona bien para paquetes que solo dependen de R
Limitación
Algunos paquetes necesitan bibliotecas adicionales del sistema Linux.
Por ejemplo:
libcurl
libxml2
OpenSSL
fontconfig
freetype
harfbuzz
Estas dependencias no se pueden instalar simplemente dentro de una carpeta de paquetes de R.
En esos casos es necesario modificar la imagen base.
Opción 2: overlay persistente
Un overlay es una capa escribible que se coloca encima de una imagen .sif.
Podemos pensar en:
r-base_4.6.1.sif
+
R-overlay.img
=
contenedor modificable
La imagen original permanece sin cambios y todas las modificaciones se almacenan en el overlay.
Crear un overlay
Por ejemplo, para crear un overlay de 10 GB:
apptainer overlay create \
--size 10240 \
R-overlay.imgDespués podemos entrar al contenedor usando el overlay:
apptainer shell \
--fakeroot \
--overlay R-overlay.img \
r-base_4.6.1.sifDentro del contenedor podemos instalar paquetes:
install.packages(
"ape",
repos="https://cloud.r-project.org"
)Al salir:
exitlos cambios permanecen dentro de:
R-overlay.img
Para volver a utilizar el mismo entorno:
apptainer exec \
--overlay R-overlay.img \
r-base_4.6.1.sif \
Rscript analisis.RVentajas
- no se modifica el
.sif - los cambios son persistentes
- permite probar paquetes antes de reconstruir una imagen
- útil durante desarrollo
Limitaciones
El entorno queda dividido en dos archivos:
r-base_4.6.1.sif
R-overlay.img
Por lo tanto, si queremos mover el entorno a otro servidor debemos copiar ambos archivos.
Opción 3: usar un sandbox
Un sandbox convierte el contenedor en una carpeta editable.
Partimos de:
r-base_4.6.1.sif
y creamos:
apptainer build \
--fakeroot \
--sandbox \
r-base_4.6.1_sandbox \
r-base_4.6.1.sifAhora podemos entrar con:
apptainer shell \
--fakeroot \
--writable \
--pwd / \
r-base_4.6.1_sandboxDentro podemos instalar paquetes del sistema:
apt update
apt install -y libxml2-devy también paquetes de R:
Rinstall.packages(
"xml2",
repos="https://cloud.r-project.org"
)Cuando terminemos:
exitpodemos reconstruir una nueva imagen:
apptainer build \
--fakeroot \
r-base_4.6.1.sif \
r-base_4.6.1_sandboxEl resultado vuelve a ser un único archivo:
r-base_4.6.1.sif
Paquetes de R y dependencias del sistema
No todos los paquetes de R están formados únicamente por código R.
Muchos paquetes contienen código:
- C
- C++
- Fortran
o necesitan bibliotecas externas proporcionadas por Linux.
Por ejemplo, al instalar:
install.packages("tidyverse")R también instala numerosas dependencias:
curl
openssl
xml2
systemfonts
textshaping
ragg
readr
readxl
rvest
ggplot2
dplyr
tidyr
...
Algunas de ellas necesitan bibliotecas del sistema operativo.
Ejemplo: tidyverse
Una instalación de tidyverse puede fallar aunque R funcione correctamente.
Por ejemplo:
ERROR: configuration failed for package 'curl'
ERROR: configuration failed for package 'xml2'
ERROR: configuration failed for package 'openssl'
Esto normalmente indica que faltan bibliotecas de desarrollo del sistema.
En Debian pueden instalarse dependencias como:
apt install -y \
libcurl4-openssl-dev \
libuv1-dev \
libxml2-dev \
libssl-dev \
libfontconfig1-dev \
libfreetype-dev \
libharfbuzz-dev \
libfribidi-dev \
libpng-dev \
libtiff-dev \
libjpeg-devDespués podemos volver a instalar:
install.packages(
"tidyverse",
repos="https://cloud.r-project.org"
)¿Por qué ocurre esto?
R descarga paquetes desde CRAN, pero algunas extensiones deben compilarse contra bibliotecas del sistema.
Por ejemplo:
| Paquete de R | Dependencia del sistema |
|---|---|
curl |
libcurl4-openssl-dev |
xml2 |
libxml2-dev |
openssl |
libssl-dev |
systemfonts |
libfontconfig1-dev, libfreetype-dev |
textshaping |
libharfbuzz-dev, libfribidi-dev |
ragg |
bibliotecas gráficas como PNG, TIFF y JPEG |
Por esta razón, para mantener una imagen de R completa es útil poder instalar tanto paquetes de R como bibliotecas del sistema.
Estrategia recomendada para mantener una imagen de R
Para pruebas rápidas puede utilizarse:
bind
o:
overlay
pero cuando queremos mantener una imagen R que pueda distribuirse y utilizarse directamente en BEAGLE, es más conveniente generar nuevamente el .sif.
El flujo recomendado es:
r-base_4.6.1.sif
|
v
sandbox temporal
|
+--> apt install ...
|
+--> install.packages(...)
|
v
nuevo r-base_4.6.1.sif
Esto puede automatizarse con el script:
update_r_sif.sh
Script update_r_sif.sh
El script permite actualizar una imagen existente utilizando fakeroot.
Puede instalar:
- paquetes del sistema Debian con
--apt - paquetes CRAN con
--r - paquetes Bioconductor con
--bioc
y después reconstruye automáticamente el .sif.
Mostrar ayuda
./update_r_sif.sh --helpLa sintaxis general es:
./update_r_sif.sh \
-i IMAGEN.sif \
[opciones]Las opciones principales son:
-i, --image FILE
Imagen SIF que se desea actualizar.
--apt PKG...
Instala paquetes del sistema Debian.
--r PKG...
Instala paquetes CRAN.
--bioc PKG...
Instala paquetes Bioconductor.
-h, --help
Muestra la ayuda.
Instalar un paquete sencillo de R
Por ejemplo:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--r apeEl script:
- convierte temporalmente el
.sifa sandbox - instala
ape - comprueba que el paquete quedó instalado
- construye un nuevo
.sif - conserva la imagen anterior como respaldo
- deja la nueva imagen con el mismo nombre
Por ejemplo:
r-base_4.6.1_20260922_101500.sif
r-base_4.6.1.sif
La imagen:
r-base_4.6.1.sif
siempre corresponde a la versión más reciente.
Volver a actualizar la misma imagen
Después podemos utilizar nuevamente exactamente el mismo archivo.
Por ejemplo:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--r ape phytoolsPosteriormente:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--bioc DESeq2Cada actualización parte del .sif más reciente.
El proceso puede verse como:
R base
|
+-- tidyverse
|
+-- ape
|
+-- phytools
|
+-- DESeq2
|
v
r-base_4.6.1.sif
Ejemplo: instalar tidyverse
tidyverse es un buen ejemplo porque necesita tanto paquetes de R como bibliotecas adicionales del sistema Linux.
No basta necesariamente con ejecutar:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--r tidyverseSi faltan dependencias del sistema, la instalación puede detenerse.
Por esta razón podemos instalar las dependencias Debian y tidyverse en una sola actualización:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--apt \
libcurl4-openssl-dev \
libuv1-dev \
libxml2-dev \
libssl-dev \
libfontconfig1-dev \
libfreetype-dev \
libharfbuzz-dev \
libfribidi-dev \
libpng-dev \
libtiff-dev \
libjpeg-dev \
--r tidyverseEl script primero instala las bibliotecas del sistema:
Debian / apt
y posteriormente ejecuta:
install.packages("tidyverse")Finalmente reconstruye:
r-base_4.6.1.sif
Ejemplo: instalar terra
terra es un paquete de R utilizado para trabajar con datos espaciales y ráster. A diferencia de paquetes formados únicamente por código R, terra depende de varias bibliotecas geoespaciales instaladas en el sistema Linux.
Si intentamos instalar directamente:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--r terrala instalación puede fallar si la imagen no contiene las bibliotecas necesarias.
Entre las dependencias del sistema más importantes se encuentran:
GDAL
GEOS
PROJ
SQLite
En una imagen basada en Debian, estas dependencias pueden instalarse con:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--apt \
libgdal-dev \
libgeos-dev \
libproj-dev \
libsqlite3-dev \
--r terraEl script primero instala las bibliotecas del sistema mediante:
apt
y posteriormente ejecuta:
install.packages("terra")Durante la instalación, terra detecta las bibliotecas geoespaciales disponibles dentro del contenedor y compila el paquete contra ellas.
Finalmente, el script reconstruye la imagen:
r-base_4.6.1.sif
que ahora contiene tanto las dependencias del sistema como el paquete terra.
Podemos comprobar la instalación con:
apptainer exec \
r-base_4.6.1.sif \
Rscript -e '
library(terra)
packageVersion("terra")
'También podemos revisar qué versiones de las bibliotecas geoespaciales fueron detectadas:
apptainer exec \
r-base_4.6.1.sif \
Rscript -e '
library(terra)
terra::gdal()
terra::projInfo()
'Este ejemplo muestra por qué algunos paquetes de R no pueden instalarse únicamente con install.packages(): parte de sus dependencias pertenece al sistema operativo y debe estar disponible dentro de la imagen Apptainer antes de compilar el paquete.
Instalar varios paquetes de R
Podemos instalar varios paquetes en la misma actualización:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--r \
ape \
phytools \
geiger \
tidyverseInstalar paquetes Bioconductor
El script también puede utilizar BiocManager.
Por ejemplo:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--bioc \
DESeq2 \
edgeR \
BiostringsTambién podemos combinar CRAN y Bioconductor:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--r \
tidyverse \
ggplot2 \
--bioc \
DESeq2 \
BiostringsInstalar solamente dependencias del sistema
También podemos actualizar únicamente el sistema base del contenedor:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--apt \
libxml2-dev \
libssl-dev \
libcurl4-openssl-devDespués podemos volver a utilizar la imagen actualizada para instalar paquetes de R:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--r xml2 curl opensslSin embargo, cuando conocemos todas las dependencias, es más eficiente instalarlas en una sola ejecución:
./update_r_sif.sh \
-i r-base_4.6.1.sif \
--apt \
libxml2-dev \
libssl-dev \
libcurl4-openssl-dev \
--r \
xml2 \
curl \
opensslAsí el .sif solamente necesita reconstruirse una vez.
fakeroot
El script utiliza:
--fakeroot
en lugar de sudo.
Esto permite realizar operaciones que normalmente requieren privilegios de administrador dentro del contenedor, sin ser root real en el sistema anfitrión.
Podemos comprobar que fakeroot funciona:
apptainer exec \
--fakeroot \
r-base_4.6.1.sif \
idEl resultado debería mostrar algo similar a:
uid=0(root) gid=0(root)
Esto no significa que tengamos acceso root al servidor.
Los privilegios existen únicamente dentro del espacio de usuario utilizado por Apptainer.
Verificar paquetes instalados
Podemos comprobar que un paquete existe:
apptainer exec \
r-base_4.6.1.sif \
Rscript -e '
library(tidyverse)
packageVersion("tidyverse")
'También podemos listar todos los paquetes instalados:
apptainer exec \
r-base_4.6.1.sif \
Rscript -e '
x <- installed.packages()[, c("Package", "Version")]
print(x, row.names=FALSE)
'Recomendación práctica
Para trabajar con R pueden utilizarse distintas estrategias:
| Estrategia | Uso recomendado |
|---|---|
Biblioteca externa con --bind |
paquetes de R por proyecto |
| Overlay | pruebas y desarrollo |
| Sandbox manual | modificar y depurar una imagen |
update_r_sif.sh |
mantener una imagen R reutilizable |
Para una imagen destinada a utilizarse repetidamente en BEAGLE, la opción recomendada es:
update_r_sif.sh
porque permite mantener en un único .sif:
Debian
|
+-- R
|
+-- bibliotecas del sistema
|
+-- paquetes CRAN
|
+-- paquetes Bioconductor
|
v
r-base_4.6.1.sif
De esta forma podemos actualizar progresivamente el entorno sin modificar el sistema operativo de BEAGLE y conservar una imagen portable y reproducible.