I'm learning how to use shinyproxy to deploy R shiny applications but I can't figure out where to place my .Renviron file which contains global variables used to access a database.
The docker image builds without any errors but when I start the container using:
docker run -it -p 3838:3838 shinyproxy-template .
It doesn't find the env variables in the .Renviron file and I end up getting an error on the part of the R code that requires the global variables.
My current folder structure is as follows:
shinyproxy-template/
|- app-folder/
|- .gitignore
|- Dockerfile
|- README.md
|- app.Rproj
|- Rprofile.site
|- .Renviron
I tried placing the .Renviron file inside the app-folder/ then built the docker image again but the global variables were still inaccessible.
Where should I place the .Renviron so that the global variables are accessed by the app?
There are multiple options:
Put .Renviron file to the expected location inside the container
You can add a COPY command to the Dockefile to copy your .Renviron file to the expected location - i.e. either a home directory of the user or the WORKDIR location if defined in the Dockerfile. In case of the root user it would be:
COPY .Renviron /root/
Add environment variables from .Renviron to the Dockerfile
Add lines like:
ENV VAR1="value1"
ENV VAR2="value2"
to your Dockerfile
Add environment variables from .Renviron to the shinyproxy configuration
You can define environment variables in the application.yaml configuration file by either using
container-env:
VAR1: VALUE1
VAR2: VALUE2
or
container-env-file: /path/to/.Renviron
for your app specification. Note that the path here is on the host and not inside the container.
For docker run
When you do a docker run outside of shinyproxy you can use argument --env-file with something like:
docker run -it -p 3838:3838 shinyproxy-template --env-file /path/to/shinyproxy-template/.Renviron
Releant documentation links:
https://www.shinyproxy.io/documentation/configuration/#apps
https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file
Edit: Have a look at #Max's solution. We posted at nearly the same time but his instructions are clearer.
After lots of trial and error I finally got a solution.
First, starting the container outside shinyproxy to check if the shiny app runs normally? Use docker's --env-file flag to specify the .Renviron filepath. In my case since both the Dockerfile and .Renviron are in the same folder so I'd do:
docker run -it --env-file .Renviron -p 3838:3838 shinyproxy-template .
The app will now recognize env vars defined in the .Renviron file and no errors!
I then changed into the directory where I had shinyproxy-2.6.1.jar file and ran it again using java -jar shinyproxy-2.6.1.jar. There was an error when I tried to start my shinyapp. It couldn't find the env vars.
So I resorted to adding them directly in the application.yml which is in the same location as shinyproxy-2.6.1.jar:
- id: app-folder
display-name: My App
description: My App's title
container-cmd: ["R", "-e", "shiny::runApp('/root/app-folder')"]
container-image: openanalytics/shinyproxy-template
container-env:
ENV1: ENV1-VALUE
ENV2: ENV2-VALUE
ENV3: ENV3-VALUE
access-groups: scientists
Replace the necessary parts of the yml section with the corresponding one's on your side depending on your case. The same applies to the env vars.
In fact let me just provide a prototype of my whole application.yml file, have a look at the last app I added "wca":
proxy:
title: Open Analytics Shiny Proxy
logo-url: https://www.openanalytics.eu/shinyproxy/logo.png
landing-page: /
# hide nav bar:
hide-navbar: true
heartbeat-rate: 10000
heartbeat-timeout: 60000
port: 8080
authentication: ldap
admin-groups: scientists
# Example: 'simple' authentication configuration
users:
- name: jack
password: password
groups: scientists
- name: jeff
password: password
groups: mathematicians
# Example: 'ldap' authentication configuration
ldap:
url: ldap://ldap.forumsys.com:389/dc=example,dc=com
user-dn-pattern: uid={0}
group-search-base:
group-search-filter: (uniqueMember={0})
manager-dn: cn=read-only-admin,dc=example,dc=com
manager-password: password
# Docker configuration
docker:
url: http://localhost:2375
port-range-start: 20000
specs:
- id: 01_hello
display-name: Hello Application
description: Application which demonstrates the basics of a Shiny app
container-cmd: ["R", "-e", "shinyproxy::run_01_hello()"]
container-image: openanalytics/shinyproxy-demo
access-groups: [scientists, mathematicians]
- id: 06_tabsets
container-cmd: ["R", "-e", "shinyproxy::run_06_tabsets()"]
container-image: openanalytics/shinyproxy-demo
access-groups: scientists
- id: euler
display-name: Euler's number
description: Adding another app to shinyproxy
container-cmd: ["R", "-e", "shiny::runApp('/root/euler')"]
container-image: openanalytics/shinyproxy-template
access-groups: scientists
- id: wca
display-name: Wasanii
description: WhatsApp Chat Analysis
container-cmd: ["R", "-e", "shiny::runApp('/root/wca')"]
container-image: wca
container-env:
FIREBASE_API_KEY: myfirebaseapikey
FIREBASE_PROJECT_ID: myfirebaseprojectid
FIREBASE_AUTH_DOMAIN: myfirebaseauthdomain
FIREBASE_STORAGE_BUCKET: myfirebasestoragebucket
FIREBASE_APP_ID: myfirebaseappid
FIREBASE_DATABASE_URL: myfirebasedatabaseurl
access-groups: scientists
logging:
file:
shinyproxy.log
There's obviously a better solution to refer to the .Renviron file directly but since I can't figure it out this will do.
Related
We have a dockerized golem app that runs fine except for not creating any output (log statements) when deployed in a docker container. In fact, we aren't even seeing any default shiny-server logs.
Here is app.R for our "AirSensorDataViewer" golem app:
pkgload::load_all(export_all = FALSE, helpers = FALSE, attach_testthat = FALSE)
options(
golem.app.prod = TRUE,
shiny.port = 3838,
shiny.host = '0.0.0.0'
)
AirSensorDataViewer::run_app()
And here is our Dockerfile (that builds on top of of a base image with all necessary packages):
FROM mazamascience/airsensor-dataviewer-base:1.0.1
# Create the build zone, copy the local directory over to the docker image, build and install R package.
RUN mkdir /build_zone
ADD . /build_zone
WORKDIR /build_zone
RUN R -e 'remotes::install_local(upgrade="never")'
# Remove sample apps
RUN rm -rf /srv/shiny-server/
# copy app to image
COPY . /srv/shiny-server/asdv
# add .conf file to image/container to preserve log file
COPY ./shiny-server.conf /etc/shiny-server/shiny-server.conf
# When run image and create a container, this container will listen on port 3838
EXPOSE 3838
# Avoiding running as root --> run container as user 'shiny' instead
# allow permission
RUN sudo chown -R shiny:shiny /srv/shiny-server
RUN chmod -R 755 /srv/shiny-server/asdv
# execute in the following as user --> imortant to give permission before that step
USER shiny
##run app
CMD ["/usr/bin/shiny-server.sh"]
And, lastly, our shiny-server.conf file:
# Instruct Shiny Server to run applications as the user "shiny"
run_as shiny;
# Define a server that listens on port 3838
server {
listen 3838;
# Define a location at the base URL
location /asdv/test/ {
# Host the directory of Shiny Apps stored in this directory
site_dir /srv/shiny-server/asdv;
# Log all Shiny output to files in this directory
log_dir /var/log/shiny-server;
# When a user visits the base URL rather than a particular application,
# an index of the applications available in this directory will be shown.
directory_index on;
}
}
Has anyone had success getting a dockerized golem app to create/write to files inside the docker container?
I hope the posted question might be helpful for those wanting to do this as it turns out everything works fine.
For the last few hours I was mistakenly typing docker run ... when I wanted to check the container log files. This creates a new container.
Instead, log files are indeed found in /var/log/shiny-server/ when I:
docker exec -ti airsensor-dataviewer-desktop /bin/bash
ls /var/log/shiny-server/
FROM golang:1.8
ADD . /go/src/beginnerapp
RUN go get -u github.com/gorilla/mux
RUN go get github.com/mattn/go-sqlite3
RUN go install beginnerapp/
VOLUME /go/src/beginnerapp/local-db
WORKDIR /go/src/beginnerapp
ENTRYPOINT /go/bin/beginnerapp
EXPOSE 8080
The sqlite db file is in the local-db directory but I don't seem to be using the VOLUME command correctly. Any ideas how I can have db changes to the sqlite db file persisted?
I don't mind if the volume is mounted before or after the build.
I also tried running the following command
user#cardboardlaptop:~/go/src/beginnerapp$ docker run -p 8080:8080 -v ./local-db:/go/src/beginnerapp/local-db beginnerapp
docker: Error response from daemon: create ./local-db: "./local-db" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.
EDIT: Works with using /absolutepath/local-db instead of relative path ./local-db
You are not mounting volumes in a Dockerfile.
VOLUME tells docker that content on those directories can be mounted via docker run --volumes-from
You're right. Docker doesn't allow relative paths on volumes on command line.
Run your docker using absolute path:
docker run -v /host/db/local-db:/go/src/beginnerapp/local-db
Your db will be persisted in the host file /host/db/local-db
If you want to use relative paths, you can make it work with docker-compose with "volumes" tag:
volumes:
- ./local-db:/go/src/beginnerapp/local-db
You can try this configuration:
Put the Dockerfile in a directory, (e.g. /opt/docker/myproject)
create a docker-compose.yml file in the same path like this:
version: "2.0"
services:
myproject:
build: .
volumes:
- "./local-db:/go/src/beginnerapp/local-db"
Execute docker-compose up -d myproject in the same path.
Your db should be stored in /opt/docker/myproject/local-db
Just a comment. The content of local-db (if any) will be replaced by the content of ./local-db path (empty). If the container have any information (initialized database) will be a good idea to copy it with docker cp or include any init logic on an entrypoint or command shell script.
Well, I'm new at Docker and I need to implement a Shiny app in a Docker Container.
I have the image from https://hub.docker.com/r/rocker/shiny/, that includes Shiny Server, but I don't know how to deploy my app in the server.
I want to deploy the app in the server, install the required packages for my app into the Docker, save the changes and export the image/container.
As I said, I'm new at Docker and I don't know how it really works.
Any idea?
I guess you should start by creating a Dockerfile in a specific folder which would look like something like this :
FROM rocker/shiny:latest
RUN echo 'install.packages(c("package1","package2", ...), \
repos="http://cran.us.r-project.org", \
dependencies=TRUE)' > /tmp/packages.R \
&& Rscript /tmp/packages.R
EXPOSE 3838
CMD ["/usr/bin/shiny-server.sh"]
Then go into this folder and build your image, giving it a name by using this command :
docker build -t your-tag .
Finally, once your image is built you can create a container, and if you don't forget to map the volume and the port, you should be able to find it at localhost:3838 with the following command launched from the folder containing the srv folder :
docker run --rm -p 3838:3838 -v $PWD/srv/shinyapps/:/srv/shiny-server/ -v $PWD/srv/shinylog/:/var/log/shiny-server/ your-tag
As said in the Docker documentation at the following address https://hub.docker.com/r/rocker/shiny/, you might want to launch it in detached mode with -d option and map it with your host's port 80 for a real deployment.
The link(https://hub.docker.com/r/rocker/shiny/) covers how to deploy the shiny server.
Simplest way would be:
docker run --rm -p 3838:3838 rocker/shiny
If you want to extend shiny server, you can write your own Dockerfile and start with shiny image as base image.(https://docs.docker.com/engine/reference/builder/)
Dockerfile:
FROM rocker/shiny:latest
I'm a Docker newbie and I'm trying to setup my first project.
To test how to play with it, I just cloned one ready-to-go project and I setup it (Project repo).
As the guide claims if I access a specific url, I reach the homepage. To be more specific a symfony start page.
Moreover with this command
docker run -i -t testdocker_application /bin/bash
I'm able to login to the container.
My problem is if I try to go to the application folder through bash, the folder that I shared with my host is empty.
I tried with another project, but the result is the same.
Where I'm wrong?
Here some infos about my env:
Ubuntu 12.04
Docker version 1.8.3, build f4bf5c7
Config:
application:
build: code
volumes:
- ./symfony:/var/www/symfony
- ./logs/symfony:/var/www/symfony/app/logs
tty: true
Looks like you have a docker-compose.yml file but are running the image with docker. You don't actually need docker-compose to start a single container. If you just want to start the container your command should look like this:
docker run -ti -v $(pwd)/symfony:/var/www/symfony -v $(pwd)/logs/symfony:/var/www/symfony/app/logs testdocker_application /bin/bash
To use your docker-compose.yml start your container with docker-compose up. You would also need to add the following to drop into a shell.
stdin_open: true
command: /bin/bash
I'm using docker-compose to set up a portable development environment for a bunch of symfony2 applications (though nothing I want to do is specific to symfony). I've decided to have the source files on the local machine exposed as a data volume with all the other dependencies in docker. This way developers can edit on the local file-system.
Everything works great, except that after running the app my cache and log files and the files created by composer in the /vendor directory are now owned by root.
I've read about this problem and some possible approaches here:
Changing permissions of added file to a Docker volume
But I can't quite quite tease out what changes I have to make in my docker-compose.yml file so that when my symphony container starts with docker-compose up any files that are created have the permissions of the user on the host machine.
I'm posting the file for reference, worker is where php, etc. live:
source:
image: symfony/worker-dev
volumes:
- $PWD:/var/www/app
mongodb:
image: mongo:2.4
ports:
- "27017:27017"
volumes_from:
- source
worker:
image: symfony/worker-dev
ports:
- "80:80"
- mongodb
volumes_from:
- source
volumes:
- "tmp/:/var/log/nginx"
One of the solutions is to execure the commands inside your container. I've tried multiple workarounds for the same issue I faced in the past. I find executing the command inside the container the most user-friendly.
Example command: docker-compose run CONTAINER_NAME php bin/console cache:clear. You may use make, ant or any modern tool to keep the commands short.
Example with Makefile:
all: | build run test
build: | docker-compose-build
run: | composer-install clear-cache
############## docker compose
docker-compose-build:
docker-compose build
############## composer
composer-install:
docker-compose run app composer install
composer-update:
docker-compose run app composer update
############## cache
clear-cache:
docker-compose run app php bin/console cache:clear
docker-set-permissions:
docker-compose run app chown -R www-data:www-data var/logs
docker-compose run app chown -R www-data:www-data var/cache
############## test
test:
docker-compose run app php bin/phpunit
Alternatively, you may introduce a .env file which contains a environment variables and then user one of the variables to run usermod command in the Docker container.