Here is the project directory:
❯ tree ../write-to-volume-from-shiny
../write-to-volume-from-shiny
├── app.R
├── Dockerfile
└── shiny-server.conf
The Dockerfile:
FROM rocker/shiny:4.3.1
RUN rm /srv/shiny-server/index.html /etc/shiny-server/shiny-server.conf
COPY app.R /srv/shiny-server
COPY shiny-server.conf /etc/shiny-server/
RUN chmod -R 755 /srv/shiny-server/
EXPOSE 80
CMD ["/usr/bin/shiny-server"]
The app file:
library(shiny)
ui <- fluidPage(
actionButton("touch", "Touch file"),
textOutput("out")
)
server <- function(input, output, session) {
observeEvent(input$touch, {
if (fs::dir_exists("/data")) {
fs::file_touch("/data/touch-test")
// Error here because of shiny user
// trying to write to root owned /data
}
})
}
shinyApp(ui, server)
Shiny server conf:
run_as shiny;
server {
listen 80;
location / {
site_dir /srv/shiny-server;
log_dir /var/log/shiny-server;
directory_index on;
}
}
docker volume create --name write-test
docker buildx build . -t write
docker run --mount source=write-test,target=/data -p 80:80 write
Go to 127.0.0.1:80
click on button produces an error which I guess happens because shiny
user is trying to write to root
owned /data
What is the workaround here?
Thanks to this answer (took me hours to find it), I have managed to modify Dockerfile
and make it work:
The line RUN mkdir /data && chown shiny:shiny /data
is the key:
FROM rocker/shiny:4.3.1
RUN rm /srv/shiny-server/index.html /etc/shiny-server/shiny-server.conf
COPY app.R /srv/shiny-server
COPY shiny-server.conf /etc/shiny-server/
RUN chmod -R 755 /srv/shiny-server/
RUN mkdir /data && chown shiny:shiny /data
EXPOSE 80
CMD ["/usr/bin/shiny-server"]