Learn How to Dockerize a ShinyApp in 7 Steps

Jun 18, 2018 · 7 minute read ShinyApp Docker

In my previous post, I suggested deploying ShinyApps with Docker instead of shinyapps.io. Using Docker allows you to…

  • increase the performance of your app
  • scale it,
  • reduce its costs,
  • make it reproducible,
  • run it on wherever you want,
  • minimize DevOps problems.

But how do you put your ShinyApp inside a Docker container?

This tutorial teaches you how you deploy your ShinyApp with Docker. I go through all necessary steps by explaining how I dockerized my own ShinyApp.

The ShinyApp I am going to dockerize is a small ShinyApp from a previous post (How to select the best performing linear model). It allows users to estimate different linear models for some given datasets and illustrates how specific selection criteria behave.

You can download the app via Github.

The ShinyApp is built upon a server.R file, ui.R, and a global.R file. In addition, I added a separate about.html file that is used as an about page inside the ShinyApp, as well as a small dataset data.csv.

Step 1: Install Docker

Obviously, you need to install Docker on your machine. If you have not Docker installed, visit docker.com and install the Community Edition:

Afterwards, start Docker on your machine.

Step 2: Create a directory and copy your ShinyApp

Next, I recommend creating a directory where you store all necessary files (I call it Docker_ShinyApp). In this folder, we will add our source code and further configuration files.

You can either use the Finder or the terminal and type:

cd ~
mkdir Docker_ShinyApp

First, we will add our ShinyApp in this directory. For this reason, we will add another folder (app) containing a copy of the ShinyApp. The file structure will look like the following:

└── app
    ├── server.R
    ├── ui.R
    ├── global.r
    ├── about.html
    └── data.csv

Note: You should be able to run your ShinyApp from this directory. If your ShinyApp is based on a server.R and ui.R file only, then you simply copy these two files in the app folder.

Persistent storage: When your app uses data that changes over time or if you want to save your results, you better use a database as a persistent storage. As my ShinyApp only contains a small dataset that is used for educational purposes, I added it permanently to my app.

Step 3: Create a Dockerfile

Now, you need to add a Dockerfile to your directory. The Dockerfile is the blueprint of any Docker image. It tells Docker what to install and in which order.

To create a Dockerfile, you simply add an empty file and call it Dockerfile. Again, using the terminal, you type:

cd Docker_ShinyApp
touch Dockerfile

Afterwards, you specify how Docker builds your image by adding all necessary commands to it.

As a basis for the Dockerfile, I use a copy from the official Shiny-Docker image. You can find it at Github.

Specify your R and ShinyServer version In contrast to the Dockerfile from the official Shiny Image, I made small adjustments to the code to make it reproducible.

As such, I specified Docker to install R version 3.5. If your app requires another version, simply define it in the second line. You can find a list of versions that are available on Dockerhub.

Specify which packages you use Depending on the packages you use for your ShinyApp, you probably need to adjust the Dockerfile. Have a look at your ui.R and server.R files and find out which libraries you need.

I only use the libraries shinyand shinydashboard. Hence, I ask Docker to install only these two packages. If your app requires different packages, however, add them to the dedicated line in the Dockerfile (I highlighted that section with „TODO“.).

You can either use the Terminal (type: nano Dockerfile) or a simple Text editor to write and edit the Dockerfile.

The final Dockerfile now looks like this: ( Download this Dockerfile )

# Install R version 3.5
FROM r-base:3.5.0

# Install Ubuntu packages
RUN apt-get update && apt-get install -y \
    sudo \
    gdebi-core \
    pandoc \
    pandoc-citeproc \
    libcurl4-gnutls-dev \
    libcairo2-dev/unstable \
    libxt-dev \

