How to use docker for your apps

2020/08/11

If you have build an application that you want to share to world, you most likely need to dockerize it before your server admin will approve it to server side. This guide is quick overview how to get started with docker and put your application in container.

Install docker desktop from their website https://www.docker.com/products/docker-desktop and make sure you have started the desktop application. Magic happens in terminal, so we’ll get there next.

Test that Docker is running correctly

Check that you have docker running and see the version

docker --version
docker-compose --version

Pull images from dockerhub

Docker has it’s own “github” called dockerhub. There users can share their pre-configured images. Let’s make good use of that and start from OS ready image where also R is installed:

docker pull rocker/r-base

We can test the image by running it:

docker run --rm -t -i rocker/r-base

If this shows that you are running R, you have done everything right for now! Quit the application by:

q()

Shiny server in your container

Next let’s step up our game. Pull pre-configured docker image with Shiny server:

docker pull rocker/shiny-verse

Run the container:

docker run --name shiny_container --rm -d -p 3838:3838 rocker/shiny-verse

and go with your web browser to address http://localhost:3838. If a shiny server is running, everything is well.

You can check what containers are running and close a container by commands

docker container ls
docker stop shiny_container

Include a Shiny application in container

To create your own docker container, you need to create a configure file called Dockerfile. This file is a blueprint how the container is configured.

But before we get to the Dockerfile, let’s make a demo shiny application with Old Faithful Geyser Data. Copy next lines as app.R to folder ./shinynapp/

library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Old Faithful Geyser Data"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30)
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("distPlot")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    output$distPlot <- renderPlot({
        # generate bins based on input$bins from ui.R
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

After that, create a blank text file which contain following lines and save file as Dockerfile without any extension to ./

FROM rocker/shiny-verse

COPY /shinyapp/ /srv/shiny-server/

Now we can build the image and run the application in container:

docker build -t my-first-shiny-container .
docker run --name any-name-you-want --rm -d -p 3838:3838 my-first-shiny-container

Go to address http://localhost:3838/ and see your demo application running in container!!

Once you are satisfied of testin your app, remember these command to see running container and to stop them:

docker container ls
docker stop any-name-you-want

Save container as tarball file

I found that it’s easy way to save your file as tarball file and then use it to move file to dockerhub or unzip it to your server. Use command below to save image file:

docker save -o ~/my-first-shiny-container.tar my-first-shiny-container

Extra: template of dockerfile

Here is more modified docker file what I have used in my latest work. It won’t most likely work with your project, but it’s something to start from:

FROM rocker/shiny-verse

## install debian packages
RUN apt-get update -qq && apt-get -y --no-install-recommends install \
    libxml2-dev \
    libcairo2-dev \
    libpq-dev \
    libssh2-1-dev \
    unixodbc-dev \
    libcurl4-openssl-dev \
    libssl-dev

## update system libraries
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get clean

## Install packages needed for running the app
RUN R -e "install.packages(c('rmarkdown', 'tidyverse', 'wordcloud', 'wordcloud2', 'mlogit',  'survival',  'Hmisc', 'RColorBrewer', 'flexdashboard', 'plotly', 'shinydashboard', 'DT', 'survival', 'survminer', 'dplyr'))"

## Copy app to image
COPY /demo-alzheimer/ /srv/shiny-server/demo-alzheimer

## RUN SHINY APP
CMD ["R", "-e", "rmarkdown::run('/srv/shiny-server/demo-alzheimer/shinyapp.Rmd', shiny_args = list(host = '0.0.0.0', port = 3838))"]