Configuration

Overview

The server configuration is mainly done in a file named application.yml. If the default values must be overridden, this can be done by adding a file application.yml in the same folder where you launch the shinyproxy-*.jar file and specify properties in the YAML format. The standard configuration has the following values:

shiny:
  proxy:
    title: Open Analytics Shiny Proxy
    logo-url: http://www.openanalytics.eu/sites/www.openanalytics.eu/themes/oa/logo.png
    landing-page: /
    heartbeat-rate: 10000
    heartbeat-timeout: 60000
    port: 8080
    authentication: ldap
    admin-groups: scientists
    # Example: 'simple' authentication configuration
    users:
    - name: jack
      password: password
      groups: scientists
    - name: jeff
      password: password
      groups: mathematicians
    # Example: 'ldap' authentication configuration
    ldap:
      url: ldap://ldap.forumsys.com:389/dc=example,dc=com
      user-dn-pattern: uid={0}
      group-search-base:
      group-search-filter: (uniqueMember={0})
      manager-dn: cn=read-only-admin,dc=example,dc=com
      manager-password: password
    # Docker configuration
    docker:
      cert-path: /home/none
      url: http://localhost:2375
      port-range-start: 20000
  apps:
  - name: 01_hello
    display-name: Hello Application
    description: Application which demonstrates the basics of a Shiny app
    docker-cmd: ["R", "-e", "shinyproxy::run_01_hello()"]
    docker-image: openanalytics/shinyproxy-demo
    groups: [scientists, mathematicians]
  - name: 06_tabsets
    docker-cmd: ["R", "-e", "shinyproxy::run_06_tabsets()"]
    docker-image: openanalytics/shinyproxy-demo
    groups: scientists

logging:
  file:
    shinyproxy.log

General

