Hi,
I have a working shinyproxy app with ldap authentication. However, for retrieving data from the SQL-database i now use (not recommended) a hardcoded connectionstring in my R code with the credentials mentioned herein (i use a service user because my end users don't have permissions to query the database):
con <- DBI::dbConnect(odbc::odbc(), encoding = "latin1", .connection_string = 'Driver={Driver};Server=Server;Database=dbb;UID=UID;PWD=PWD')
I tried to replace this connection string with an environmental variable, that i pass from my linux host to the container. The R code now changed to:
connString <- Sys.getenv("CONNSTRING")
connString <- sub("\\\\","\\", connString)
con <- DBI::dbConnect(odbc::odbc(), encoding = "latin1", .connection_string = connString)
This works fine when running the container outside ShinyProxy, and thus by passing the environmental variables at runtime with the following docker command:
docker run -it --env-file .env.list app123
The environmental variable is also found when entering the running container and typing 'env'.
However, when using ShinyProxy, it is not clear to me how to configure this in the yaml config file and in the bash-command at runtime. How do i define the parameter container-env-file for the app container? And how do i pass the statement --env-file .env.list at runtime so that it is picked up in the linked containers?
My application yaml looks now like this (i intentionally left the ldap config blank):
proxy:
port: 8080
authentication: ldap
admin-groups: admins
ldap:
url: url
manager-dn: manager-dn
manager-password: manager-password
user-search-base: user-search-base
user-search-filter: user-search-filter
group-search-filter: group-search-filter
group-search-base: group-search-base
docker:
internal-networking: true
specs:
- id: 01_ok
display-name: dashboard
description: Dashboard
container-cmd: ["R", "-e", "shiny::runApp('/root/R')"]
container-image: hberten/app123
container-env-file: .env.list
container-network: shineyproxyn-net
access-groups: [GG_APP_ShinyProxy]
logging:
file:
shinyproxy.log
I then run the following command to start the ShinyProxy container:
sudo docker run -d --env-file ~/.env.list -v /var/run/docker.sock:/var/run/docker.sock --net shineyproxyn-net -p 8080:8080 hberten/shinyproxy
A related issue is found here, but this one uses a Docker compose.yml. Is it possible to configure things without a Docker Compose? What am i missing?
Any help kindly appreciated!
Hi @Bertusian,
I think the problem is that you are running shinyproxy itself in a container, so you need to make your .env.list
file available inside that container (by volume mounting it), or alternatively use container-env
with env vars that you pass via file in your docker run command. In addition, I believe that container-env-file
expects an absolute path.
Hi @ mnazarov.
Indeed, i am running shinyproxy in a container. Can you eventually provide an example of the runtime command for lauching the shinyproxy container (with .env.list volume mounted), and is it then captured by the R-app container? I thought that the .env.list was made available by adding --env-file ~/.env.list (that worked when running the container without shinyproxy).
And do i still need to adapt the application.yml? Still not very clear to me. Grateful for any assitance or an example...
I will try to explain more clearly: you have a host system and 2 containers: one outer where shinyproxy is running and one inner with your app.
By running docker run --env-file ...
on your host system, you make environment variables from that file on the host system available to the outer container as env vars. Now you can pass them further to the inner container using container-env
variable.
Alternatively you can mount the host folder with your file into your outer container, and then you can make the env vars from that file available in your inner container by using container-env-file
variable.
An example command for the 2nd alternative may be somehting like:
sudo docker run -d -v /home/envs:/tmp/envs -v /var/run/docker.sock:/var/run/docker.sock --net shineyproxyn-net -p 8080:8080 hberten/shinyproxy
assuming your .env.list file is located in /home/envs/ on your host - you make it available in the outer container under /tmp/envs/env.list with volume mount - now you can use container-env-file: /tmp/envs/.env.list
in your application.yml
An example for the 1st alternative is to use your original command, and then in the application.yaml use container-env
with something like:
container-env:
VAR11: "${VAR1}"
VAR22: "${VAR2}"
where VAR1 and VAR2 are env vars defined in the file on the host and hence available as env vars in outer container, and here you pass them to the inner container as VAR11 and VAR22 (for example, you can of course use the same names too)
OMG. This is great! Now it works. I haven't tried the first suggestion (but will do later), but your second solution did it straight way! I knew i was close, but couldn't find it.
Thank you very much!!
Great stuff you folks are doing with ShinyProxy.
I am glad it worked!
Most helpful comment
I will try to explain more clearly: you have a host system and 2 containers: one outer where shinyproxy is running and one inner with your app.
By running
docker run --env-file ...
on your host system, you make environment variables from that file on the host system available to the outer container as env vars. Now you can pass them further to the inner container usingcontainer-env
variable.Alternatively you can mount the host folder with your file into your outer container, and then you can make the env vars from that file available in your inner container by using
container-env-file
variable.An example command for the 2nd alternative may be somehting like:
assuming your .env.list file is located in /home/envs/ on your host - you make it available in the outer container under /tmp/envs/env.list with volume mount - now you can use
container-env-file: /tmp/envs/.env.list
in your application.ymlAn example for the 1st alternative is to use your original command, and then in the application.yaml use
container-env
with something like:where VAR1 and VAR2 are env vars defined in the file on the host and hence available as env vars in outer container, and here you pass them to the inner container as VAR11 and VAR22 (for example, you can of course use the same names too)