generated from coatless-devcontainer/r-pkg
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdockitect-templates.R
178 lines (149 loc) · 5.34 KB
/
dockitect-templates.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#' Templates registry for storing custom templates
#'
#' @keywords internal
template_registry <- new.env()
#' Register a custom dockerfile template
#'
#' @param name Template name
#' @param template_fn Function that returns a dockerfile
#' @return Invisible TRUE if successful
#' @export
dk_register_template <- function(name, template_fn) {
if (!is.function(template_fn)) {
cli::cli_abort("template_fn must be a function that returns a dockerfile")
}
template_registry[[name]] <- template_fn
cli::cli_alert_success("Template '{name}' registered successfully")
invisible(TRUE)
}
#' Create a dockerfile from a custom template
#'
#' @param template_name Name of the template
#' @param ... Arguments to pass to the template function
#' @return A dockerfile object
#' @export
dk_template_custom <- function(template_name, ...) {
if (!exists(template_name, envir = template_registry)) {
cli::cli_abort("Template '{template_name}' not found. Use dk_register_template() to register it.")
}
template_fn <- get(template_name, envir = template_registry)
template_fn(...)
}
#' Create a base R dockerfile template
#'
#' @param r_version R version to use (default: current version)
#' @param additional_pkgs Additional R packages to install
#' @return A dockerfile object
#' @export
dk_template_base <- function(r_version = NULL, additional_pkgs = NULL) {
if (is.null(r_version)) {
r_version <- paste(R.version$major, R.version$minor, sep = ".")
}
base_image <- paste0("rocker/r-ver:", r_version)
df <- dockerfile() |>
dfi_from(base_image) |>
dfi_label(
maintainer = Sys.getenv("USER", "unknown"),
description = "Base R image for analysis"
) |>
dfi_workdir("/app")
# Add additional packages if specified
if (!is.null(additional_pkgs) && length(additional_pkgs) > 0) {
# Add system requirements
df <- dk_add_sysreqs(df, additional_pkgs)
# Install R packages
pkg_list <- paste0(shQuote(additional_pkgs), collapse = ", ")
df <- dfi_run(df, paste0("R -e \"install.packages(c(", pkg_list, "), repos='https://cloud.r-project.org/')\""))
}
# Add script and data directories
df <- df |>
dfi_run("mkdir -p /app/scripts /app/data /app/output") |>
dfi_volume("/app/data") |>
dfi_volume("/app/output") |>
dfi_cmd("R --no-save")
df
}
#' Create a Shiny app dockerfile template
#'
#' @param r_version R version to use (default: current version)
#' @param port Port to expose (default: 3838)
#' @param app_dir Local directory with Shiny app (default: ".")
#' @param additional_pkgs Additional R packages to install
#' @return A dockerfile object
#' @export
dk_template_shiny <- function(r_version = NULL, port = 3838, app_dir = ".", additional_pkgs = NULL) {
if (is.null(r_version)) {
r_version <- paste(R.version$major, R.version$minor, sep = ".")
}
# Use rocker/shiny as the base image
base_image <- paste0("rocker/shiny:", r_version)
# Create base dockerfile
df <- dockerfile() |>
dfi_from(base_image) |>
dfi_label(
maintainer = Sys.getenv("USER", "unknown"),
description = "Shiny application"
)
# Required packages for Shiny
required_pkgs <- c("shiny")
# Combine with additional packages
if (!is.null(additional_pkgs)) {
all_pkgs <- c(required_pkgs, additional_pkgs)
} else {
all_pkgs <- required_pkgs
}
# Add system requirements
df <- dk_add_sysreqs(df, all_pkgs)
# Install R packages
pkg_list <- paste0(shQuote(all_pkgs), collapse = ", ")
df <- dfi_run(df, paste0("R -e \"install.packages(c(", pkg_list, "), repos='https://cloud.r-project.org/')\""))
# Copy app files and set up server
df <- df |>
dfi_copy(app_dir, "/srv/shiny-server/app") |>
dfi_workdir("/srv/shiny-server/app") |>
dfi_expose(port) |>
dfi_cmd("shiny-server")
df
}
#' Create a Plumber API dockerfile template
#'
#' @param r_version R version to use (default: current version)
#' @param port Port to expose (default: 8000)
#' @param api_file Path to plumber.R file (default: "plumber.R")
#' @param additional_pkgs Additional R packages to install
#' @return A dockerfile object
#' @export
dk_template_plumber <- function(r_version = NULL, port = 8000, api_file = "plumber.R", additional_pkgs = NULL) {
if (is.null(r_version)) {
r_version <- paste(R.version$major, R.version$minor, sep = ".")
}
# Use rocker/r-ver as the base image
base_image <- paste0("rocker/r-ver:", r_version)
# Create base dockerfile
df <- dockerfile() |>
dfi_from(base_image) |>
dfi_label(
maintainer = Sys.getenv("USER", "unknown"),
description = "Plumber API"
)
# Required packages for Plumber
required_pkgs <- c("plumber")
# Combine with additional packages
if (!is.null(additional_pkgs)) {
all_pkgs <- c(required_pkgs, additional_pkgs)
} else {
all_pkgs <- required_pkgs
}
# Add system requirements
df <- dk_add_sysreqs(df, all_pkgs)
# Install R packages
pkg_list <- paste0(shQuote(all_pkgs), collapse = ", ")
df <- dfi_run(df, paste0("R -e \"install.packages(c(", pkg_list, "), repos='https://cloud.r-project.org/')\""))
# Copy API file and set up server
df <- df |>
dfi_workdir("/app") |>
dfi_copy(api_file, "/app/plumber.R") |>
dfi_expose(port) |>
dfi_cmd(c("R", "-e", paste0("pr <- plumber::plumb('/app/plumber.R'); pr$run(host='0.0.0.0', port=", port, ")")))
df
}