6  RStudio Server on SPCS

Native R IDE in a custom container service

Keywords

snowflake, R, RStudio, Posit, VS Code, workspace notebooks, snowflakeR, RSnowflake, mlops

6.1 Overview

RStudio Server on SPCS runs the open-source RStudio IDE as a long-running Snowpark Container Services (SPCS) service. You get a full native R session — Connections pane, debugger, Quarto, plots — inside the Snowflake security perimeter, with RSnowflake and snowflakeR baked into the image.

This chapter is the walkthrough. Deep reference material lives in package vignettes and the deploy kit under snowflakeR/inst/rstudio-spcs/.

Note

Prerequisites: SPCS compute pool, image repository, role with CREATE SERVICE, and (for in-account builds) Snowflake CLI ≥ 3.16 with Image Builder preview.

6.2 Learning objectives

  • Decide when RStudio-on-SPCS fits vs Workspace, Posit Native App, or Remote Dev
  • Provision stages, build an image, and deploy a service end-to-end
  • Connect with RSnowflake and snowflakeR in a native R session
  • Run smoke tests and recover the ingress URL after redeploy

6.3 When to choose this path

Choose RStudio on SPCS Choose another path
RStudio UX is required; you accept operating Docker + pool Notebook-first → Workspace
DIY image control (R version, packages, Conda) Managed IDE → Posit Workbench Native App (ch. 4)
No Posit Marketplace license yet VS Code / Cursor → Snowflake Remote Dev

Comparison matrix: Workspaces overview — related paths.


6.4 Architecture

flowchart TB
  user[R user browser]
  ingress[SPCS public ingress]
  svc[RStudio Server container]
  token["/snowflake/session/token"]
  host[SNOWFLAKE_HOST internal gateway]
  wh[Snowflake warehouse]

  user --> ingress --> svc
  svc --> token
  svc --> host
  svc --> wh

Component Role
RStudio Server Native R IDE on port 8787
RSnowflake dbConnect(Snowflake()) via SQL REST API + SPCS OAuth
snowflakeR ML APIs via reticulate → Snowpark Python
Miniconda snowflake_ml Shared Python env for reticulate (not Ubuntu system Python)
Stage volumes Persist workspace files and user R libraries

6.5 Deploy kit

The reference implementation ships with snowflakeR:

system.file("rstudio-spcs", package = "snowflakeR")

Public source: snowflakeR/inst/rstudio-spcs.

File Purpose
README.md Kit entry point
config.example.env Account, registry, pool, passwords
provision.sh Render + run SQL templates from config.env
create_password_secret.sh Snowflake secret → runtime PASSWORD (never in git)
provision.sql.template Stages + pool resume
provision_image_builder_eai.sql.template Egress for in-account image build
build_snowflake.sh / build_local.sh Image build paths
deploy_service.sh CREATE SERVICE
smoke_test.R / smoke_test.py Validation

Vignettes (detail):


6.6 End-to-end steps

6.6.1 1. Configure

cd inst/rstudio-spcs
cp config.example.env config.env
# Edit: SNOW_CONNECTION, account, registry URL, pool, roles (not the RStudio password)

All object names live in config.env — the same file used by build and deploy scripts.

6.6.2 2. Provision Snowflake objects

./provision.sh
./provision.sh --eai    # once, if using SPCS Image Builder (SNOW_EAI_ROLE, default ACCOUNTADMIN)

You need:

  • Image repository with OWNERSHIP for your deploy role
  • Compute pool (build + runtime can share a pool for pilots)
  • Stage VOLUMES with subpaths rstudio_workspace and rstudio_r_libs

6.6.3 3. Build the image

Preferred — in-account (Image Builder):

source config.env
./build_snowflake.sh

Requires CLI ≥ 3.16 and enable_spcs_build_image = true in ~/.snowflake/config.toml.

Fallback — local Docker:

source config.env
PUSH=1 ./build_local.sh    # always linux/amd64 for SPCS

The build context uploads pre-built snowflakeR/RSnowflake tarballs when possible — compiling from source inside the builder is slow. See R package tarball workflow.

6.6.4 4. Store the RStudio password (Snowflake secret)

Do not put the RStudio login password in config.env or the image. Create a Snowflake secret and reference it from the service spec — SPCS injects it as the container PASSWORD env var at runtime.

source config.env
RSTUDIO_PASSWORD='your-new-password' ./create_password_secret.sh

6.6.5 5. Deploy the service

source config.env
./deploy_service.sh

service-spec.template.yaml sets SNOWFLAKE_WAREHOUSE and other context env vars (required because RSnowflake cannot run USE WAREHOUSE on the SQL REST API). The RStudio password is not in the rendered spec — only the secret object name.

6.6.6 6. Open RStudio and smoke test

SHOW ENDPOINTS IN SERVICE MY_DB.MY_SCHEMA.RSTUDIO_SVC;
Ingress URL changes on redeploy

Each DROP SERVICE + CREATE SERVICE cycle assigns a new public hostname. Re-run SHOW ENDPOINTS after every redeploy.

  1. Browser → ingress URL → Snowflake SSO
  2. RStudio login: user rstudio, password from create_password_secret.sh
  3. In R Console: source("~/smoke_test.R")
  4. In Terminal: python3 ~/smoke_test.py

6.7 Using RSnowflake

library(DBI)
library(RSnowflake)

con <- dbConnect(Snowflake())
dbGetQuery(con, "SELECT CURRENT_USER(), CURRENT_WAREHOUSE()")

Warehouse, database, schema, and role come from service env vars set at deploy time. Full detail: vignette: spcs-custom-services.


6.8 Using snowflakeR

sfr_connect() auto-detects Workspace Notebooks only. In this custom SPCS service, use sfr_connect_spcs() from the kit:

source("~/spcs_helpers.R")
conn <- sfr_connect_spcs()

The image configures reticulate with Miniconda Python at /opt/conda/envs/snowflake_ml/bin/python. See the rstudio-spcs vignette for collect() vs to_pandas() and OpenSSL notes.


6.9 Operations

Topic Guidance
Image updates Rebuild, push, redeploy; suspend/resume pool to force fresh pull
Persistence Use stage volume mounts — not container ephemeral storage
EAI Required for image build egress (Docker Hub, CRAN/PPM, PyPI); not for routine Snowflake queries via internal gateway
Security Use ingress OAuth; set a strong PASSWORD; do not use DISABLE_AUTH
Cost Dedicated service + pool — size MIN_NODES / MAX_NODES for pilots

Stage file I/O: mount stages as volumes — RSnowflake does not support SQL GET/PUT. Same pattern as Parallel doSnowflake workers.