R Production Deployment Best Practices¶
Objective: Master senior-level R production deployment patterns for enterprise systems. When you need to deploy R applications to production, when you want to ensure reliability and scalability, when you need enterprise-grade deployment strategiesโthese best practices become your weapon of choice.
Core Principles¶
- Reliability: Ensure consistent and reliable deployments
- Scalability: Design for horizontal and vertical scaling
- Security: Implement security best practices
- Monitoring: Monitor application health and performance
- Automation: Automate deployment processes
Shiny Server Deployment¶
Shiny Server Configuration¶
# R/01-shiny-server.R
#' Create Shiny Server configuration
#'
#' @param server_config Server configuration
#' @return Shiny Server configuration
create_shiny_server_config <- function(server_config) {
config <- list(
server = create_server_config(server_config),
applications = create_applications_config(server_config),
security = create_security_config(server_config)
)
return(config)
}
#' Create server configuration
#'
#' @param server_config Server configuration
#' @return Server configuration
create_server_config <- function(server_config) {
server_config <- c(
"# Shiny Server Configuration",
"server {",
" listen 3838;",
" ",
" # Define the user we should use to spawn R processes",
" run_as shiny;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
"}"
)
return(server_config)
}
#' Create applications configuration
#'
#' @param server_config Server configuration
#' @return Applications configuration
create_applications_config <- function(server_config) {
applications_config <- c(
"# Applications Configuration",
"server {",
" listen 3838;",
" ",
" # Define the user we should use to spawn R processes",
" run_as shiny;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
"}"
)
return(applications_config)
}
#' Create security configuration
#'
#' @param server_config Server configuration
#' @return Security configuration
create_security_config <- function(server_config) {
security_config <- c(
"# Security Configuration",
"server {",
" listen 3838;",
" ",
" # Define the user we should use to spawn R processes",
" run_as shiny;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
"}"
)
return(security_config)
}
Shiny Server Pro Configuration¶
# R/01-shiny-server.R (continued)
#' Create Shiny Server Pro configuration
#'
#' @param server_config Server configuration
#' @return Shiny Server Pro configuration
create_shiny_server_pro_config <- function(server_config) {
config <- list(
server = create_pro_server_config(server_config),
applications = create_pro_applications_config(server_config),
security = create_pro_security_config(server_config),
monitoring = create_pro_monitoring_config(server_config)
)
return(config)
}
#' Create Pro server configuration
#'
#' @param server_config Server configuration
#' @return Pro server configuration
create_pro_server_config <- function(server_config) {
pro_server_config <- c(
"# Shiny Server Pro Configuration",
"server {",
" listen 3838;",
" ",
" # Define the user we should use to spawn R processes",
" run_as shiny;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
"}"
)
return(pro_server_config)
}
#' Create Pro applications configuration
#'
#' @param server_config Server configuration
#' @return Pro applications configuration
create_pro_applications_config <- function(server_config) {
pro_applications_config <- c(
"# Pro Applications Configuration",
"server {",
" listen 3838;",
" ",
" # Define the user we should use to spawn R processes",
" run_as shiny;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
"}"
)
return(pro_applications_config)
}
#' Create Pro security configuration
#'
#' @param server_config Server configuration
#' @return Pro security configuration
create_pro_security_config <- function(server_config) {
pro_security_config <- c(
"# Pro Security Configuration",
"server {",
" listen 3838;",
" ",
" # Define the user we should use to spawn R processes",
" run_as shiny;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
"}"
)
return(pro_security_config)
}
#' Create Pro monitoring configuration
#'
#' @param server_config Server configuration
#' @return Pro monitoring configuration
create_pro_monitoring_config <- function(server_config) {
pro_monitoring_config <- c(
"# Pro Monitoring Configuration",
"server {",
" listen 3838;",
" ",
" # Define the user we should use to spawn R processes",
" run_as shiny;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/shiny-server;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/shiny-server;",
" }",
"}"
)
return(pro_monitoring_config)
}
RStudio Connect Deployment¶
RStudio Connect Configuration¶
# R/02-rstudio-connect.R
#' Create RStudio Connect configuration
#'
#' @param connect_config Connect configuration
#' @return RStudio Connect configuration
create_rstudio_connect_config <- function(connect_config) {
config <- list(
server = create_connect_server_config(connect_config),
applications = create_connect_applications_config(connect_config),
security = create_connect_security_config(connect_config),
monitoring = create_connect_monitoring_config(connect_config)
)
return(config)
}
#' Create Connect server configuration
#'
#' @param connect_config Connect configuration
#' @return Connect server configuration
create_connect_server_config <- function(connect_config) {
connect_server_config <- c(
"# RStudio Connect Configuration",
"server {",
" listen 3939;",
" ",
" # Define the user we should use to spawn R processes",
" run_as rstudio-connect;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" }",
"}"
)
return(connect_server_config)
}
#' Create Connect applications configuration
#'
#' @param connect_config Connect configuration
#' @return Connect applications configuration
create_connect_applications_config <- function(connect_config) {
connect_applications_config <- c(
"# Connect Applications Configuration",
"server {",
" listen 3939;",
" ",
" # Define the user we should use to spawn R processes",
" run_as rstudio-connect;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" }",
"}"
)
return(connect_applications_config)
}
#' Create Connect security configuration
#'
#' @param connect_config Connect configuration
#' @return Connect security configuration
create_connect_security_config <- function(connect_config) {
connect_security_config <- c(
"# Connect Security Configuration",
"server {",
" listen 3939;",
" ",
" # Define the user we should use to spawn R processes",
" run_as rstudio-connect;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" }",
"}"
)
return(connect_security_config)
}
#' Create Connect monitoring configuration
#'
#' @param connect_config Connect configuration
#' @return Connect monitoring configuration
create_connect_monitoring_config <- function(connect_config) {
connect_monitoring_config <- c(
"# Connect Monitoring Configuration",
"server {",
" listen 3939;",
" ",
" # Define the user we should use to spawn R processes",
" run_as rstudio-connect;",
" ",
" # Define a location that can be used to run R scripts",
" location / {",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" ",
" # When a user visits the base URL, make sure they see the index page",
" directory_index on;",
" }",
" ",
" # Define a location for the admin interface",
" location /admin {",
" # Only allow access from localhost",
" allow 127.0.0.1;",
" deny all;",
" ",
" # Host the directory of Shiny Apps stored in this directory",
" site_dir /srv/rstudio-connect;",
" ",
" # Log all Shiny output to files in this directory",
" log_dir /var/log/rstudio-connect;",
" }",
"}"
)
return(connect_monitoring_config)
}
Cloud Deployment¶
AWS Deployment¶
# R/03-cloud-deployment.R
#' Create AWS deployment configuration
#'
#' @param aws_config AWS configuration
#' @return AWS deployment configuration
create_aws_deployment_config <- function(aws_config) {
config <- list(
ec2 = create_ec2_config(aws_config),
rds = create_rds_config(aws_config),
s3 = create_s3_config(aws_config),
cloudfront = create_cloudfront_config(aws_config)
)
return(config)
}
#' Create EC2 configuration
#'
#' @param aws_config AWS configuration
#' @return EC2 configuration
create_ec2_config <- function(aws_config) {
ec2_config <- c(
"# EC2 Configuration",
"resource \"aws_instance\" \"r_server\" {",
" ami = \"ami-0c02fb55956c7d316\"",
" instance_type = \"t3.medium\"",
" ",
" vpc_security_group_ids = [aws_security_group.r_server.id]",
" ",
" user_data = <<-EOF",
" #!/bin/bash",
" yum update -y",
" yum install -y R",
" yum install -y shiny-server",
" systemctl start shiny-server",
" systemctl enable shiny-server",
" EOF",
" ",
" tags = {",
" Name = \"R Server\"",
" }",
"}"
)
return(ec2_config)
}
#' Create RDS configuration
#'
#' @param aws_config AWS configuration
#' @return RDS configuration
create_rds_config <- function(aws_config) {
rds_config <- c(
"# RDS Configuration",
"resource \"aws_db_instance\" \"r_database\" {",
" identifier = \"r-database\"",
" ",
" engine = \"postgres\"",
" engine_version = \"13.7\"",
" instance_class = \"db.t3.micro\"",
" ",
" allocated_storage = 20",
" max_allocated_storage = 100",
" storage_type = \"gp2\"",
" ",
" db_name = \"rdatabase\"",
" username = \"ruser\"",
" password = \"rpassword\"",
" ",
" vpc_security_group_ids = [aws_security_group.r_database.id]",
" ",
" backup_retention_period = 7",
" backup_window = \"03:00-04:00\"",
" maintenance_window = \"sun:04:00-sun:05:00\"",
" ",
" skip_final_snapshot = true",
" ",
" tags = {",
" Name = \"R Database\"",
" }",
"}"
)
return(rds_config)
}
#' Create S3 configuration
#'
#' @param aws_config AWS configuration
#' @return S3 configuration
create_s3_config <- function(aws_config) {
s3_config <- c(
"# S3 Configuration",
"resource \"aws_s3_bucket\" \"r_data\" {",
" bucket = \"r-data-bucket\"",
" ",
" tags = {",
" Name = \"R Data Bucket\"",
" }",
"}",
"",
"resource \"aws_s3_bucket_versioning\" \"r_data_versioning\" {",
" bucket = aws_s3_bucket.r_data.id",
" versioning_configuration {",
" status = \"Enabled\"",
" }",
"}",
"",
"resource \"aws_s3_bucket_server_side_encryption_configuration\" \"r_data_encryption\" {",
" bucket = aws_s3_bucket.r_data.id",
" ",
" rule {",
" "apply_server_side_encryption_by_default {",
" sse_algorithm = \"AES256\"",
" }",
" }",
"}"
)
return(s3_config)
}
#' Create CloudFront configuration
#'
#' @param aws_config AWS configuration
#' @return CloudFront configuration
create_cloudfront_config <- function(aws_config) {
cloudfront_config <- c(
"# CloudFront Configuration",
"resource \"aws_cloudfront_distribution\" \"r_distribution\" {",
" origin {",
" domain_name = aws_instance.r_server.public_dns",
" origin_id = \"r-server\"",
" ",
" custom_origin_config {",
" http_port = 80",
" https_port = 443",
" origin_protocol_policy = \"http-only\"",
" origin_ssl_protocols = [\"TLSv1.2\"]",
" }",
" }",
" ",
" enabled = true",
" is_ipv6_enabled = true",
" default_root_object = \"index.html\"",
" ",
" default_cache_behavior {",
" allowed_methods = [\"DELETE\", \"GET\", \"HEAD\", \"OPTIONS\", \"PATCH\", \"POST\", \"PUT\"]",
" cached_methods = [\"GET\", \"HEAD\"]",
" target_origin_id = \"r-server\"",
" ",
" forwarded_values {",
" query_string = false",
" ",
" cookies {",
" forward = \"none\"",
" }",
" }",
" ",
" viewer_protocol_policy = \"redirect-to-https\"",
" min_ttl = 0",
" default_ttl = 3600",
" max_ttl = 86400",
" }",
" ",
" price_class = \"PriceClass_All\"",
" ",
" restrictions {",
" geo_restriction {",
" restriction_type = \"none\"",
" }",
" }",
" ",
" viewer_certificate {",
" cloudfront_default_certificate = true",
" }",
"}"
)
return(cloudfront_config)
}
Azure Deployment¶
# R/03-cloud-deployment.R (continued)
#' Create Azure deployment configuration
#'
#' @param azure_config Azure configuration
#' @return Azure deployment configuration
create_azure_deployment_config <- function(azure_config) {
config <- list(
vm = create_azure_vm_config(azure_config),
database = create_azure_database_config(azure_config),
storage = create_azure_storage_config(azure_config),
cdn = create_azure_cdn_config(azure_config)
)
return(config)
}
#' Create Azure VM configuration
#'
#' @param azure_config Azure configuration
#' @return Azure VM configuration
create_azure_vm_config <- function(azure_config) {
azure_vm_config <- c(
"# Azure VM Configuration",
"resource \"azurerm_virtual_machine\" \"r_server\" {",
" name = \"r-server\"",
" location = azurerm_resource_group.r_group.location",
" resource_group_name = azurerm_resource_group.r_group.name",
" network_interface_ids = [azurerm_network_interface.r_nic.id]",
" vm_size = \"Standard_B2s\"",
" ",
" storage_image_reference {",
" publisher = \"Canonical\"",
" offer = \"UbuntuServer\"",
" sku = \"18.04-LTS\"",
" version = \"latest\"",
" }",
" ",
" storage_os_disk {",
" name = \"r-server-os\"",
" caching = \"ReadWrite\"",
" create_option = \"FromImage\"",
" managed_disk_type = \"Standard_LRS\"",
" }",
" ",
" os_profile {",
" computer_name = \"r-server\"",
" admin_username = \"azureuser\"",
" admin_password = \"AzurePassword123!\"",
" }",
" ",
" os_profile_linux_config {",
" disable_password_authentication = false",
" }",
" ",
" tags = {",
" environment = \"production\"",
" }",
"}"
)
return(azure_vm_config)
}
#' Create Azure database configuration
#'
#' @param azure_config Azure configuration
#' @return Azure database configuration
create_azure_database_config <- function(azure_config) {
azure_database_config <- c(
"# Azure Database Configuration",
"resource \"azurerm_postgresql_server\" \"r_database\" {",
" name = \"r-database-server\"",
" location = azurerm_resource_group.r_group.location",
" resource_group_name = azurerm_resource_group.r_group.name",
" ",
" administrator_login = \"ruser\"",
" administrator_login_password = \"rpassword\"",
" ",
" sku_name = \"B_Gen5_2\"",
" version = \"11\"",
" storage_mb = 51200",
" ",
" backup_retention_days = 7",
" geo_redundant_backup_enabled = false",
" ",
" ssl_enforcement_enabled = true",
" ",
" tags = {",
" environment = \"production\"",
" }",
"}",
"",
"resource \"azurerm_postgresql_database\" \"r_database\" {",
" name = \"rdatabase\"",
" resource_group_name = azurerm_resource_group.r_group.name",
" server_name = azurerm_postgresql_server.r_database.name",
" charset = \"UTF8\"",
" collation = \"English_United States.utf8\"",
"}"
)
return(azure_database_config)
}
#' Create Azure storage configuration
#'
#' @param azure_config Azure configuration
#' @return Azure storage configuration
create_azure_storage_config <- function(azure_config) {
azure_storage_config <- c(
"# Azure Storage Configuration",
"resource \"azurerm_storage_account\" \"r_storage\" {",
" name = \"rstorageaccount\"",
" resource_group_name = azurerm_resource_group.r_group.name",
" location = azurerm_resource_group.r_group.location",
" account_tier = \"Standard\"",
" account_replication_type = \"LRS\"",
" ",
" tags = {",
" environment = \"production\"",
" }",
"}",
"",
"resource \"azurerm_storage_container\" \"r_data\" {",
" name = \"r-data\"",
" storage_account_name = azurerm_storage_account.r_storage.name",
" container_access_type = \"private\"",
"}"
)
return(azure_storage_config)
}
#' Create Azure CDN configuration
#'
#' @param azure_config Azure configuration
#' @return Azure CDN configuration
create_azure_cdn_config <- function(azure_config) {
azure_cdn_config <- c(
"# Azure CDN Configuration",
"resource \"azurerm_cdn_profile\" \"r_cdn\" {",
" name = \"r-cdn-profile\"",
" location = azurerm_resource_group.r_group.location",
" resource_group_name = azurerm_resource_group.r_group.name",
" sku = \"Standard_Microsoft\"",
" ",
" tags = {",
" environment = \"production\"",
" }",
"}",
"",
"resource \"azurerm_cdn_endpoint\" \"r_cdn_endpoint\" {",
" name = \"r-cdn-endpoint\"",
" profile_name = azurerm_cdn_profile.r_cdn.name",
" location = azurerm_resource_group.r_group.location",
" resource_group_name = azurerm_resource_group.r_group.name",
" ",
" origin {",
" name = \"r-server\"",
" host_name = azurerm_public_ip.r_public_ip.fqdn",
" }",
" ",
" tags = {",
" environment = \"production\"",
" }",
"}"
)
return(azure_cdn_config)
}
Docker Deployment¶
Docker Compose Configuration¶
# R/04-docker-deployment.R
#' Create Docker deployment configuration
#'
#' @param docker_config Docker configuration
#' @return Docker deployment configuration
create_docker_deployment_config <- function(docker_config) {
config <- list(
compose = create_docker_compose_config(docker_config),
dockerfile = create_dockerfile_config(docker_config),
nginx = create_nginx_config(docker_config)
)
return(config)
}
#' Create Docker Compose configuration
#'
#' @param docker_config Docker configuration
#' @return Docker Compose configuration
create_docker_compose_config <- function(docker_config) {
docker_compose_config <- c(
"# Docker Compose Configuration",
"version: '3.8'",
"",
"services:",
" r-app:",
" build: .",
" ports:",
" - \"3838:3838\"",
" environment:",
" - R_ENV=production",
" volumes:",
" - ./app:/srv/shiny-server",
" - ./logs:/var/log/shiny-server",
" depends_on:",
" - r-database",
" restart: unless-stopped",
"",
" r-database:",
" image: postgres:13",
" environment:",
" - POSTGRES_DB=rdatabase",
" - POSTGRES_USER=ruser",
" - POSTGRES_PASSWORD=rpassword",
" volumes:",
" - postgres_data:/var/lib/postgresql/data",
" ports:",
" - \"5432:5432\"",
" restart: unless-stopped",
"",
" nginx:",
" image: nginx:alpine",
" ports:",
" - \"80:80\"",
" - \"443:443\"",
" volumes:",
" - ./nginx.conf:/etc/nginx/nginx.conf",
" - ./ssl:/etc/nginx/ssl",
" depends_on:",
" - r-app",
" restart: unless-stopped",
"",
"volumes:",
" postgres_data:"
)
return(docker_compose_config)
}
#' Create Dockerfile configuration
#'
#' @param docker_config Docker configuration
#' @return Dockerfile configuration
create_dockerfile_config <- function(docker_config) {
dockerfile_config <- c(
"# Dockerfile Configuration",
"FROM rocker/shiny:4.3.0",
"",
"# Install system dependencies",
"RUN apt-get update && apt-get install -y \\",
" libcurl4-openssl-dev \\",
" libssl-dev \\",
" libxml2-dev \\",
" libpq-dev \\",
" && rm -rf /var/lib/apt/lists/*",
"",
"# Install R packages",
"RUN R -e \"install.packages(c('shiny', 'DT', 'plotly', 'leaflet', 'dplyr', 'ggplot2', 'RPostgreSQL'))\"",
"",
"# Copy application files",
"COPY app/ /srv/shiny-server/",
"",
"# Set working directory",
"WORKDIR /srv/shiny-server",
"",
"# Expose port",
"EXPOSE 3838",
"",
"# Start Shiny Server",
"CMD [\"shiny-server\"]"
)
return(dockerfile_config)
}
#' Create Nginx configuration
#'
#' @param docker_config Docker configuration
#' @return Nginx configuration
create_nginx_config <- function(docker_config) {
nginx_config <- c(
"# Nginx Configuration",
"events {",
" worker_connections 1024;",
"}",
"",
"http {",
" upstream r_app {",
" server r-app:3838;",
" }",
"",
" server {",
" listen 80;",
" server_name localhost;",
"",
" location / {",
" proxy_pass http://r_app;",
" proxy_set_header Host $host;",
" proxy_set_header X-Real-IP $remote_addr;",
" proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;",
" proxy_set_header X-Forwarded-Proto $scheme;",
" }",
" }",
"}"
)
return(nginx_config)
}
Monitoring and Health Checks¶
Application Monitoring¶
# R/05-monitoring-health.R
#' Create application monitoring
#'
#' @param monitoring_config Monitoring configuration
#' @return Application monitoring
create_application_monitoring <- function(monitoring_config) {
monitoring <- list(
health_checks = create_health_checks(monitoring_config),
metrics = create_application_metrics(monitoring_config),
alerts = create_application_alerts(monitoring_config)
)
return(monitoring)
}
#' Create health checks
#'
#' @param monitoring_config Monitoring configuration
#' @return Health checks
create_health_checks <- function(monitoring_config) {
health_checks <- c(
"# Health Checks",
"health_check:",
" stage: health",
" image: rocker/r-ver:4.3.0",
" script:",
" - echo 'Running health checks...'",
" - Rscript -e 'source(\"health_check.R\")'",
" artifacts:",
" reports:",
" junit: health-results.xml",
" paths:",
" - health-results/"
)
return(health_checks)
}
#' Create application metrics
#'
#' @param monitoring_config Monitoring configuration
#' @return Application metrics
create_application_metrics <- function(monitoring_config) {
application_metrics <- c(
"# Application Metrics",
"application_metrics:",
" stage: metrics",
" image: rocker/r-ver:4.3.0",
" script:",
" - echo 'Collecting application metrics...'",
" - Rscript -e 'source(\"metrics.R\")'",
" artifacts:",
" reports:",
" junit: metrics.xml",
" paths:",
" - metrics/"
)
return(application_metrics)
}
#' Create application alerts
#'
#' @param monitoring_config Monitoring configuration
#' @return Application alerts
create_application_alerts <- function(monitoring_config) {
application_alerts <- c(
"# Application Alerts",
"application_alerts:",
" stage: alerts",
" image: rocker/r-ver:4.3.0",
" script:",
" - echo 'Setting up application alerts...'",
" - Rscript -e 'source(\"alerts.R\")'",
" rules:",
" - if: '$CI_PIPELINE_STATUS == \"failed\"'",
" - if: '$CI_PIPELINE_STATUS == \"success\"'"
)
return(application_alerts)
}
TL;DR Runbook¶
Quick Start¶
# 1. Create Shiny Server configuration
shiny_config <- create_shiny_server_config(server_config)
# 2. Create RStudio Connect configuration
connect_config <- create_rstudio_connect_config(connect_config)
# 3. Create cloud deployment configuration
aws_config <- create_aws_deployment_config(aws_config)
azure_config <- create_azure_deployment_config(azure_config)
# 4. Create Docker deployment configuration
docker_config <- create_docker_deployment_config(docker_config)
# 5. Create monitoring configuration
monitoring_config <- create_application_monitoring(monitoring_config)
Essential Patterns¶
# Complete production deployment
create_production_deployment <- function(deployment_config) {
# Create server configuration
server_config <- create_shiny_server_config(deployment_config$server_config)
# Create cloud deployment
cloud_config <- create_aws_deployment_config(deployment_config$cloud_config)
# Create Docker deployment
docker_config <- create_docker_deployment_config(deployment_config$docker_config)
# Create monitoring
monitoring_config <- create_application_monitoring(deployment_config$monitoring_config)
return(list(
server = server_config,
cloud = cloud_config,
docker = docker_config,
monitoring = monitoring_config
))
}
This guide provides the complete machinery for implementing production deployment for R applications. Each pattern includes implementation examples, deployment strategies, and real-world usage patterns for enterprise deployment.