├── .gitignore ├── img ├── sample-app.png └── shiny-base.png ├── Makefile ├── Singularity ├── LICENSE ├── prepare_template.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | shiny-server.conf 2 | shiny.simg 3 | -------------------------------------------------------------------------------- /img/sample-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsoch/singularity-shiny/HEAD/img/sample-app.png -------------------------------------------------------------------------------- /img/shiny-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsoch/singularity-shiny/HEAD/img/shiny-base.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | run: clean build 2 | 3 | clean: 4 | sudo rm -rf shiny.simg 5 | 6 | build: clean 7 | sudo singularity build shiny.simg Singularity 8 | -------------------------------------------------------------------------------- /Singularity: -------------------------------------------------------------------------------- 1 | Bootstrap: docker 2 | From: rocker/shiny 3 | 4 | # sudo singularity build shiny.simg Singularity 5 | 6 | %labels 7 | maintainer vsochat@stanford.edu 8 | 9 | %post 10 | mkdir -p /var/log/shiny-server 11 | chown shiny.shiny /var/log/shiny-server 12 | 13 | %runscript 14 | exec shiny-server 2>&1 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Vanessa Sochat 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /prepare_template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | usage () { 4 | 5 | echo "Steps: 6 | ---------------------------------------------------------------------- 7 | 1. Use this script to prepare your shiny-server.conf (configuration) 8 | 9 | /bin/bash prepare_template.sh 10 | 11 | ---------------------------------------------------------------------- 12 | 2. If needed, you can provide the following arguments 13 | 14 | Commands: 15 | help: show help and exit 16 | start: the generation of your config 17 | 18 | Options: 19 | --port: the port for the application (e.g., shiny default is 3737) 20 | --user: the user for the run_as directive in the shiny configuration 21 | --base: base folder with applications 22 | --logs: temporary folder with write for logs (not required) 23 | --disable-index: disable directory indexing 24 | 25 | ---------------------------------------------------------------------- 26 | 3. Make sure Singularity is loaded, and run the container using 27 | the commands shown by the template. 28 | 29 | " 30 | } 31 | 32 | # Start the application 33 | SHINY_START="no"; 34 | 35 | # Port for Flask 36 | CHECK_PORT="notnull" 37 | while [[ ! -z $CHECK_PORT ]]; do 38 | SHINY_PORT=$(( ( RANDOM % 60000 ) + 1025 )) 39 | CHECK_PORT=$(netstat -atn | grep $SHINY_PORT) 40 | done 41 | 42 | # Base for apps 43 | SHINY_BASE=/srv/shiny-server; 44 | 45 | # Log folder assumed to be bound to 46 | SHINY_LOGS=$(mktemp -d /tmp/shiny-server.XXXXXX) && rmdir ${SHINY_LOGS}; 47 | 48 | # Disable indexing (on, default, is not disabled) 49 | DISABLE_DIRINDEX="on"; 50 | 51 | # User to run_as, defaults to docker 52 | SHINY_USER="${USER}" 53 | 54 | if [ $# -eq 0 ]; then 55 | usage 56 | exit 57 | fi 58 | 59 | while true; do 60 | case ${1:-} in 61 | -h|--help|help) 62 | usage 63 | exit 64 | ;; 65 | -s|--start|start) 66 | SHINY_START="yes" 67 | shift 68 | ;; 69 | -p|--port|port) 70 | shift 71 | SHINY_PORT="${1:-}" 72 | shift 73 | ;; 74 | -b|--base|base) 75 | shift 76 | SHINY_BASE="${1:-}" 77 | shift 78 | ;; 79 | -u|--user) 80 | shift 81 | SHINY_USER="${1:-}" 82 | shift 83 | ;; 84 | -di|--disable-index|disable-index) 85 | DISABLE_DIRINDEX="off" 86 | shift 87 | ;; 88 | -l|logs|--logs) 89 | shift 90 | SHINY_LOGS="${1:-}" 91 | shift 92 | ;; 93 | -*) 94 | echo "Unknown option: ${1:-}" 95 | exit 1 96 | ;; 97 | *) 98 | break 99 | ;; 100 | esac 101 | done 102 | 103 | # Functions 104 | 105 | function prepare_conf() { 106 | SHINY_PORT=$1 107 | SHINY_BASE=$2 108 | SHINY_LOGS=$3 109 | DISABLE_DIRINDEX=$4 110 | SHINY_USER=$5 111 | CONFIG="run_as ${SHINY_USER}; 112 | server { 113 | listen ${SHINY_PORT}; 114 | 115 | # Define a location at the base URL 116 | location / { 117 | 118 | # Host the directory of Shiny Apps stored in this directory 119 | site_dir ${SHINY_BASE}; 120 | 121 | # Log all Shiny output to files in this directory 122 | log_dir ${SHINY_LOGS}; 123 | 124 | # When a user visits the base URL rather than a particular application, 125 | # an index of the applications available in this directory will be shown. 126 | directory_index ${DISABLE_DIRINDEX}; 127 | } 128 | }" 129 | echo "${CONFIG}"; 130 | } 131 | 132 | 133 | # Are we starting the server? 134 | 135 | if [ "${SHINY_START}" == "yes" ]; then 136 | 137 | echo "Generating shiny configuration..."; 138 | echo "port: ${SHINY_PORT}"; 139 | echo "logs:" ${SHINY_LOGS}; 140 | echo "base: ${SHINY_BASE}"; 141 | echo "run_as: ${SHINY_USER}"; 142 | 143 | # Prepare the template 144 | 145 | CONFIG=$(prepare_conf $SHINY_PORT $SHINY_BASE $SHINY_LOGS $DISABLE_DIRINDEX $SHINY_USER); 146 | 147 | # Temporary directories, if don't exist 148 | mkdir -p "${SHINY_LOGS}"; 149 | mkdir -p ${SHINY_LOGS}/logs; 150 | mkdir -p ${SHINY_LOGS}/lib; 151 | 152 | # Configuration file 153 | echo "${CONFIG}" > "shiny-server.conf"; 154 | echo "Server logging will be in ${SHINY_LOGS}"; 155 | echo 156 | echo "To run your server: 157 | 158 | module load singularity 159 | singularity run --bind $SHINY_LOGS/logs:/var/log/shiny \\ 160 | --bind $SHINY_LOGS/lib:/var/lib/shiny-server \\ 161 | --bind shiny-server.conf:/etc/shiny-server/shiny-server.conf shiny.simg 162 | 163 | --------------------------------------------------------------------------- 164 | For custom applications, also add --bind $SHINY_BASE:/srv/shiny-server 165 | To see your applications, open your browser to http://127.0.0.1:$SHINY_PORT or 166 | open a ssh connection from your computer to your cluster. 167 | " 168 | exit 169 | else 170 | usage 171 | fi 172 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Singularity Shiny 2 | Singularity Image to run a local shiny server. 3 | 4 | ## Build 5 | Use the makefile 6 | 7 | ``` 8 | make 9 | ``` 10 | 11 | or build on your own: 12 | 13 | ``` 14 | sudo singularity build shiny.simg Singularity 15 | ``` 16 | 17 | ## Generate Configuration 18 | You will first generate a custom configuration for your user, and it will 19 | give you instructions for usage: 20 | 21 | ``` 22 | $ /bin/bash prepare_template.sh 23 | 24 | Steps: 25 | ---------------------------------------------------------------------- 26 | 1. Use this script to prepare your shiny-server.conf (configuration) 27 | 28 | /bin/bash prepare_template.sh 29 | 30 | ---------------------------------------------------------------------- 31 | 2. If needed, you can provide the following arguments 32 | 33 | Commands: 34 | help: show help and exit 35 | start: the generation of your config 36 | 37 | Options: 38 | --port: the port for the application (e.g., shiny default is 3737) 39 | --user: the user for the run_as directive in the shiny configuration 40 | --base: base folder with applications 41 | --logs: temporary folder with write for logs (not required) 42 | --disable-index: disable directory indexing 43 | 44 | ---------------------------------------------------------------------- 45 | 3. Make sure Singularity is loaded, and run the container using 46 | the commands shown by the template. 47 | 48 | ``` 49 | When you add `start` it will do the generation. Here we don't supply any arguments 50 | so that they are randomly generated. 51 | 52 | ``` 53 | $ /bin/bash prepare_template.sh start 54 | Generating shiny configuration... 55 | port: 9870 56 | logs: /tmp/shiny-server.gG1X2Z 57 | base: /srv/shiny-server 58 | Server logging will be in /tmp/shiny-server.gG1X2Z 59 | 60 | To run your server: 61 | 62 | module load singularity/2.4.6 63 | singularity run --bind /tmp/shiny-server.gG1X2Z/logs:/var/log/shiny \ 64 | --bind /tmp/shiny-server.gG1X2Z/lib:/var/lib/shiny-server \ 65 | --bind shiny-server.conf:/etc/shiny-server/shiny-server.conf shiny.simg 66 | 67 | --------------------------------------------------------------------------- 68 | For custom applications, also add --bind /srv/shiny-server:/srv/shiny-server 69 | To see your applications, open your browser to http://127.0.0.1:9870 or 70 | open a ssh connection from your computer to your cluster. 71 | 72 | ``` 73 | 74 | The configuration is generated in your present working directory: 75 | 76 | ``` 77 | $ cat shiny-server.conf 78 | run_as vanessa; 79 | server { 80 | listen 9098; 81 | 82 | # Define a location at the base URL 83 | location / { 84 | 85 | # Host the directory of Shiny Apps stored in this directory 86 | site_dir /srv/shiny-server; 87 | 88 | # Log all Shiny output to files in this directory 89 | log_dir /tmp/shiny-server.PtVRXE; 90 | 91 | # When a user visits the base URL rather than a particular application, 92 | # an index of the applications available in this directory will be shown. 93 | directory_index on; 94 | } 95 | } 96 | ``` 97 | 98 | ## Start Server 99 | Once you have that template, follow the instructions to run the container. The 100 | temporary folder is already created for you. 101 | 102 | ``` 103 | singularity run --bind /tmp/shiny-server.gG1X2Z/logs:/var/log/shiny \ 104 | --bind /tmp/shiny-server.gG1X2Z/lib:/var/lib/shiny-server \ 105 | --bind shiny-server.conf:/etc/shiny-server/shiny-server.conf shiny.simg 106 | [2018-04-07T00:14:17.403] [INFO] shiny-server - Shiny Server v1.5.7.890 (Node.js v8.10.0) 107 | [2018-04-07T00:14:17.405] [INFO] shiny-server - Using config file "/etc/shiny-server/shiny-server.conf" 108 | [2018-04-07T00:14:17.456] [INFO] shiny-server - Starting listener on 0.0.0.0:9870 109 | ``` 110 | 111 | ## Interface 112 | When you open your browser to the port instructed, you will see the root of shiny! 113 | 114 | ![img/shiny-base.png](img/shiny-base.png) 115 | 116 | You can check out the sample apps: 117 | 118 | ![img/sample-app.png](img/sample-app.png) 119 | 120 | You can press Control+C to exit the server and stop the container. Be careful with running 121 | Shiny with Singularity - if you lose connection to the container and the server is 122 | running, it will remain as a ghost process. When Singularity has the ability for 123 | the start script to take arguments, we will be able to run it as an instance 124 | (but not yet). 125 | 126 | ## Customization 127 | If you shell inside and look under /srv/shiny-server, you will see all the default 128 | (sample) apps! 129 | 130 | ``` 131 | singularity shell shiny.simg 132 | $ ls /src/shiny-server 133 | ls /srv/shiny-server/ 134 | 01_hello 03_reactivity 05_sliders 07_widgets 09_upload 11_timer sample-apps 135 | 02_text 04_mpg 06_tabsets 08_html 10_download index.html 136 | ``` 137 | This means that when you run the container, if you add a bind to a folder of your own apps 138 | here, you can add your custom applications. The bind would look something like: 139 | 140 | ``` 141 | --bind /path/to/apps/folder:/srv/shiny-server 142 | ``` 143 | 144 | You can also choose to disable the indexing, meaning that someone that navigates to 145 | the root of the server (at the port) won't be able to explore all of your apps. 146 | 147 | ``` 148 | $ /bin/bash prepare_template.sh --disable-index 149 | ``` 150 | 151 | You can also customize the port, temporary folder, "run_as" user, and base (if somewhere other than 152 | /srv/shiny-server). Have fun! 153 | --------------------------------------------------------------------------------