This repository is a starter template for R Shiny applications, packaged with Docker and ready to deploy on CapRover.
We suggest building and running the example app as-is first. Then once you've got that far, go back and start adding your own app content (and building any R package as needed in the Dockerfile).
The shiny user inside the container needs to read files you mount from your host machine. To make this work, build the image with your user's UID/GID:
docker build --build-arg SHINY_UID=$(id -u) --build-arg SHINY_GID=$(id -g) -t my-shiny-app .If deploying to a server where the data files are owned by a different user, use that user's UID/GID instead.
If you installed CapRover on a fresh VM, the correct UID and GID to use there are most likely 1000.
docker run -p 3838:3838 -v "$(pwd)/data_mount:/data_mount" my-shiny-appThen open http://localhost:3838
Without Docker (for development): Open app/shiny-app.Rproj in RStudio and click "Run App". The app will read from data_mount/ in the repo root.
-
Push the Docker image to a container registry that's hooked up in your CapRover deployment.
-
Create a new app in CapRover, making sure to check Has Persistent Data.
-
In HTTP Settings, set the Container HTTP Port to
3838. -
In App Configs > Environment Variables, add:
APP_DATA_PATH=/data_mount -
In App Configs > Persistent Directories, add a volume mount:
- Path in App:
/data_mount
- Path in App:
- Map to a host path or named volume containing your data
-
If you need password protection, in HTTP Settings > Edit HTTP Basic Auth assign a username and password. This approach does not allow multiple different usernames.
-
Under the Deployment tab, use "Method 6: Deploy via ImageName"
.
├── app/
│ ├── app.R # Your Shiny application
│ └── shiny-app.Rproj # RStudio project file
├── data_mount/ # Put data files here for LOCAL development
├── Dockerfile
├── shiny-server.conf
└── README.md
Your app reads data from APP_DATA_PATH:
- Local development: Defaults to
../data_mount(relative toapp/) - Docker: Set to
/data_mountvia the.Renvironfile in the image
In your R code:
APP_DATA_PATH <- Sys.getenv("APP_DATA_PATH", unset = "../data_mount")
# Helper to build paths
data_path <- function(...) file.path(APP_DATA_PATH, ...)
# Use it
my_data <- read.csv(data_path("my_data.csv"))Install packages in the Dockerfile, not at runtime. Edit the Dockerfile:
RUN R -e "install.packages(c('dplyr', 'ggplot2', 'plotly'), repos='https://cloud.r-project.org')"This keeps container startup fast and ensures reproducible builds.
- Edit
app/app.Rto build your application - Add data files to
data_mount/for local testing - Update the Dockerfile to install any packages you need
- Rename
shiny-app.Rprojif you like
If you encounter this error message on startup:
[INFO] shiny-server - Error getting worker: Error: The application exited during initialization.
That is an indicator that you might be missing an R package, or that something in the R code is not working as expected. Turn on logging by uncommenting preserve_logs true; in shiny-server.conf and check the logs on the container in /var/log/shiny-server/ for more information.
See rstudio/shiny-server#353 for more information.
If your app crashes with errors like:
unable to load shared object '/usr/local/lib/R/site-library/stringi/libs/stringi.so':
libicui18n.so.70: cannot open shared object file: No such file or directory
Or similar errors mentioning .so files (shared objects), this means an R package was compiled against a different version of system libraries than what's available in the container.
Solution: Install those packages from source in the Dockerfile so they compile against the correct system library versions.
How to identify which packages need source compilation:
- Check the error logs in
/var/log/shiny-server/- the error will tell you which package failed to load - Look for the library name in the error (e.g.,
libicui18n.so= ICU libraries, used bystringi) - Compile that package and any packages that depend on it from source
Common examples:
ICU library issues (stringi/janitor):
# Install ICU development libraries
RUN apt-get update && apt-get install -y libicu-dev && rm -rf /var/lib/apt/lists/*
# Compile stringi from source
RUN R -e "install.packages('stringi', repos='https://cloud.r-project.org', type='source')"
# Compile packages that depend on stringi from source too
RUN R -e "install.packages(c('snakecase', 'janitor'), repos='https://cloud.r-project.org', type='source', Ncpus=2)"ImageMagick library issues (magick package):
# Install ImageMagick development libraries
RUN apt-get update && apt-get install -y libmagick++-dev && rm -rf /var/lib/apt/lists/*
# Compile magick from source
RUN R -e "install.packages('magick', repos='https://cloud.r-project.org', type='source')"General pattern:
- Install system library (the
-devpackage) - Compile the R package from source using
type='source' - Install remaining packages as binaries for speed