RInno: How to install local shiny apps

[This article was first published on FI Labs - R Feed, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

The name, RInno (“R Inno”), is a combination of R and Inno Setup, an installer for Windows programs (sorry Mac and Linux users). If the name brings to mind a specific species of odd-toed ungulate, just remember, White and Black Rhinoceros are actually both gray, and although RInno resembles “rhino,” it actually rhymes with minnow. Ce n’est pas un rhinocéros (This is not a Rhino); it’s our newest R package.

Getting Started

install.packages("RInno")
require(RInno)
RInno::install_inno()

We put a simple example Shiny app in the package:

example_app(app_dir = "app") 

A minimal installation can be created using the package defaults with two lines of code:

create_app(app_name = "myapp", app_dir = "app")
compile_iss()

Now, there should be a new directory, app/RInno_installer, in your working directory. Double-click the .exe to see how that example app can be installed on your computer.

Background

RStudio publishes great articles about deploying shiny apps on their website; the local deployment article is one of my favorites. You can find instructions about how to use many different cloud and on premise servers to deploy your app, but clients/organizations often request that it be an on-premise app without installing any new hosting software (RStudio Connect/Shiny Server). They also want apps to be available to non-technical staff who may or may not have R installed. Each manual, r-specific step is a barrier to entry. RInno can meet these requirements because it:

  • Provides a clean user experience similar to installing any other program
  • Requires no R programming skills nor a previous installation of R to install your app, many users don’t even know R is being used
  • Does not share data/code with a third party or require server software
  • Can be extended to support continuous installation from GitHub and/or BitBucket
  • Can be easily uninstalled using the Windows Control Panel
  • Is low maintenance for R developers because most steps are fully automated
  • Logs start up errors so that you can follow up with specific user’s needs

We work with a lot of sensitive data, and deploying our shiny apps would require vetting third party hosts/software. However, the unknown benefit of building and deploying a shiny app usually cannot compete with the known pains of an organization’s security review process.

Because R often gets approved before Shiny Server, RInno allows us to install shiny apps on users’ desktops in the interim. After organizations start using those locally installed shiny apps, it is our hope that they will build demand for hosted solutions and help push Shiny Server up the priority list.

If you are familiar with Dr. Lee Pang’s DesktopDeployR project, he built a very nice JScript procedure to manage app start up sequences. RInno installs and controls a modified version of that procedure using Inno Setup. This is useful because it removes a lot of manual work for you, the developer, and it allows business users to install Shiny apps themselves. If you change your mind using DesktopDeployR, you and your users need to know exactly how to implement those changes. However, using RInno, you just specify arguments once in create_app, and they will flow through the framework without requiring in-depth editing and/or knowledge. And most importantly, your users just need to double-click their app’s icon to get updates via GitHub/BitBucket. RInno produces a higher quality, more reliable result with an agile design, but Dr. Pang’s DesktopDeployR project was a necessary prerequisite.

Even as demand builds among Data Scientists and Analysts, many companies are very cautious about placing open source software on their servers. Especially, whimsically named software that invokes a response like this:

scared-baby

shiny-object-syndrome

If you have ever asked IT to install Shiny Server, they may have been affected by an unfortunate psychological phenomenon called an anchoring bias. That is where RInno fits in. It avoids the shiny bias and replaces it with a Rhino image.

Basic Features

By default, RInno does not include an installation of R, so if some of your users do not have R installed, or they are using different versions of R, you should change the default for include_R:

create_app(app_name = "myapp", app_dir = "path/to/myapp", include_R = TRUE)

But keep in mind, this feature drastically increases the size of your installer, so only change include_R = TRUE if you really need it. We’ve added a short snippet of Pascal code to the installer to check each user’s registry during installation. If they have R installed, the installer will not re-install it. However, if another version is present, it will give them the version included in your installer. You can control which version of R is included and checked for by changing the R_version argument:

create_app(
	app_name  = "myapp", 
	app_dir   = "path/to/myapp", 
	include_R = TRUE, 
	R_version = 3.2.9)

We’ve debated making this process less strict and just looking for any version of R on the user’s computer. However, a strict strategy was easier to develop, and we think it is good to know exactly which version of R your app is running on, which would not be known using a more flexible strategy (i.e. the registry check finds a version of R, so don’t install the version included with the app). This might be a feature people would like to control, so we are actively looking at ways to implement strict and flexible installations. For now, RInno is strict about the version of R included with your installer.

Managing Dependencies

In order to manage dependencies found in CRAN-like repositories, provide them as a character vector to the pkgs argument, or if you have any GitHub dependencies, add them to the remotes argument:

create_app(
	app_name = "myapp", 
	app_dir  = "path/to/myapp"
	pkgs     = c("shiny", "dplyr", "plotly", "ggplot2", "xkcd"),
	remotes  = c("talgalili/installr", "daattali/shinyjs"))

These are added to utils/config.cfg and used by RInno to build a local library for your app on each user’s computer. Dependencies will only be installed the first time users open the app. So keep in mind, major package updates will not be triggered unless users re-install your app. This design choice prevents existing installations from breaking post-install, but there is still some risk that a major update happens pre-install.

Advanced Features

For complex installations, RInno provides support for many of Inno Setup’s features. We’ll highlight many of the most commonly used features here, but you should check out create_app’s support functions for more.

?setup
?icons

Company Info

If you provide a publisher and/or pub_url, your RInno installer will display that information on the “Support” dialog of the Add/Remove Programs Control Panel applet. Many standard programs provide this information, so it gives your shiny app a more official feel.

create_app(
	app_name  = "myapp",
	app_dir   = "path/to/myapp",
	publisher = "FI Consulting, Inc.",
	pub_url   = "www.ficonsulting.com")

Additionally, you can provide two other types of URLs that will also be displayed in Add/Remove Programs, upd_url and sup_url.

Password Protection

There are restrictions on exporting technology encrypted above 64-bit levels, so we could not include this feature automatically. However, you can add it by visiting the Inno Setup downloads page, downloading the ISCrypt.dll, and placing it in your Inno Setup directory.

Afterwards, if inst_pw is supplied then the contents of the RInno installer will be encrypted using a 160-bit key derived from the password string. This ensures that if unauthorized personnel try to gain access to the contents of your installer, it will take them a while to get in.

create_app(
	app_name = "myapp",
	app_dir  = "path/to/myapp",
	inst_pw  = "0r4nGE5")

Licensing

You can provide a .txt or .rtf file name with your license agreement to the license_file argument of create_app. The agreement will be displayed before the Select Destination Page of the installer and request that each user accept your terms before proceeding.

create_app(
	app_name     = "myapp",
	app_dir      = "path/to/myapp",
	license_file = "LICENSE")

Default Directory

default_dir is where the installed shiny app will be saved on your users’ computers. You should not hard code this value for the same reason that you should not setwd("C:/Users/jhill/Documents") at the top of any of your R scripts. That will work on your computer, but it is not portable. Luckily, Inno Setup provides support for 100s of constants, which will return the correct string value for each user’s environment.

Here are some of our favorites:

  • “pf”: The path of the system’s Program Files directory
  • “win”: The system’s Windows directory, usually “C:/Windows”
  • “sd”: The System Directory, typically “C:”
  • “userdocs”: The path to My Documents
  • “userdesktop”: The path to the user’s desktop

Inno Setup supports every version of Windows released since 2000, so these constants are very useful tools when you don’t know what version of Windows your users have. create_app defaults to default_dir = "userdocs" because some IT controls prevent you from working out of Program Files.

create_app(
	app_name    = "myapp",
	app_dir     = "path/to/myapp",
	default_dir = "pf")

Privileges

Some IT departments like to press “next”, “next”, “next”, and “finish” for you, so RInno supports that level of control. create_app defaults to privilege = "lowest", which will allow your users to install your app on their own, but you can elevate the privilege level to “poweruser” and “admin”. These will ask for elevated rights when someone tries to install your app.

create_app(
	app_name  = "myapp",
	app_dir   = "path/to/myapp",
	privilege = "admin")

Icons

To change your app’s icon: You need to copy the new icon into app_dir and update the file name of app_icon = "new_app_icon.ico".

If you also don’t like our taste in setup icons: Feel free to download your own and add setup_icon = "new_setup_icon.ico".

create_app(
	app_name   = "myapp",
	app_dir    = "path/to/myapp",
	app_icon   = "new_app_icon.ico",
	setup_icon = "new_setup_icon.ico")

Compression Options

RInno supports 17 different compression methods including zip, bzip, lzma and lzma2. In general, higher levels of compression take longer and require more memory to compress/decompress. zip is fast and requires very little memory, but it does not compress as well as the other methods. bzip is somewhere in the middle, and lzma compresses the best but takes the longest and requires the most memory.

create_app(
	app_name    = "myapp",
	app_dir     = "path/to/myapp",
	compression = "bzip")

Custom Messaging – Last Page

infoafter.txt is copied into your app_dir by copy_installation via create_app. If you would like to customize the message your users see at the end of your installer, add the name of a .txt or .rtf file to the info_after arg of create_app and edit the document accordingly.

create_app(
	app_name   = "myapp",
	app_dir    = "path/to/myapp",
	info_after = "infoafter.txt")

To leave a comment for the author, please follow the link and comment on their blog: FI Labs - R Feed.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)