Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added registry/joergklein/.images/avatar.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions registry/joergklein/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
display_name: "Jörg Klein"
bio: "Data Scientists"
github: "joergklein"
avatar: "./.images/avatar.jpg"
status: "community"
---

# Jörg Klein

Data Scientists
98 changes: 98 additions & 0 deletions registry/joergklein/templates/docker-rstudio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
display_name: Docker RStudio
description: Provision Docker containers with RStudio, code-server, and RMarkdown
icon: ../../../../.icons/rstudio.svg
verified: true
tags: [docker, rstudio, r, rmarkdown, code-server]
---

# R Development on Docker Containers

Provision Docker containers pre-configured for R development as [Coder workspaces](https://coder.com/docs/workspaces) with this template.

Each workspace comes with:

- **RStudio Server** — full-featured R IDE in the browser.
- **code-server** — VS Code in the browser for general editing.
- **RMarkdown** — author reproducible documents, reports, and presentations.

The workspace is based on the [rocker/rstudio](https://rocker-project.org/) image, which ships R and RStudio Server pre-installed.

## Prerequisites

### Infrastructure

#### Running Coder inside Docker

If you installed Coder as a container within Docker, you will have to do the following things:

- Make the Docker socket available to the container
- **(recommended) Mount `/var/run/docker.sock` via `--mount`/`volume`**
- _(advanced) Restrict the Docker socket via https://github.com/Tecnativa/docker-socket-proxy_
- Set `--group-add`/`group_add` to the GID of the Docker group on the **host** machine
- You can get the GID by running `getent group docker` on the **host** machine

#### Running Coder outside of Docker

If you installed Coder as a system package, the VM you run Coder on must have a running Docker socket and the `coder` user must be added to the Docker group:

```sh
# Add coder user to Docker group
sudo adduser coder docker

# Restart Coder server
sudo systemctl restart coder

# Test Docker
sudo -u coder docker ps
```

## Architecture

This template provisions the following resources:

- Docker image (built from `build/Dockerfile`, extending `rocker/rstudio` with system dependencies)
- Docker container (ephemeral — destroyed on workspace stop)
- Docker volume (persistent on `/home/rstudio`)

When the workspace restarts, tools and files outside `/home/rstudio` are not persisted. The R library path defaults to a subdirectory of the home folder, so installed packages (including RMarkdown) survive restarts.

> [!NOTE]
> This template is designed to be a starting point! Edit the Terraform to extend it for your use case.

## Customization

### Changing the R version

Set the `rstudio_version` variable to any valid [rocker/rstudio tag](https://hub.docker.com/r/rocker/rstudio/tags) (for example `4.4.2`, `4.3`, or `latest`).

### Installing additional R packages

R packages are pre-installed via the `build/Dockerfile` so they are available immediately when the workspace starts. To add more packages, add `install.packages()` calls to the Dockerfile:

```dockerfile
RUN R -e "install.packages(c('tidyverse', 'shiny'))"
```

The image is pre-configured to use [Posit Package Manager](https://packagemanager.posit.co/) which provides pre-compiled binary packages for fast installation. Packages installed at build time avoid long startup delays from compiling from source on every workspace start.

### Adding system dependencies

The `build/Dockerfile` extends the `rocker/rstudio` base image with system packages required by modules (e.g. `curl` for code-server, `cmake` for R package compilation). If you add modules that need additional system-level tools, add them to the `Dockerfile`:

```dockerfile
RUN apt-get update \
&& apt-get install -y \
curl \
cmake \
your-package-here \
&& rm -rf /var/lib/apt/lists/*
```

### Adding LaTeX for PDF rendering

RMarkdown can render PDF output when LaTeX is available. Add the following to the startup script to install TinyTeX:

```sh
R --quiet -e "if (!require('tinytex', quietly = TRUE)) { install.packages('tinytex', repos = 'https://cloud.r-project.org'); tinytex::install_tinytex() }"
```
46 changes: 46 additions & 0 deletions registry/joergklein/templates/docker-rstudio/build/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# syntax=docker/dockerfile:1

ARG RSTUDIO_VERSION=latest
FROM rocker/rstudio:${RSTUDIO_VERSION}

USER root

RUN apt-get update && apt-get install -y \
curl \
git \
sudo \
procps \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /tmp

# TeX Live Installer
RUN wget https://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz \
&& tar -xzf install-tl-unx.tar.gz \
&& cd install-tl-* \
&& echo "selected_scheme scheme-medium" > profile.txt \
&& ./install-tl -profile profile.txt \
&& cd / \
&& rm -rf /tmp/install-tl-* /tmp/install-tl-unx.tar.gz

# Set PATH
ENV PATH="/usr/local/texlive/2026/bin/x86_64-linux:${PATH}"

# Optional: LuaLaTeX-Pakete
RUN tlmgr install unicode-math luacode

# R Pakete
RUN R -e "install.packages(c('rmarkdown'), repos='https://cloud.r-project.org')"

# RStudio Konfiguration (kein Login nötig)
RUN echo "auth-minimum-user-id=0" >> /etc/rstudio/rserver.conf

# Environment
ENV HOME=/home/rstudio \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8

RUN chown -R rstudio:rstudio /home/rstudio

USER rstudio
WORKDIR /home/rstudio
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 138 additions & 0 deletions registry/joergklein/templates/docker-rstudio/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
}
docker = {
source = "kreuzwerker/docker"
}
}
}

# -------------------------
# PROVIDER
# -------------------------

provider "docker" {}

# -------------------------
# DATA
# -------------------------

data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
data "coder_provisioner" "me" {}

locals {
username = data.coder_workspace_owner.me.name
}

# -------------------------
# IMAGE
# -------------------------

resource "docker_image" "workspace" {
name = "coder-rstudio-${data.coder_workspace.me.id}"

build {
context = "./build"
}
}

# -------------------------
# VOLUME
# -------------------------

resource "docker_volume" "home" {
name = "coder-${data.coder_workspace.me.id}-home"

lifecycle {
ignore_changes = all
}
}

# -------------------------
# CODER AGENT
# -------------------------

resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch
os = "linux"

env = {
HOME = "/home/rstudio"
}
}

# -------------------------
# CONTAINER
# -------------------------

resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count

image = docker_image.workspace.image_id

name = "coder-${local.username}-${data.coder_workspace.me.name}"

command = [
"bash",
"-lc",
<<-EOT
set -e

echo "[startup] starting coder agent"
coder agent &

echo "[startup] starting RStudio"
rserver --auth-none=1 \
--www-port=8787 \
--www-address=0.0.0.0 &

wait -n
EOT
]

env = [
"CODER_AGENT_TOKEN=${coder_agent.main.token}"
]

volumes {
container_path = "/home/rstudio"
volume_name = docker_volume.home.name
}
}

# -------------------------
# RSTUDIO APP
# -------------------------

resource "coder_app" "rstudio" {
agent_id = coder_agent.main.id
slug = "rstudio"
display_name = "RStudio"

url = "http://localhost:8787"

subdomain = true
share = "owner"

healthcheck {
url = "http://localhost:8787"
interval = 5
threshold = 30
}
}

# -------------------------
# CODE-SERVER (MODUL)
# -------------------------

module "code-server" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/code-server/coder"
version = "~> 1.0"

agent_id = coder_agent.main.id
folder = "/home/rstudio"
}
Loading