Skip to content

Instantly share code, notes, and snippets.

@dbkegley
Last active September 15, 2023 17:58
Show Gist options
  • Save dbkegley/e40bb68a38b39b1eaec71edaecc47908 to your computer and use it in GitHub Desktop.
Save dbkegley/e40bb68a38b39b1eaec71edaecc47908 to your computer and use it in GitHub Desktop.
Posit: Using Workbench images with Connect

Sharing custom Posit Workbench images with Posit Connect

Posit Workbench image base: ghcr.io/rstudio/r-session-complete-preview:jammy-daily

Build the custom project image:

docker build . -t ghcr.io/dbkegley/posit/image-classifier:jammy
docker push ghcr.io/dbkegley/posit/image-classifier:jammy

Add the image to Posit Connect:

curl -XPOST -H "Authorization: key ${CONNECT_API_KEY}" ${CONNECT_SERVER}/__api__/v1/environments \
--data '{
  "title": "Custom image classifier",
  "description": "My custom image classifier environment",
  "cluster_name": "Kubernetes",
  "name": "ghcr.io/dbkegley/posit/image-classifier:jammy",
  "matching": "exact",
  "r": {
    "installations": [
      {
        "version": "4.2.3",
        "path": "/opt/R/4.2.3/bin/R"
      }
    ]
  },
  "python": {
    "installations": [
      {
        "version": "3.9.14",
        "path": "/opt/python/3.9.14/bin/python"
      }
    ]
  }
}'

On Posit Workbench, clone the project:

git clone https://github.com/sol-eng/python-examples
cd python-examples
git checkout 4e4be3f59f0fbcf3ccecc724a00b0da7a4ad6f07
git checkout -b image-classifier

Run the App on Posit Workbench and deploy the App to Posit Connect:

Note: The following deployment steps use rsconnect::deployApp to deploy the application to Posit Connect because push-button deployments do not support the image or envManagement arguments.

setwd("~/python-examples/reticulated-image-classifier")

# Run the app on Posit Workbench
shiny::runApp()

# Deploy the Application and tell Posit Connect to use the custom image
# when executing content. `envManagement=FALSE` tells Posit Connect not to
# install any additional R or Python packages during the deployment.
rsconnect::deployApp(image = 'ghcr.io/dbkegley/posit/image-classifier:jammy', envManagement = FALSE)
FROM ghcr.io/rstudio/r-session-complete-preview:jammy-daily
ARG R_VERSION="4.2.3"
ARG PYTHON_VERSION="3.9.17"
ARG CRAN_MIRROR="https://p3m.dev/cran/__linux__/jammy/latest"
ARG PYPI_MIRROR="https://p3m.dev/pypi/latest/simple"
ARG GIT_SHA="bb9d3ee5700dd8d65044c96a57f565d13e4b881f"
# Install the Python packages
# These commands install the python packages defined in the project's requirements.txt
# which pins the package versions and provides an immutable set of Python dependencies.
RUN pip install --upgrade pip && \
curl -sSfL https://raw.githubusercontent.com/sol-eng/python-examples/${GIT_SHA}/reticulated-image-classifier/requirements.txt \
-o /tmp/requirements.txt && \
pip install --default-timeout=1000 --index-url=${PYPI_MIRROR} -r /tmp/requirements.txt && \
rm /tmp/requirements.txt
# Install the R packages
# These commands install the R packages defined in the project's renv.lock file
# which pins the package versions and provides an immutable set of R dependencies.
# They also configure the global Renviron.site so that the RENV_PATHS_CACHE is used
# to to download/cache packages in a shared location during `renv::restore()`.
# RETICULATE_PYTHON is also set in the Renviron.site so that reticulate will load the
# global python installation instead of attempting to load libraries from a virtual environment.
RUN printf "RETICULATE_PYTHON=/opt/python/${PYTHON_VERSION}/bin/python\n" > /opt/R/${R_VERSION}/lib/R/etc/Renviron.site && \
printf "RENV_PATHS_CACHE=/usr/share/renv/cache\n" >> /opt/R/${R_VERSION}/lib/R/etc/Renviron.site && \
chmod 644 /opt/R/${R_VERSION}/lib/R/etc/Renviron.site && \
R -e $"install.packages(c('renv', 'rsconnect'), repos = c(CRAN = '${CRAN_MIRROR}'))" && \
curl -sSfL https://raw.githubusercontent.com/sol-eng/python-examples/${GIT_SHA}/reticulated-image-classifier/renv.lock \
-o /tmp/renv.lock && \
R -e $"renv::restore(lockfile = '/tmp/renv.lock', repos = c(CRAN = '${CRAN_MIRROR}'))" && \
rm /tmp/renv.lock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment