← Back to learnwithForhad

Building Production Shiny Dashboards with golem & Docker

From prototype to production — structuring Shiny apps with golem, containerizing with Docker, and deploying to ShinyProxy or Posit Connect.


Why Most Shiny Apps Die in Development

The typical Shiny app starts as app.R — a single file with UI and server mashed together. It works on your laptop. It breaks everywhere else. The problem isn't Shiny — it's the lack of engineering structure.

Enter golem

golem is an opinionated framework that treats your Shiny app as an R package. That means you get:

# Scaffold a new golem app
golem::create_golem("myDashboard")

# Add a module
golem::add_module(name = "sales_overview")

# This creates:
# R/mod_sales_overview.R  (UI + server functions)

Structuring Modules

Each module is a self-contained unit. The mod_sales_overview_ui() function returns the UI, and mod_sales_overview_server() handles the logic. Modules can call other modules — you compose your app like building blocks.

# R/mod_sales_overview.R
mod_sales_overview_ui <- function(id) {
  ns <- NS(id)
  tagList(
    selectInput(ns("region"), "Region", choices = NULL),
    plotOutput(ns("trend_plot"))
  )
}

mod_sales_overview_server <- function(id, shared_data) {
  moduleServer(id, function(input, output, session) {
    output$trend_plot <- renderPlot({
      shared_data() %>%
        filter(region == input$region) %>%
        ggplot(aes(date, sales)) + geom_line()
    })
  })
}

Dockerizing

golem ships with golem::add_dockerfile() that generates a production-ready Dockerfile. The key trick: use renv for reproducible package snapshots.

FROM rocker/r-ver:4.3.2
RUN apt-get update && apt-get install -y libcurl4-openssl-dev libssl-dev
COPY renv.lock /app/renv.lock
WORKDIR /app
RUN Rscript -e "install.packages('renv'); renv::restore()"
COPY . /app
EXPOSE 3838
CMD ["R", "-e", "myDashboard::run_app()"]

Deployment Options

Once containerized, you have options:

Takeaway

Treat your Shiny app like a real software project. Use golem for structure, renv for reproducibility, Docker for portability, and CI/CD for safety. Your future self will thank you.