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
6 RStudio Server on SPCS
Native R IDE in a custom container service
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/.
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
| 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:
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):
- snowflakeR: rstudio-spcs — kit, reticulate,
sfr_connect_spcs() - RSnowflake: spcs-custom-services — DBI auth, REST API limits
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
VOLUMESwith subpathsrstudio_workspaceandrstudio_r_libs
6.6.3 3. Build the image
Preferred — in-account (Image Builder):
Requires CLI ≥ 3.16 and enable_spcs_build_image = true in ~/.snowflake/config.toml.
Fallback — local Docker:
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.
6.6.5 5. Deploy the service
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
Each DROP SERVICE + CREATE SERVICE cycle assigns a new public hostname. Re-run SHOW ENDPOINTS after every redeploy.
- Browser → ingress URL → Snowflake SSO
- RStudio login: user
rstudio, password fromcreate_password_secret.sh - In R Console:
source("~/smoke_test.R") - 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:
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.