├── .gitignore ├── README.md ├── application.yml ├── docker-compose.yml ├── nginx.conf ├── run_first_time.sh └── webapp ├── Dockerfile ├── Rprofile.site ├── shinyapps └── app.R └── shinylog └── placeholder.txt /.gitignore: -------------------------------------------------------------------------------- 1 | nginx/certs/localhost 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Telethon Kids Institute ShinyProxy Docker Template 2 | ================ 3 | 4 | ### Docker Ubuntu Server Installation/Set-up 5 | 6 | 1. Docker CE for Ubuntu installation: 7 | 8 | 2. Follow post-installation instructions: 9 | 10 | 1. configuring the daemon.json file will not work with Ubuntu 16.04 11 | (and above), instead add the following to the systemd unit file: 12 | `ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:275 -H 13 | unix:///var/run/docker.sock` 14 | 3. Install docker-compose 15 | (optional): 16 | 17 | 18 | 19 | sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0-rc1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 20 | sudo chmod +x /usr/local/bin/docker-compose 21 | sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose 22 | 23 | ### Docker App Deployment 24 | 25 | 1. Build Shiny App Docker image: 26 | 1. Change current directory to project folder `cd ...` 27 | 2. `docker build -t telethonkids/new_shiny_app .//webapp` 29 | 2. Start Docker containers 30 | 3. `docker-compose up -d` 31 | 3. App is ready on port 80: in browser, go to 192.168.99.100 (windows) 32 | or 127.17.0.1 (Ubuntu) 33 | 34 | ### HTTPS encryption 35 | 36 | [These instructions](https://medium.com/@pentacent/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71) 37 | were used to set up a secure HTTPS connection with Certbot SSL certificates. 38 | Also see [here](https://github.com/wmnnd/nginx-certbot). 39 | 40 | This will not work out of the box, the NGINX configuration file will need to be 41 | updated with your domain name (which is required) at the indicated places in 42 | `nginx.conf`. `init-letsencrypt.sh` also needs to be configured with your domain 43 | names(s) and email address. 44 | 45 | The following commands will need to be run on the host machine in order to obtain 46 | the first valid certificates: first run `chmod +x init-letsencrypt.sh` then 47 | `./init-letsencrypt.sh`. 48 | 49 | If HTTPS security is not wanted then you will need to remove the indicated chunks 50 | of code in `nginx.conf`. 51 | -------------------------------------------------------------------------------- /application.yml: -------------------------------------------------------------------------------- 1 | proxy: 2 | title: Telethon Kids Institute Shiny Apps 3 | hide-navbar: false 4 | landing-page: / 5 | heartbeat-rate: 10000 6 | heartbeat-timeout: 600000 7 | port: 8080 8 | docker: 9 | internal-networking: true 10 | specs: 11 | - id: shiny_app 12 | display-name: New Shiny App 13 | description: The default app when initiating a new shiny app via. RStudio 14 | container-cmd: ["R", "-e", "shiny::runApp('/root/app')"] 15 | container-image: telethonkids/new_shiny_app 16 | container-network: tki-net 17 | container-env: 18 | user: "shiny" 19 | environment: 20 | - APPLICATION_LOGS_TO_STDOUT=false 21 | usage-stats-url: http://influxdb:8086/write?db=shinyproxy_usage 22 | 23 | server: 24 | useForwardHeaders: true 25 | 26 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.6" 2 | services: 3 | nginx: 4 | image: nginx:alpine 5 | container_name: tki_nginx 6 | restart: on-failure 7 | networks: 8 | - tki-net 9 | volumes: 10 | - ./nginx.conf:/etc/nginx/nginx.conf 11 | - ./data/certbot/conf:/etc/letsencrypt 12 | - ./data/certbot/www:/var/www/certbot 13 | ports: 14 | - 80:80 15 | - 443:443 16 | command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" 17 | depends_on: 18 | - shinyproxy 19 | 20 | certbot: 21 | image: certbot/certbot 22 | container_name: certbot 23 | restart: on-failure 24 | volumes: 25 | - ./data/certbot/conf:/etc/letsencrypt 26 | - ./data/certbot/www:/var/www/certbot 27 | entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" 28 | 29 | influxdb: 30 | image: influxdb:1.7.3-alpine 31 | container_name: tki_influxdb 32 | restart: on-failure 33 | volumes: 34 | - ./run_first_time.sh:/home/run_first_time.sh 35 | - type: volume 36 | source: shinyproxy_usage 37 | target: /var/lib/influxdb 38 | volume: 39 | nocopy: true 40 | networks: 41 | - tki-net 42 | ports: 43 | - 8083:8083 44 | - 8086:8086 45 | 46 | shinyproxy: 47 | depends_on: 48 | - influxdb 49 | image: telethonkids/shinyproxy 50 | container_name: tki_shinyproxy 51 | restart: on-failure 52 | networks: 53 | - tki-net 54 | volumes: 55 | - ./application.yml:/opt/shinyproxy/application.yml 56 | - /var/run/docker.sock:/var/run/docker.sock 57 | expose: 58 | - 8080 59 | 60 | networks: 61 | tki-net: 62 | name: tki-net 63 | 64 | volumes: 65 | shinyproxy_usage: 66 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | events { worker_connections 1024; } 3 | 4 | http { 5 | sendfile on; 6 | upstream tki_shinyproxy { 7 | server tki_shinyproxy:8080; 8 | } 9 | 10 | #### START REMOVE - remove this block of code if SSL certification is not wanted #### 11 | server { 12 | listen 80; 13 | server_name example.org; #### UPDATE example.org to your domain name #### 14 | server_tokens off; 15 | 16 | location /.well-known/acme-challenge/ { 17 | root /var/www/certbot; 18 | } 19 | 20 | location / { 21 | return 301 https://$host$request_uri; 22 | } 23 | } 24 | #### END REMOVE #### 25 | 26 | server { 27 | listen 443 ssl; # listen 80; #### remove "listen 443 ssl; #" statement if SSL certification is not wanted #### 28 | server_name example.org; #### UPDATE example.org to your domain name #### 29 | server_tokens off; 30 | 31 | #### START REMOVE - remove this block of code if SSL certification is not wanted #### 32 | ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem; #### UPDATE example.org to your domain name #### 33 | ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem; #### UPDATE example.org to your domain name #### 34 | include /etc/letsencrypt/options-ssl-nginx.conf; 35 | ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; 36 | #### END REMOVE #### 37 | 38 | location / { 39 | proxy_pass http://tki_shinyproxy; 40 | 41 | proxy_http_version 1.1; 42 | proxy_set_header Upgrade $http_upgrade; 43 | proxy_set_header Connection "upgrade"; 44 | proxy_read_timeout 600s; 45 | proxy_buffering off; 46 | 47 | proxy_redirect off; 48 | proxy_set_header Host $host; 49 | proxy_set_header X-Real-IP $remote_addr; 50 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 51 | proxy_set_header X-Forwarded-Host $server_name; 52 | proxy_set_header X-Forwarded-Proto $scheme; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /run_first_time.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Author : Paul Stevenson 4 | # Create influxdb config file and database for shinyproxy usage statistics 5 | # only to be run once after the first "docker-compose up -d" on a system 6 | # run in docker with: docker exec tki_influxdb sh /home/run_first_time.sh 7 | 8 | # influxdb configuration file creation 9 | influxd config > influxdb.conf 10 | 11 | # create shinyproxy_usagestats database 12 | influx -execute 'CREATE DATABASE shinyproxy_usage' 13 | -------------------------------------------------------------------------------- /webapp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rocker/shiny:3.5.1 2 | 3 | RUN apt-get update && apt-get install libcurl4-openssl-dev libnode-dev -y &&\ 4 | mkdir -p /var/lib/shiny-server/bookmarks/shiny 5 | 6 | # Download and install library 7 | RUN R -e "install.packages(c('shinydashboard', 'shinyjs', 'V8'))" 8 | 9 | # copy the app to the image 10 | COPY shinyapps /root/app 11 | COPY Rprofile.site /usr/local/lib/R/etc/Rprofile.site 12 | 13 | # make all app files readable (solves issue when dev in Windows, but building in Ubuntu) 14 | RUN chmod -R 755 /root/app 15 | RUN chmod -R 755 /usr/local/lib/R/etc 16 | 17 | EXPOSE 3838 18 | 19 | CMD ["R", "-e", "shiny::runApp('/root/app')"] 20 | -------------------------------------------------------------------------------- /webapp/Rprofile.site: -------------------------------------------------------------------------------- 1 | local({ 2 | options(shiny.port = 3838, shiny.host = "0.0.0.0") 3 | }) 4 | -------------------------------------------------------------------------------- /webapp/shinyapps/app.R: -------------------------------------------------------------------------------- 1 | # 2 | # This is a Shiny web application. You can run the application by clicking 3 | # the 'Run App' button above. 4 | # 5 | # Find out more about building applications with Shiny here: 6 | # 7 | # http://shiny.rstudio.com/ 8 | # 9 | 10 | library(shiny) 11 | 12 | # Define UI for application that draws a histogram 13 | ui <- fluidPage( 14 | 15 | # Application title 16 | titlePanel("Old Faithful Geyser Data"), 17 | 18 | # Sidebar with a slider input for number of bins 19 | sidebarLayout( 20 | sidebarPanel( 21 | sliderInput("bins", 22 | "Number of bins:", 23 | min = 1, 24 | max = 50, 25 | value = 30) 26 | ), 27 | 28 | # Show a plot of the generated distribution 29 | mainPanel( 30 | plotOutput("distPlot") 31 | ) 32 | ) 33 | ) 34 | 35 | # Define server logic required to draw a histogram 36 | server <- function(input, output) { 37 | 38 | output$distPlot <- renderPlot({ 39 | # generate bins based on input$bins from ui.R 40 | x <- faithful[, 2] 41 | bins <- seq(min(x), max(x), length.out = input$bins + 1) 42 | 43 | # draw the histogram with the specified number of bins 44 | hist(x, breaks = bins, col = 'darkgray', border = 'white') 45 | }) 46 | } 47 | 48 | # Run the application 49 | shinyApp(ui = ui, server = server) 50 | 51 | -------------------------------------------------------------------------------- /webapp/shinylog/placeholder.txt: -------------------------------------------------------------------------------- 1 | placeholder to sync directory with git --------------------------------------------------------------------------------