The first block of configuration in the application.yml file concerns general configuration values for the ShinyProxy application:

  • title: title that is displayed in the ShinyProxy navigation bar;
  • logo-url: url of the logo that is displayed in the ShinyProxy navigation bar; this can also be a local file using the file scheme (file://)
  • landing page: landing page resource; default value is /;
  • heartbeat-rate: the user's browser will sent a heartbeat call every heartbeat-rate milliseconds; default value is 10000 (10 seconds);
  • heartbeat-timeout: if the server does not receive a heartbeat for heartbeat-timeout milliseconds, the relevant proxy will be released (and the container stopped); default value is 60000 (60 seconds);
  • port: port to be used by ShinyProxy; the default port is 8080.
  • authentication: authentication method; one of ldap (default), simple or none
  • admin-groups: one or more groups (as defined in the authentication back-end) that have access to the administrative interface of ShinyProxy e.g. to view and manage active sessions; multiple groups are enclosed in square brackets and separated by commas.

Besides the basic configuration options described above, there are also some more advanced configuration options that are not part of the default configuration:

  • container-wait-time: timeout for the container to be available to ShinyProxy; defaults to 20s (20000):
shiny:
  proxy:
    [...]
    container-wait-time: 20000

Note that a container is considered to be 'available' if its HTTP listener responds with status 200.

  • hide-navbar: boolean; if set to true the navigation bar at the top will be hidden; this may be useful when ShinyProxy is deployed as part of larger applications

Note:

  • ShinyProxy will run by default on the '/' context path; the context path can be configured using a server.contextPath setting
server:
  contextPath: /abc

Authentication

LDAP

When using LDAP authentication, ShinyProxy will use the provided LDAP url to:

  • Authenticate users by attempting to bind with their login name and password.
  • Authorize users to access apps by searching for any LDAP groups they are a member of, and matching those group names to the list of group names configured for the app.

With the default values (authentication: ldap), authentication will be done against the LDAP server at ldap.forumsys.com; to log in one can use the user name "tesla" and password "password".

In order to use it with your own LDAP directory, you can use the following fields:

  • url: the LDAP connection string, composed of the URL and base DN of the LDAP directory;
  • user-dn-pattern: pattern of the distinguished name for a user. Use this if all your users are in a single LDAP location;
  • user-search-filter: LDAP filter to search for users. Use this if your users are in different LDAP locations, and you cannot use user-dn-pattern;
  • user-search-base: search base to search for users. Only used if user-search-filter is set;
  • group-search-filter: LDAP filter used to search for group memberships;
  • group-search-base: search base to search for groups. Only used if group-search-filter is set;
  • manager-dn: the distinguished name of the user used to bind to the LDAP directory; leave empty if the initial bind is anonymous;
  • manager-password: the password of the user used to bind to the LDAP directory; can be omitted if manager-dn is empty (i.e. when the initial bind is anonymous).

Notes:

  • the base DN given in the url (e.g. dc=example,dc=com in ldap://ldap.forumsys.com:389/dc=example,dc=com) does not have to be repeated in user-search-base or group-search-base. However, it must be repeated in the manager-dn.
  • user-dn-pattern and user-search-filter support the placeholder {0} which will be replaced with the user's login name.
  • group-search-filter supports three placeholders: {0} maps to the user's DN, {1} maps to the user's login name, and {2} maps to the user's CN.

Environment Variables

When a user is authenticated, the following environment variables will be available in any Shiny application launched by the user:

  • SHINYPROXY_USERNAME: the name of the user, as used when logging in
  • SHINYPROXY_USERGROUPS: the groups the authenticated user is a member of, as a comma-separated value

Multiple LDAP providers

When multiple LDAP providers need to be configured (e.g. to support different domains or forests), this can be done using

shiny:
  proxy:
    ldap:
    - url: ldap://ldap.forumsys.com:389/dc=example,dc=com
      ...
    - url: ldap://another.ldap.server:389/...
      ...

instead of the single LDAP configuration

shiny:
  proxy:
    ldap:
      url: ldap://ldap.forumsys.com:389/dc=example,dc=com
      ...

StartTLS

Using LDAP with StartTLS can be achieved by adding a setting

shiny:
  proxy:
    ldap:
      starttls: simple

This setting may have the following values:

  • simple: StartTLS is enabled, using simple client authentication;
  • true: same as simple;
  • external: StartTLS is enabled, using external (certificate) client authentication;
  • (None): if the property is absent (default), StartTLS is disabled.

More information on the StartTLS extension can be found here.

Note:

  • LDAPS and LDAP with StartTLS are mutually exclusive; it is not possible to combine the two mechanisms.

Example: FreeIPA

When using a FreeIPA server for managing identities (e.g. the standard on RHEL), the configuration with the default directory tree will be:

ldap:
      url: ldaps://example.com:636/dc=example,dc=com
      manager-dn: uid=shinyproxy,cn=sysaccounts,cn=etc,dc=example,dc=com
      manager-password: xxxxxxxxxxxx
      user-dn-pattern: uid={0},cn=users,cn=accounts
      group-search-filter: (member={0})
      group-search-base: cn=groups,cn=accounts

Notes:

  • in this example uid=shinyproxy,cn=sysaccounts,cn=etc,dc=example,dc=com is a specific system account created to bind against the FreeIPA LDAP directory on behalf of ShinyProxy;

Example: Active Directory

ldap:
      url: ldaps://example.com:3269/dc=example,dc=com
      manager-dn: cn=shinyproxy,ou=Service Accounts,dc=example,dc=com
      manager-password: xxxxxxxxxxxx
      user-search-filter: (sAMAccountName={0})
      group-search-filter: (member={0})
      group-search-base: ou=Groups

Notes:

  • sAMAccountName is often used as the unique login name in Active Directory environments. That's why it is used here in the user-search-filter.
  • 3269 is the SSL-enabled port for the Global Catalog.

Single-Sign On / Keycloak

A second type of authentication is Keycloak authentication, a very powerful option that delegates authentication and authorization to the open source identity and access management system Keycloak supported by Red Hat. Many advanced features are available to ShinyProxy such as User Federation, Identity Brokering and Social Login.

Keycloak authentication can be configured using

shiny:
  proxy:

    [...]

    authentication: keycloak

in the application.yml file. The details related to the application identifiers and secrets for each of the social platforms can be configured in a separate keycloak block:

shiny:
  proxy:

  [...]

    keycloak:
      realm: yoursso
      auth-server-url: http://yoururl.com:8180/auth
      resource: yourresource
      credentials-secret: your-credentials-secret

Further documentation on setting up Keycloak can be found here.

Social Authentication

A third type of authentication offered by ShinyProxy besides LDAP and Keycloak is so-called social authentication. This type of authentication allows users to log in with

  • Facebook,
  • Twitter,
  • Google,
  • Github or
  • Linkedin

accounts into ShinyProxy.

Social authentication can be configured using

shiny:
  proxy:

    [...]

    authentication: social

in the application.yml file. The details related to the application identifiers and secrets for each of the social platforms can be configured in a separate social block:

shiny:
  proxy:

  [...]

    social:
      facebook:
        app-id: yourfacebookappid
        app-secret: yourfacebookappsecret
      twitter:
        app-id: yourtwitterappid
        app-secret: yourtwitterappsecret
      google:
        app-id: yourgoogleappid
        app-secret: yourgoogleappsecret
      github:
        app-id: yourgithubappid
        app-secret: yourgithubappsecret
      linkedin:
        app-id: yourlinkedinappid
        app-secret: yourlinkedinappsecret

Since no authorization is offered by the social platforms, authorization logic is not implemented and authenticated users will be able to access all public applications.

Simple Authentication

Besides LDAP and social authentication, ShinyProxy also offers the possibility to define users and groups inside the application.yml file. In order to select this authentication method, one needs to choose the simple authentication method:

shiny:
  proxy:

    [...]

    authentication: simple

The example configuration demonstrates how users and groups can be specified:

shiny:
  proxy:
    users:
    - name: jack
      password: password
      groups: scientists
    - name: jeff
      password: password
      groups: mathematicians

Since passwords are contained in clear text in the application.yml file, this is not a secure way to set up authentication, but can be useful for demonstration purposes (e.g. in the absence of a network connection) or for very specific use cases.

Note:

  • the user name of the authenticated user is made available to the Shiny application via the environment variable SHINYPROXY_USERNAME
  • the groups the authenticated user is member of are made available to the Shiny application via the environment variable SHINYPROXY_USERGROUPS

No authentication

In some scenarios, one wants to disable the ShinyProxy authentication. This can be done using

shiny:
  proxy:

    [...]

    authentication: none

Note:

  • with authentication: none the environment variable SHINYPROXY_USERNAME inside the Docker container will contain a random hash instead of the user name; if a user name needs to be passed from an external application it may be more useful to pass this information to the Shiny application via the URL (see this article).

Container Back-ends

ShinyProxy supports multiple container back-ends to run the Shiny apps, namely

  • a plain Docker host (default)
  • a Docker Swarm cluster and
  • a Kubernetes cluster

The backend can be configured using

shiny:
  proxy:
    container-backend: docker  

The container-backend can be one of docker (default), docker-swarm or kubernetes. The specific configuration these back-ends is documented below.

Docker

The Docker back-end is the default back-end for ShinyProxy. In order to specify it explicitly, one can set shiny.proxy.container-backend to docker.

The configuration of the back-end can be done using the following properties:

  • cert-path: path to the folder that contains the certificate files (ca.pem, cert.pem and key.pem) used for encrypted traffic to the docker daemon; if the files have other names or are located in different folders, symbolic links can be used (for ca.pem, cert.pem and key.pem) that point to the actual certificate files. If a non-existing path is used as cert-path, traffic will not be encrypted; the default value for cert-path is set to /home/none; this property can be omitted when not applicable;
  • url: URL and port on which to connect to the docker daemon; the default value of http://localhost:2375 does not connect over TLS; this is not recommended for production environments;
  • container-protocol: optional setting to indicate the protocol to be used to communicate with the containers; can be one of http or https; if not set, the protocol is derived from the url specified (cf. above);
  • port-range-start: every docker container will be assigned a port on the docker host to which the ShinyProxy will proxy the traffic of a particular user; the value of port-range-start will be the port assigned to the first container that is started; by default the first port will be 20000 (second 20001, third 20002 etc.).
  • port-range-max: maximum port number to be handled by ShinyProxy (e.g. 20099, which allows to run a maximum of 100 containers if port-range-start is set to the default value 20000); this allows to limit the number of concurrent apps that can be managed by a single ShinyProxy instance or, in case multiple ShinyProxy instances launch docker containers on a shared Docker Swarm, can prevent the same port number being used by multiple such instances; the default value of port-range-max is -1 (no maximum). If the port pool is exhausted, the following error message will appear:
Cannot start container: all allocated ports are currently in use. Please try again later or contact an administrator.
  • internal-networking: set this to true if ShinyProxy will run as a container on the same Docker host; default value is false.

Note:

  • when internal-networking is true, no ports will be allocated per proxy and the port range settings are ignored (port-range-start and port-range-max); also, the proxy target URLs will use the container host name.

Docker Swarm

In order to use a Docker Swarm back-end, set shiny.proxy.container-backend to docker-swarm. The configuration of the back-end is not different from the configuration of a plain Docker back-end (cf. supra).

Note:

  • when internal-networking is true, no ports will be allocated per proxy and the port range settings are ignored (port-range-start and port-range-max); also, the proxy target URLs will use the container name.

Kubernetes

In order to use a Kubernetes back-end, set shiny.proxy.container-backend to kubernetes. The configuration of the back-end can be done using the following properties:

  • shiny.proxy.kubernetes.url: the URL of the apiserver
  • shiny.proxy.kubernetes.cert-path: the path to a dir containing ca.pem, cert.pem and key.pem to be used if url is https
  • shiny.proxy.kubernetes.namespace: the namespace to create pods in; the default value is default
  • shiny.proxy.kubernetes.api-version: the API version to use; the default value is v1
  • shiny.proxy.kubernetes.image-pull-policy: the pull policy for images; the default value is IfNotPresent
  • shiny.proxy.kubernetes.image-pull-secret: the name of a secret to use for pulling images from a registry
  • shiny.proxy.kubernetes.image-pull-secrets: see above, but for multiple secrets
  • shiny.proxy.kubernetes.privileged: should the container be privileged?; default value is false
  • shiny.proxy.kubernetes.internal-networking: set this to true if ShinyProxy will run inside the cluster itself; default value is false
  • shiny.proxy.kubernetes.container-protocol: the protocol to use when accessing a container; can be one of http (default) or https
  • shiny.proxy.kubernetes.port: the TCP port to access on the container; the default port is 3838

An example configuration is:

shiny:
  proxy:
    container-backend: kubernetes
    kubernetes:
      cert-path: /etc/certs
      url: https://1.2.3.4

Note:

  • when internal-networking is true, no ports will be allocated per proxy and the proxy target URLs will use the Pod IP.

Apps

Every single Shiny app served by Shiny Proxy has its own configuration block under apps:

    apps:
  - name: 01_hello
    docker-cmd: ["R", "-e", "shinyproxy::run_01_hello()"]
    docker-image: openanalytics/shinyproxy-demo
    groups: [scientists, mathematicians]
  - name: 06_tabsets
    docker-cmd: ["R", "-e", "shinyproxy::run_06_tabsets()"]
    docker-image: openanalytics/shinyproxy-demo
    groups: [scientists]

For each app, four fields can be specified:

  • name: the name that will be displayed for the app on the ShinyProxy landing page;
  • docker-cmd: the command that will be run when the Docker container is launched; typically this command will be the R command ("R") as well as the command that will launch the Shiny app ("-e", "shinyproxy::run_01_hello()");
  • docker-image: name of the docker image to be started for every new user of this app; by default a demo image (openanalytics/shinyproxy-demo) will be used;
  • groups: one or more groups (e.g. LDAP groups) a user needs to belong to in order to gain access to the app; multiple groups are enclosed in square brackets and separated by commas; this field allows to authorize access per app; to test the authorization with LDAP authentication, one can use gauss with password password as an example mathematician; user tesla with password password is one of the example scientists. Other users are described here.

Note:

  • apps for which groups are not specified will be handled as "public" applications in the sense that all authenticated users will be able to access these applications.

Besides the basic configuration options described above, there are also some more advanced configuration options that are not part of the default configuration:

  • docker-dns: a comma-separated list of IP addresses that are added as server lines in the /etc/resolv.conf file of the container; this is the equivalent of launching the container with a --dns option.
  • docker-env: one or more environment variables specified as
docker-env:
    VAR1: VALUE1
    VAR2: VALUE2

and that will be passed to the container; this is equivalent to docker run --env. - docker-env-file: a path to a file in which environment variables are specified to be passed to the container; this can be configured using

    docker-env-file: /path/to/env-file

and is equivalent to docker run --env-file.

  • docker-memory: memory limit for the Shiny application (e.g. 256m or 4g); units can be one of b, k, m, or g and the minimum is 4m. This is the equivalent of launching the container with a --memory option.
  • docker-network: facilities to set the networking of the container. This is the equivalent of launching the container with a --network option (and defaults to bridge which is also the Docker default).
  • docker-volumes: list of docker volumes to mount into the container; can be specified along
 docker-volumes: [ "/host/path1:/container/path1", "/host/path2:/container/path2" ]

and implements the functionality of docker run --volume.

  • logo-url: the URL to an image that can be used as the logo for an application; this can also be a local file using the file scheme (file://); if none of the applications in the application.yml specifies a logo-url field, the landing page will present the applications as a bullet list (cf. the default presentation in the openanalytics/shinyproxy-demo image).
  • port: the port on which the app is listening in the container; this setting will override the default port (3838)

Logging

In the default configuration, simple logging is enabled

logging:
  file:
    shinyproxy.log

and with this setting ShinyProxy will not only log to the console but also to the shinyproxy.log file in the directory in which it was started. The logging field offers much more and gives access to fine-grained and powerful logging configuration as detailed here. If you want e.g. to debug LDAP authentication, you can use something along

logging:
  level:
    org.springframework.security.ldap.authentication: DEBUG
    org.springframework.security.ldap.userdetails: DEBUG
  file:
    shinyproxy.log

instead.

Reporting Issues

ShinyProxy can be enabled to allow end users to send feedback or bug reports of the Shiny applications that are deployed on ShinyProxy.

In order to do so, a shiny.proxy.support block needs to be added to the application.yml file:

shiny:
  proxy:
    support:
      container-log-path: ./container-logs
      mail-to-address: some.user@somedomain.com

When ShinyProxy is started with this configuration an extra 'Report Issue' link will be displayed in the navigation bar. Users can click the link to send custom messages and these messages will be sent to the configured e-mail address (some.user@somedomain.com in the example configuration). The information that will be sent to the support address will include:

  • user name: name of the authenticated user that sends the issue
  • app name: only if user was running an app when he clicked the 'Report Issue' button
  • location: the URL in the user's browser
  • custom message: the message that the user entered in the Report Issue dialog
  • attachments: the stdout and stderr of the container that was running at the time (only if container-log-path is enabled in the configuration).

The attachments with the Shiny application logs (i.e. the containers logs with the stdout and stderr streams) are named using <container-id>_stdout.log and <container-id>_stderr.log as file names. These files will be collected and stored by ShinyProxy in the folder specified as the container-log-path in the configuration (cf. above; standard value ./container-logs).

The configuration of the mail server settings can be done in a separate spring.mail block, e.g.

spring:
  mail:
    host: smtp.gmail.com
    # TLS: 587 SSL: 465 Plain: 25
    port: 465
    username: my_username
    password: my_password
    properties:
      # For StartTLS
      mail.smtp.starttls.enable: true
      # For SSL
      #mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory

More information on these properties can be found here.

Note:

Optionally, one can also define the 'from' address to be used for the e-mail messages in the shiny.proxy.support block:

shiny:
  proxy:
    support:
      mail-from-address: issues@shinyproxy.io

Usage Statistics

ShinyProxy supports the tracking and saving usage statistics to see which apps are popular and by whom these are used. Currently, an influxDB back-end can be used for this purpose. With this back-end events are posted (via HTTP) to an InfluxDB instance.

Two properties allow to configure the posting of the events:

  • usage-stats-url: the URL of the InfluxDB instance and its query port; a typical value is http://localhost:8086
  • usage-stats-db: the name of the database in which to store the ShinyProxy specific events; a typical value is shinyproxy_usagestats

In the default configuration these properties are not set and, as a consequence, tracking of usage statistics in an InfluxDB instance is not enabled.