# Download and install ShinyServer (latest version)
RUN wget --no-verbose https://s3.amazonaws.com/rstudio-shiny-server-os-build/ubuntu-12.04/x86_64/VERSION -O "version.txt" && \
    VERSION=$(cat version.txt)  && \
    wget --no-verbose "https://s3.amazonaws.com/rstudio-shiny-server-os-build/ubuntu-12.04/x86_64/shiny-server-$VERSION-amd64.deb" -O ss-latest.deb && \
    gdebi -n ss-latest.deb && \
    rm -f version.txt ss-latest.deb

# Install R packages that are required
# TODO: add further package if you need!
RUN R -e "install.packages(c('shiny', 'shinydashboard'), repos='http://cran.rstudio.com/')"

# Copy configuration files into the Docker image
COPY shiny-server.conf  /etc/shiny-server/shiny-server.conf
COPY /app /srv/shiny-server/

# Make the ShinyApp available at port 80

# Copy further configuration files into the Docker image
COPY shiny-server.sh /usr/bin/shiny-server.sh

CMD ["/usr/bin/shiny-server.sh"]

Step 4: Add configuration files for your ShinyApp

Within the Dockerfile, we already specified two configuration files. The first one shiny_server.conf adjust some ShinyServer configurations. For example, it specifies that user inputs come from port 80. If you want to know more about this file, refer to the official ShinyServer Documentation.

The second file shiny-server.sh specifies the location of log-files.

Add both files to the Docker_ShinyApp directory. In the end, this directory should have the following structure:

├── Dockerfile
├── shiny-server.conf
├── shiny-server.sh
└── app
    ├── server.R
    ├── ui.R
    ├── global.r
    ├── about.html
    └── data.csv

Step 5: Build the docker image

Building the Docker Image is straightforward. Make sure you are in the Docker_ShinyApp directory with the Terminal and type in:

docker build -t My_ShinyApp .

You can name the Docker Image whatever you like. For example, I chose the tag My_ShinyApp.

This process might take a couple of minutes as Docker will download the dedicated R and ShinyApp version, as well as all dependencies and packages.

Step 6: Run the docker image with your ShinyApp

When this process is done, you can run your ShinyApp in Docker 🎉

docker run -p 80:80 My_SinyApp

This command specifies, that Docker should start the image called My_ShinyApp and route port 80 from your browser to port 80 of your Docker container.

Now, you can open the app with any browser by visiting http://localhost :

Step 7: Transfer the ShinyApp to a web server and deploy it online

So far, your Docker Image runs on your local machine. In order to deploy it on a web server or another machine, you can either push it to DockerHub or save it as an archive file and share it privately.

As there are many tutorials on how to push and pull Docker Images to and from DockerHub, I will rather describe how to save a copy of your image and transfer it to a web server without making it public via DockerHub.

To save your Docker Image as a tar-archive, you simply type into your terminal:

docker save -o ~/My_ShinyApp.tar My_ShinyApp

Depending on the size of your image, this might take a minute or two. Afterwards, you can share this tar-file with anyone who has Docker installed.

To deploy your Docker Image on a web server, you simply copy this file to your server. You can use the terminal, Cyberduck, or whatever FTP service you prefer. Now, you log into your server and make sure that Docker is installed and running. Afterwards, you just load the tar-file and run it:

docker load -i My_ShinyApp.tar
docker run MyShinyApp

With the IP address of your server, you should be able to access your ShinyApp. Simply type in the IP address of your server in a browser. If you like, you can add a domain name or point a subdomain to your ShinyApp. That way, users can better remember how to access your and if you change to another server, you simply adjust the DNS settings of your domain without losing any users.


  • If you are using Docker on Windows 7 with the Docker Toolbox, you might end up receiving an error message like chown: invalid user: shiny.shiny. A reader pointed me to this issue and found the following solution: Just add a usergroup shiny to the container and the problem is fixed. To do this, add the following code snippet to your Dockerfile:
# Add shiny user
RUN groupadd  shiny \
&& useradd --gid shiny --shell /bin/bash --create-home shiny