This vignette provides a set of instructions for deploying maplandscape on Google Cloud Run. Google Cloud Run provides pay-per-use services for deploying containerised applications; this means you are only billed when the application is running.
Shiny apps can be deployed as containerised applications on Google Cloud Run with some configuration.
Clone the maplandscape GitHub repo:
git clone https://github.com/livelihoods-and-landscapes/maplandscape.git cd maplandscape/inst/docker
There is a sub-directory named
inst/docker. This contains a
Dockerfile that lists instructions that are used to build a docker image.
docker build -t maplandscape .
The image is based on the
rocker/shiny:latest image which includes Shiny Server to host the maplandscape Shiny application. Shiny Server serves apps out of the
srv/shiny-server/ directory; building the docker image will install all the R packages required to run maplandscape, install the maplandscape package from github, and copy an
app.R script into
srv/shiny-server/app which contains the commands to launch maplandscape.
shiny-customised.config file is used to set the
app_dir to the app directory where Shiny Server will launch and serve the app from.
While Google Cloud Run supports WebSockets, it is stateless, does not provide session affinity or sticky sessions, and it is possible that user requests could be routed different container instances of Shiny applications. Thus, user requests could be routed to a different container instance than the one which stores their session in memory. To sidestep this issue, when deploying a containerised Shiny app on Google Cloud Run the service can be configured to limit the number of container instances to one. This ensures that user’s requests are always routed to the same Shiny app instance. The trade-off with this approach is that the app won’t dynamically scale if it receives more traffic than one instance can handle. is possible to use higher CPU / RAM for a single container so it can better handle more traffic.
It is also necessary to disable some WebSocket protocols in Shiny Server that do not work with Google Cloud Run (see here for an example). The
shiny-customized.config file in the
docker directory of this package can be used to overwrite default shiny server configurations and disable WebSocket features not supported by Google Cloud Run. When building the docker image this file can be copied to
/etc/shiny-server/shiny-server.conf as specified in the
Setup a Google Cloud project and ensure billing is enabled.
Install the Google Cloud SDK and initialise it:
Enable Google Container Registry:
gcloud services enable containerregistry.googleapis.com
Configure docker to work with Google Cloud and allow the docker client to make authenticated requests to Google Container Registry.
google auth configure-docker
Rename the image tag with a reference to a Google Container Registry image:
docker tag <tag name> gcr.io/<gcs project id>/<image name>
Push image to Google Container Registry:
docker push gcr.io./<project-id>/<image-name>
Deploy the containerised Shiny app on Google Cloud Run using
gcloud command line tools:
gcloud run deploy <service name> --image gcr.io/<gcs project id>/<image name> --platform managed --port 3838 --memory 2Gi --allow-unauthenticated --cpu 1 --max-instances 1
--allow-unauthenticaed flag to make the app public and allow it to be launched by unauthenticated users.
--max-instances 1 flag to ensure only Google Cloud Run only launches one Shiny instance.
Shiny on Google Cloud Run - Scale-to-Zero R Web Apps: https://code.markedmondson.me/shiny-cloudrun/
Outstanding User Interfaces with Shiny - Chapters 5 and 11 provide an excellent overview of client-server concepts from a Shiny application perspective - https://unleash-shiny.rinterface.com/shiny-intro.html
Deploying containerised applications on Google Cloud Run - https://cloud.google.com/run/docs/deploying#command-line