Preserve environment variables when spawning shiny processes within a container - r

I have a running Docker container with the shiny server from the slightly modified rocker/shiny image.
The default shiny-server.conf file sets the shiny user as the one under
# Define the user we should use when spawning R Shiny processes
run_as shiny;
means the server is running as root by default, but the worker processes for shiny apps are run as user shiny
The apps themselves use a data warehouse connection to the SQL server, initialized via RODBC. While we did not want to put the entire connection details string (including DB host and password) into the codebase, we wanted to read them from the environment variables with which the container is created by running the following routine
HOST <- Sys.getenv("host")
DB <- Sys.getenv("db")
UID <- Sys.getenv("uid")
PWD <- Sys.getenv("pwd")
conn<-paste0("driver={ODBC Driver 17 for SQL Server};server=",HOST,";database=",DB,";uid=",UID,";pwd=",PWD)
dbhandle<-odbcDriverConnect(conn)
The problem is, that those env variables are empty when the worker process is spawned within a container as the user shiny.
If I try to run the same code in the interactive R console (as both root, or shiny user) I am getting the env variables as expected.
Any input would be much appreciated. Please note I do not intend to use docker secrets as I am not running the app within a docker swarm cluster, just a standalone Rancher OS host.
EDIT:
While .Renviron file might be a viable alternative to solving that particular problem, it would entail putting the variables into the codebase, which we are trying to avoid here.

I added the following in shiny-server.sh start script which is the docker container's CMD, as suggested by Ralf Stubner
env > /home/shiny/.Renviron
chown shiny.shiny /home/shiny/.Renviron

Related

Input doesn't pass through into attached container with R session

I was trying to do some debugging in R code when it's already on the container.
After doing docker attach #container-id, I attach as expected to the running process, I get to see the browser prompt as well. However, I cannot interact with the R session due to the input not passing through to R session. Commands that I enter stay in a buffer and only get executed in the local bash after the container detaches.
R session is started through ShinyProxy that spins up a Docker container with R instance in which the following script is run:
#!/bin/bash
R -e "shiny::runApp(host='0.0.0.0', port=3838)"
I'm connecting to the machine with docker from windows using putty. How can I make my input pass through into the attacked R container?
The problem turned out to be due to putty which seems to send something to the input resulting in the closing of Browser prompt.
Using ssh client from git provided a solution.

run local Rscript on remote R server

I am trying to run some Rscripts on a remote server which has a fixed IP-Adress.
Background is the following.
I connected a Front-end web app with R and am able to insert different values, which are then passed to R, where different outcomes are evaluated.
Everything works fine when I run it locally.
I want to be able to run the Web-app from every location, so I set up an RServer with username, password etc.
What I want to next is to establish a connection between R and the server.
I wasn't able to find anything on that topic yet, so I hope you can help me with this.
Establish a connection to the Rserver with some IP.
Login with my username and password
Tell my R script where to find the Rscript.exe file
Doing that locally I just tell my php-file:
$command = '"C:\Users\Username\Documents\R\R-3.3.1\bin\Rscript.exe" "'.__DIR__.'\rfile.R" '.$json;
So I tell him where to find my RScript.exe and to read with that my rfile.R.
Thanks for your help.

Will shiny work online without shiny-server?

I need to integrate a shiny application to some existing php/html code. And I've seen that its possible to run the app by typing :
R -e "shiny::runApp('path_to_shiny', port=9999)"
So I've plan to run this script on the server and put a iframe which redirect to this. May it work ?
You can let the Shiny server run on a different port than the webserver (default 80). For example, see the default configuration of shiny server, which lets shiny run on port 3838. This is better than running an R process with the shiny package inside of it, because you get startup scripts for shiny server that handle all sorts of cases that you would have to handle manually otherwise (e.g., restarting the R process when the server reboots, etc).
Yes, you need to add host argument with '0.0.0.0' in your code as well like below,
R -e "shiny::runApp('path_to_shiny', host='0.0.0.0', port=9999)"
And, you also need to be sure that that server is not using port 9999, for example, if web server uses port 80 (i.e. yoururl.com), you may need to change to some port something like yoururl.com:8080, in case of any conflict. So basically you can run two different apps like this.

How to setup AWS cluster to work with openCPU?

I have two EC2 machines: master and slave. SSH keys are generated for user ubuntu and saved to ~/.ssh/authorized_keys on both machines. Thus I can use the cluster from master node as ubuntu user like this:
library(doSNOW)
cluster_options <-
c(rep(list(
list(host = "ec2-xx-xx-xx-xx.compute-1.amazonaws.com",
snowlib = "/usr/local/lib/R/site-library")), 2))
cl <- makeCluster(cluster_options, type = "SOCK")
clusterApply(cl, 1:2, get("+"), 3)
stopCluster(cl)
But when I call it via openCPU it gives permission denied message.
Currently I'm thinking about two possible solutions:
Add SSH keys for opencpu user. But I don't have idea how to do it as opencpu is non-interactive user
Make slaves accessible by master without any SSH keys
I'd prefer the first way and definitely need help here. But second way is also ok.
Finally I ended up with solution. It has several aspects:
Hostbased Authentication should be configured between two EC2 nodes. Good tutorial can be found here: https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Host-based_Authentication
OpenCPU should be installed on both nodes.
SSH keys should be generated for www-data user (R process is executed with this user). Delicate aspect here is that www-data is non-interactive user, so we need to make it interactive (edit /etc/passwd), generate SSH keypair for www-data, add public key to server node and make www-data non-interactive again.
Not so elegant, but it works :)

Amazon EC2 / RStudio : Is there are a way to run a job without maintaining a connection?

I have a long running job that I'd like to run using EC2 + RStudio. I setup the EC2 instance then setup RStudio as a page on my web browser. I need to physically move my laptop that I use to setup the connection and run the web browser throughout the course of the day and my job gets terminated in RStudio but the instance is still running on the EC2 dashboard.
Is there a way to keep a job running without maintaining an active connection?
Does it have to be started / controlled via RStudio?
If you make your task a "normal" R script, executed via Rscript or littler, then you can run them from the shell ... and get to
use old-school tools like nohup, batch or at to control running in the background
use tools like screen, tmux or byobu to maintain one or multiple sessions in which you launch the jobs, and connect / disconnect / reconnect at leisure.
RStudio Server works in similar ways but AFAICT limits you to a single user per user / machine -- which makes perfect sense for interactive work but is limiting if you have a need for multiple sessions.
FWIW, I like byobu with tmux a lot for this.
My original concern that it needed to maintain a live connection was incorrect. It turns out the error was from running out of memory, it just coincided with being disconnected from the internet connection.
An instance is started from the AWS dashboard and stopped or terminated from there also. As long as it is still running it can be accessed from an RStudio tab by copying the public DNS to the address bar on the web page and logging in again.

Resources