Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic ENV vars during Container Startup of rstudio-based images (solution) #170

Closed
Pit-Storm opened this issue Jun 9, 2021 · 8 comments

Comments

@Pit-Storm
Copy link
Contributor

Pit-Storm commented Jun 9, 2021

Hi folks!

As we discussed in #151, there are problems with updating timezone and locale settings dynamically through container runtime env vars. For that I am preparing a fix in my fork.

It contains two parts:

  1. Automatically update the timezone and/or locale setting of the containers OS on startup if the env vars TZ or LANG differ from the default.
  2. Automatically add arbitrary container env vars to the RStudio environment so that they are available in the IDE. (WIP)

The first point is done by providing two conditions in the userconf.sh those check if $LANG or $TZ differ from default. If so, the commands to update those settings on the container OS are executed.

So You are able to do e.g. docker run --rm -e PASSWORD=mypass -e TZ=Europe/Berlin -e LANG=de_DE.utf8 -p 8787:8787 --name rstudio rocker/rstudio and after that in the RStudio frontend Sys.timezone() and sessioninfo() will return the values set through the -e options.

This can be seen as a leap forward to automatically provide localization configuration to the users.

The second part is done through a dynamically generated update for the Renviron.site file on startup. The reason why we have to set env vars in Renviron.site is, because RStudio Server int he community edition does not pick up any env var from the bash context it starts from. This is not well documented in official docs but they giving hints with the PRO label. There are many issues and discussions not being resolved on this. E.g. on Stack Overflow or the RStudio community. The latter one pointed me to the solution I am providing here. This issue takes effect if you want to deploy an rstudio based image with an orchestrator or you want to dynamically pass env vars to rstudio during container startup by using the native -e Option.

It works as follows:

  • Create an upstream dockerfile and add the following lines: ENV MY_VAR default_value and RUN echo "MY_VAR=$MY_VAR" >> /etc/environment. (The Value set in the Dockerfile can be seen as a default value, because on startup the userconf.sh overwrites the value with the one you defined during startup.)
  • Then you can set the environment variable you defined in the dockerfile through CLI, kubernetes environment or other orchestrator config.
  • The userconf.sh will pick up the new line in /etc/environment and adds it to Renviron.site so that RStudio will add the env var to the environment of the rsession.

A solution where one do not has to create an downstream dockerfile would be better, but as far as I investigated, this is not possible at the moment.

Maybe someone can help with the second part. It should look like that:

  • for line in /etc/environment
  • echo "$line_till_equalsign=$value_at_runtime_or_default_in_file" >> $R_HOME/etc/Renviron.site

An other way could be to pick up all that is stored in /var/run/s6/container_environment and write FILENAME=content to $R_HOME/etc/Renviron.site during startup.

If something should be not clear or you have suggestions, don't hasitate to let me know.

If all this is done, I will send a Pull Request :-)

Kind regards!

@eddelbuettel
Copy link
Member

What about just using -v ~/some.local.Renviron.file:/root/.Renviron ?

edd@rob:~$ echo FOO123RANDOM=bar > .demo.Renviron
edd@rob:~$ docker run --rm -ti -v ${HOME}/.demo.Renviron:/root/.Renviron r-base Rscript -e 'print(Sys.getenv("FOO123RANDOM"))'
[1] "bar"
edd@rob:~$ 

@Pit-Storm
Copy link
Contributor Author

@eddelbuettel Thanks for the comment. In case of r-base or r-ver or something other than RStudio Server that will work. In these cases there will be no problem with dynamic ENV vars set during startup, because normal R and Rscript inherits the ENV-Vars correctly from the bash shell context it gets launched.
Only RStudio in the community edition is not doing it out of the bash login shell context.

Side note: If you write some env vars in a user related (~) .Renviron-File, this file is not going to be loaded if you open a .Rproject-file inside of RStudio (Server). So if one as an admin wants to privde an ENV var that will be present in ever case, one has to write it to *.site file(s).

I will update the Title that this specific issue is related to rstudio based images.

@Pit-Storm Pit-Storm changed the title Dynamic ENV vars during Container Startup (solution) Dynamic ENV vars during Container Startup of rstudio-based images (solution) Jun 10, 2021
@eddelbuettel
Copy link
Member

I think you may have misunderstand my point. We at the Rocker Project are acutely aware that RStudio Server 'swallows' environment variables. What I showed was NOT an export of a shell variable but rather provided (from the outside) a file which will be by R on startup due to the way R behaves (so that Rstudio cannot block it, help(Startup) details all that as you likely know) all of which should work as is, not require any furher changes and hence be a bit more defensive in its approach.

@Pit-Storm
Copy link
Contributor Author

Okay, well... I think we are coming from two perspectives onto that point. If one is using the rocker images (which are great work, no doubt) manually for local development in a container, your approach is working just fine. This is a usecase lot of users have.

The other perspective on that is, if you are using an orchestrator or even want to set env-vars on container startup it should be more easy to achive that task. For example: If you are using a CI-Pipeline with three tears (dev, test and prod) you will load different configuration upon a specific value of an env var set in the pipeline. It would be convenient to provide a solution for that usecase in addition.

My goal was to bring the discussion for a solution of the second usecase to the public and preventing many members of the community to solve the same issue multiple times. I should have made that more clearly in the first place. ✌

What do you think of the solution for $LANG and $TZ?

@eddelbuettel
Copy link
Member

eddelbuettel commented Jun 10, 2021

"It's complicated" with the env vars. I understand where you are coming from, I am just wary of unintended consequence when altering startup sequences or general configuration. I think that is best done locally so I would lean towards wiki writeups or vignettes rather than PRs. But it is Carl's and Noam's call, really.

By the way I have absolutely no issues with CI which I based for several 'heavier to build' projects off containers from the Rocker r-base corner.

@Pit-Storm
Copy link
Contributor Author

I found a really cool solution for the dynamic env vars.

We can use the S6 cont-environment dir to write variables and their values to ${R_HOME}/etc/Renviron.site file. My solution is like that:

for file in /var/run/s6/container_environment/*;
    do echo "${file##*/}=$(cat $file)" >> ${R_HOME}/etc/Renviron.site;
done;

this is a really less invasive solution.

I do have some checks for the TZ and LANG configuration, but it all works in general. PR is coming soon.

@cboettig
Copy link
Member

@Pit-Storm yes, I think using S6-init is reasonable here. Of course it will only run when the default init command is used, but that's probably okay since if a user requests cli R (a la docker run --ti -e VAR=value rocker/rstudio R) they will see the local env vars anyway in the R session, even though they won't see them in Renviron.site.

(Not directly related, but we also need to adjust the current scripts that are writing env vars to $R_HOME/etc/Renviron to use $R_HOME/etc/Renviron.site instead. )

PR welcome!

@cboettig
Copy link
Member

resolved in #186

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants