2.2 Align local development and deployment environments
When developing and testing an app locally, it is important to ensure the environment is aligned with the target deployment environment. This might imply using e.g. multiple R and package versions for the local development of different applications, which clash with the typical setup (especially on Linux systems), where only one R version (the latest release) exists.
The idea is then to rely on the same version-stable rocker containers used for
the deployments, using a containerized versioned RStudio instance for the local
development. This is available through Rocker’s versioned
stack, so we could
use e.g. rocker/rstudio:3.6.1
.
Note that the same version-stable instance of RStudio can be used across all
different projects for which such version is relevant. For this reason, a
sensible choice is to rely on rocker/verse
, which adds tidyverse and
devtools to the stack, as well as properly setting up R Markdown system
dependencies TinyTeX and pandoc
, sparing the effort of the tedious extra
install. See the specific section below about ‘TinyTeX considerations’.
2.2.1 Running versioned RStudio instances
Assume we want to run a containerized versioned instance of RStudio for R 3.6.1, possibly alongside instances for other versions of R.
First of all, we need to get the image from docker-hub
We then want to have a running instance on localhost
(127.0.0.1
), with the
following setup:
- No authentication required (local setup).
- Enable root by setting the environment variable
ROOT
toTRUE
, so that e.g.sudo apt-get
can be used in RStudio. - Use a version-specific port, e.g.
3500
for R 3.5.0,3610
for R 3.6.1 and so on, so that we can uselocalhost
for concurrent R version instances. - The development code of all relevant projects should live outside the
container and be shared with it (and possibly many of them), e.g. under
~/RStudioProjects
on the host machine and/home/rstudio/RStudioProjects
in the container.- For this to work w/o permission
issues,
the container user (
rstudio
) must match the UID of the host user ($UID
).
- For this to work w/o permission
issues,
the container user (
- In order for the RStudio setting to persist if the container is recreated
(e.g. after pulling a new
rocker
image), we also use a shared volume (like~/.rstudio-docker/3.6.1
) for thehome/rstudio/.rstudio
directory, which is version-specific in case of multiple R versions - If we want to use Meld via the compareWith addins, we need to
- map the
DISPLAY
environment variable and volume/tmp/.X11-unix
- add
DISPLAY
toRenviron
- install Meld
- install
dbus-x11
- map the
- Use a version-specific name for the container running the RStudio instance,
e.g.
rstudio_3.6.1
.
R_VER=3.6.1
SHARED_DIR=RStudioProjects
docker run -d --restart=always \
-p 127.0.0.1:$(echo $R_VER | sed 's/[.]//g')0:8787 \
-e DISABLE_AUTH=true \
-e ROOT=TRUE \
-e USERID=$UID \
-v $HOME/$SHARED_DIR:/home/rstudio/$SHARED_DIR \
-v $HOME/.rstudio-docker/$R_VER:/home/rstudio/.rstudio \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
--name rstudio_$R_VER \
rocker/verse:$R_VER
# R and RStudio are not getting the DISPLAY environment variable
docker exec rstudio_$R_VER bash -c \
'echo "DISPLAY=${DISPLAY}" >> /usr/local/lib/R/etc/Renviron'
# Install Meld
docker exec rstudio_$R_VER bash -c \
'apt-get update && apt-get install -y --no-install-recommends meld dbus-x11'
The running RStudio can then be accessed by visiting http://localhost:3610/
.
You may find convenient to define a shell function as follows
run_rstudio_ver() {
local R_VER=${1:?"you must supply the R version as first argument"}
local SHARED_DIR=${2:?"you must supply the shared directory as second argument"}
local RVER_IMAGE=${3:-"verse"}
local BASE_IMAGE=rocker/$RVER_IMAGE:$R_VER
local PORT=$(echo $R_VER | sed 's/[.]//g')0
local CONTANER_NAME=rstudio_$R_VER
echo "Containerized version-stable RStudio for R "$R_VER\
"based on image "$BASE_IMAGE\
"with shared volume "$SHARED_DIR
docker pull $BASE_IMAGE &&
docker run -d --restart=always \
-p 127.0.0.1:$PORT:8787 \
-e DISABLE_AUTH=true \
-e ROOT=TRUE \
-e USERID=$UID \
-v $HOME/$SHARED_DIR:/home/rstudio/$SHARED_DIR \
-v $HOME/.rstudio-docker/$R_VER:/home/rstudio/.rstudio \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
--name $CONTANER_NAME \
$BASE_IMAGE &&
# R and RStudio are not getting the DISPLAY environment variable
docker exec $CONTANER_NAME bash -c \
'echo "DISPLAY=${DISPLAY}" >> /usr/local/lib/R/etc/Renviron' &&
# Install Meld
docker exec $CONTANER_NAME bash -c \
'apt-get update && apt-get install -y --no-install-recommends meld dbus-x11' &&
echo "RStudio running in container "$CONTANER_NAME" on port "$PORT &&
echo "visit http://localhost:"$PORT
}
which you can re-use as compact command for any R version as follows
Note that --restart=always
specifies that the container should stay up and restart
itself after stopping, e.g. upon machine reboot or docker upgrade, so that it is
always available. Still, you can explicitly stop the running container with
Alternatively, you can omit --restart=always
and explicitly start the
container whenever needed with
Note that start
/stop
operations do not affect the persistence of files
created outside the shared location, including global RStudio options such as
dark theme, diagnostic, etc. (set via Tools > Global Options…). On the other
hand, these files and settings do not (see above) persist removing the
container (docker rm
, see below) .
2.2.2 TinyTeX considerations
2.2.2.1 pdfcrop
Older rocker/verse
images might not include pdfcrop
, which is required for
the default and desirable cropping of PDF figures with R Markdown (see
rocker-org/rocker-versioned#146).
Make sure pdfcrop
is installed by running at R console
2.2.2.2 Align TinyTeX to current remote repo
NOTE - This should never be needed with recent rocker/verse
images, where
a version-stable Tex Live repository is used for the TinyTeX install (see
rocker-org/rocker-versioned#169).
If you are using LaTeX and start seeing errors like
Remote repository is newer than local (2018 < 2019)
it means that you have to re-install TinyTeX. This happens e.g. with
rocker/verse:3.6.1
, since it was build at the end of 2018 but the current
Tex Live repo is 2019. You can fix this via a user-specific re-installation of
TinyTeX for R. NOTE however that this will uninstall the system-level
TinyTeX pre-installed in rocker/verse
.
First, make sure /home/rstudio/bin
is part of the PATH
environment variable.
Check this by running
If you don’t see /home/rstudio/bin
, you can make sure it is part of the PATH
for R via
docker exec --user rstudio rstudio_3.6.1 sh -c 'echo "PATH=$HOME/bin:\${PATH}" >> $HOME/.Renviron'
# check again
docker exec --user rstudio rstudio_3.6.1 R --slave -e 'Sys.getenv("PATH")'
Then, from the running RStudio, run