├── .Rbuildignore ├── .devcontainer └── devcontainer.json ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ └── pkgdown.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE.md ├── NAMESPACE ├── R ├── dockerfile-core.R ├── dockerfile-instructions.R ├── dockerfile-io.R ├── dockerfile-modifications.R ├── dockerignore-core.R ├── dockerignore-instructions.R ├── dockerignore-io.R ├── dockerignore-templates.R ├── dockitect-from-environment.R ├── dockitect-package.R ├── dockitect-templates.R └── utils.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── dockitect.Rproj ├── man ├── add_dockerfile_line.Rd ├── c.dockerignore.Rd ├── check_dockerfile.Rd ├── check_dockerignore.Rd ├── determine_linux_distribution.Rd ├── determine_package_manager.Rd ├── dfi_add.Rd ├── dfi_arg.Rd ├── dfi_cmd.Rd ├── dfi_copy.Rd ├── dfi_entrypoint.Rd ├── dfi_env.Rd ├── dfi_expose.Rd ├── dfi_from.Rd ├── dfi_healthcheck.Rd ├── dfi_label.Rd ├── dfi_maintainer.Rd ├── dfi_onbuild.Rd ├── dfi_run.Rd ├── dfi_shell.Rd ├── dfi_stopsignal.Rd ├── dfi_user.Rd ├── dfi_volume.Rd ├── dfi_workdir.Rd ├── dfm_add_line.Rd ├── dfm_group_similar.Rd ├── dfm_move_line.Rd ├── dfm_remove_line.Rd ├── dfm_replace_line.Rd ├── dfm_sort_by_instruction.Rd ├── di_add.Rd ├── di_remove.Rd ├── di_replace.Rd ├── dk_add_sysreqs.Rd ├── dk_from_description.Rd ├── dk_from_renv.Rd ├── dk_from_script.Rd ├── dk_from_session.Rd ├── dk_register_template.Rd ├── dk_template_base.Rd ├── dk_template_custom.Rd ├── dk_template_ignore_common.Rd ├── dk_template_ignore_data.Rd ├── dk_template_ignore_editor.Rd ├── dk_template_ignore_git.Rd ├── dk_template_ignore_node.Rd ├── dk_template_ignore_os.Rd ├── dk_template_ignore_packrat.Rd ├── dk_template_ignore_python.Rd ├── dk_template_ignore_r.Rd ├── dk_template_ignore_raw_data.Rd ├── dk_template_ignore_renv.Rd ├── dk_template_plumber.Rd ├── dk_template_shiny.Rd ├── dockerfile.Rd ├── dockerignore.Rd ├── dockitect-package.Rd ├── figures │ ├── dockitect-animated-logo.svg │ └── dockitect-logo.svg ├── generate_pkg_install_cmd.Rd ├── has_instruction.Rd ├── is_dockerfile.Rd ├── is_dockerignore.Rd ├── map_to_sysreqs_platform.Rd ├── print.dockerfile.Rd ├── print.dockerignore.Rd ├── read_dockerfile.Rd ├── read_dockerignore.Rd ├── template_registry.Rd ├── write_dockerfile.Rd └── write_dockerignore.Rd ├── tests ├── testthat.R └── testthat │ ├── setup.R │ ├── test-dockerfile-core.R │ ├── test-dockerfile-instructions.R │ ├── test-dockerfile-io.R │ ├── test-dockerfile-modifications.R │ ├── test-dockerignore-core.R │ ├── test-dockerignore-instructions.R │ ├── test-dockerignore-io.R │ ├── test-dockerignore-templates.R │ ├── test-dockitect-from-environment.R │ ├── test-dockitect-templates.R │ └── test-utils.R └── vignettes ├── .gitignore ├── getting-started-with-dockitect.Rmd └── making-a-dockitect-dockerfile-into-a-running-container.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^LICENSE\.md$ 2 | ^README\.Rmd$ 3 | ^_pkgdown\.yml$ 4 | ^docs$ 5 | ^pkgdown$ 6 | ^\.github$ 7 | ^dockitect\.Rproj$ 8 | ^\.devcontainer$ 9 | ^\.Rproj\.user$ 10 | ^Dockerfile$ 11 | ^\.dockerignore$ 12 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // Config options: https://github.com/rocker-org/devcontainer-templates/tree/main/src/r-ver 2 | { 3 | "name": "R Package Dev Prebuilt (rocker/r-ver base)", 4 | // Image to pull when not building from scratch. 5 | // See .github/devcontainer/devcontainer.json for build details 6 | // and .github/workflows/pre-build-devcontainer.yml for how the 7 | // image is built using GitHub Actions/CI 8 | "image": "ghcr.io/coatless-devcontainer/r-pkg:latest" 9 | } 10 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | 8 | name: R-CMD-check.yaml 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | R-CMD-check: 14 | runs-on: ubuntu-latest 15 | env: 16 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 17 | R_KEEP_PKG_SOURCE: yes 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - uses: r-lib/actions/setup-r@v2 22 | with: 23 | use-public-rspm: true 24 | 25 | - uses: r-lib/actions/setup-r-dependencies@v2 26 | with: 27 | extra-packages: any::rcmdcheck 28 | needs: check 29 | 30 | - uses: r-lib/actions/check-r-package@v2 31 | with: 32 | upload-snapshots: true 33 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 34 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | release: 8 | types: [published] 9 | workflow_dispatch: 10 | 11 | name: pkgdown.yaml 12 | 13 | permissions: read-all 14 | 15 | jobs: 16 | pkgdown: 17 | runs-on: ubuntu-latest 18 | # Only restrict concurrency for non-PR jobs 19 | concurrency: 20 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 21 | env: 22 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 23 | permissions: 24 | contents: write 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - uses: r-lib/actions/setup-pandoc@v2 29 | 30 | - uses: r-lib/actions/setup-r@v2 31 | with: 32 | use-public-rspm: true 33 | 34 | - uses: r-lib/actions/setup-r-dependencies@v2 35 | with: 36 | extra-packages: any::pkgdown, local::. 37 | needs: website 38 | 39 | - name: Build site 40 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 41 | shell: Rscript {0} 42 | 43 | - name: Deploy to GitHub pages 🚀 44 | if: github.event_name != 'pull_request' 45 | uses: JamesIves/github-pages-deploy-action@v4.5.0 46 | with: 47 | clean: false 48 | branch: gh-pages 49 | folder: docs 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | docs 6 | .DS_Store 7 | inst/doc 8 | .dockerignore 9 | Dockerfile 10 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: dockitect 2 | Title: Create and Validate Dockerfiles Programmatically 3 | Version: 0.0.1 4 | Authors@R: c( 5 | person("James Joseph", "Balamuta", 6 | email = "james.balamuta@gmail.com", 7 | role = c("aut", "cre"), 8 | comment = c(ORCID = "0000-0003-2826-8458") 9 | ) 10 | ) 11 | Description: A toolkit for programmatically creating, modifying, and validating 12 | Dockerfiles in R. Provides a pipe-friendly interface for building Docker 13 | environments from R sessions, packages, and scripts, with support for templates 14 | and automatic system requirement detection. 15 | URL: https://r-pkg.thecoatlessprofessor.com/dockitect/, https://github.com/coatless-rpkg/dockitect 16 | BugReports: https://github.com/coatless-rpkg/dockitect/issues 17 | License: AGPL (>= 3) 18 | Depends: R (>= 4.4) 19 | Imports: 20 | cli, 21 | pak, 22 | jsonlite 23 | Suggests: 24 | knitr, 25 | rmarkdown, 26 | testthat (>= 3.0.0) 27 | Encoding: UTF-8 28 | Roxygen: list(markdown = TRUE) 29 | RoxygenNote: 7.3.2 30 | Config/testthat/edition: 3 31 | VignetteBuilder: knitr 32 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(c,dockerignore) 4 | S3method(print,dockerfile) 5 | S3method(print,dockerignore) 6 | export(check_dockerfile) 7 | export(check_dockerignore) 8 | export(determine_linux_distribution) 9 | export(determine_package_manager) 10 | export(dfi_add) 11 | export(dfi_arg) 12 | export(dfi_cmd) 13 | export(dfi_copy) 14 | export(dfi_entrypoint) 15 | export(dfi_env) 16 | export(dfi_expose) 17 | export(dfi_from) 18 | export(dfi_healthcheck) 19 | export(dfi_label) 20 | export(dfi_maintainer) 21 | export(dfi_onbuild) 22 | export(dfi_run) 23 | export(dfi_shell) 24 | export(dfi_stopsignal) 25 | export(dfi_user) 26 | export(dfi_volume) 27 | export(dfi_workdir) 28 | export(dfm_add_line) 29 | export(dfm_group_similar) 30 | export(dfm_move_line) 31 | export(dfm_remove_line) 32 | export(dfm_replace_line) 33 | export(dfm_sort_by_instruction) 34 | export(di_add) 35 | export(di_remove) 36 | export(di_replace) 37 | export(dk_add_sysreqs) 38 | export(dk_from_description) 39 | export(dk_from_renv) 40 | export(dk_from_script) 41 | export(dk_from_session) 42 | export(dk_register_template) 43 | export(dk_template_base) 44 | export(dk_template_custom) 45 | export(dk_template_ignore_common) 46 | export(dk_template_ignore_data) 47 | export(dk_template_ignore_editor) 48 | export(dk_template_ignore_git) 49 | export(dk_template_ignore_node) 50 | export(dk_template_ignore_os) 51 | export(dk_template_ignore_packrat) 52 | export(dk_template_ignore_python) 53 | export(dk_template_ignore_r) 54 | export(dk_template_ignore_raw_data) 55 | export(dk_template_ignore_renv) 56 | export(dk_template_plumber) 57 | export(dk_template_shiny) 58 | export(dockerfile) 59 | export(dockerignore) 60 | export(generate_pkg_install_cmd) 61 | export(has_instruction) 62 | export(is_dockerfile) 63 | export(is_dockerignore) 64 | export(read_dockerfile) 65 | export(read_dockerignore) 66 | export(write_dockerfile) 67 | export(write_dockerignore) 68 | -------------------------------------------------------------------------------- /R/dockerfile-core.R: -------------------------------------------------------------------------------- 1 | #' Create a new `dockerfile` object 2 | #' 3 | #' Creates an empty `dockerfile` object that can be populated with Docker instructions. 4 | #' 5 | #' @return 6 | #' A `dockerfile` object with the following structure: 7 | #' * `lines`: Character vector containing Dockerfile instructions 8 | #' * `metadata`: List containing metadata about the Dockerfile: 9 | #' * `base_image`: Base image name 10 | #' * `package_manager`: Package manager type (e.g., "apt", "yum") 11 | #' * `r_version`: R version (if using a rocker image) 12 | #' * `distribution`: Linux distribution flavor 13 | #' 14 | #' @examples 15 | #' # Create a new dockerfile 16 | #' df <- dockerfile() 17 | #' 18 | #' # Add instruction for a base image 19 | #' df <- dfi_from(df, "rocker/r-ver:4.4.0") 20 | #' df 21 | #' 22 | #' # Add an instruction to run a command to update system packages 23 | #' df <- dfi_run(df, "apt update") 24 | #' df 25 | #' 26 | #' @seealso 27 | #' [is_dockerfile()] for checking if an object is a dockerfile, 28 | #' [dfi_from()] for adding a base image, & 29 | #' [write_dockerfile()] for writing a dockerfile to disk 30 | #' 31 | #' @family dockerfile core functions 32 | #' @export 33 | dockerfile <- function() { 34 | structure( 35 | list( 36 | lines = character(), 37 | metadata = list( 38 | base_image = NULL, 39 | package_manager = NULL, 40 | r_version = NULL, 41 | os = NULL 42 | ) 43 | ), 44 | class = "dockerfile" 45 | ) 46 | } 47 | 48 | #' Test if an object is a `dockerfile` 49 | #' 50 | #' Checks whether the provided object is a valid `dockerfile` class object. 51 | #' 52 | #' @param x Object to test 53 | #' 54 | #' @return 55 | #' `TRUE` if `x` is a `dockerfile` object, `FALSE` otherwise 56 | #' 57 | #' @examples 58 | #' df <- dockerfile() 59 | #' is_dockerfile(df) 60 | #' is_dockerfile(list()) 61 | #' 62 | #' @seealso 63 | #' [dockerfile()] for creating a `dockerfile` object & 64 | #' [check_dockerfile()] for ensuring an object is a `dockerfile` (with error) 65 | #' 66 | #' @family dockerfile core functions 67 | #' @export 68 | is_dockerfile <- function(x) { 69 | inherits(x, "dockerfile") 70 | } 71 | 72 | 73 | #' Check if a dockerfile has a specific instruction 74 | #' 75 | #' @param dockerfile A dockerfile object 76 | #' @param instruction Instruction to check for (e.g., "FROM", "RUN") 77 | #' @return TRUE if instruction exists, FALSE otherwise 78 | #' @export 79 | has_instruction <- function(dockerfile, instruction) { 80 | check_dockerfile(dockerfile) 81 | instruction <- toupper(instruction) 82 | any(grepl(paste0("^", instruction, " "), dockerfile$lines)) 83 | } 84 | 85 | #' Ensure an object is a `dockerfile` 86 | #' 87 | #' Verifies that the provided object is a valid `dockerfile` class object, 88 | #' throwing an error if not. Useful for validation inside functions that 89 | #' expect `dockerfile` objects. 90 | #' 91 | #' @param dockerfile Object to check 92 | #' 93 | #' @return 94 | #' Invisibly returns `TRUE` if valid, otherwise throws an error 95 | #' 96 | #' @examples 97 | #' df <- dockerfile() 98 | #' check_dockerfile(df) 99 | #' \dontrun{ 100 | #' # This would throw an error 101 | #' check_dockerfile(list()) 102 | #' } 103 | #' 104 | #' @seealso 105 | #' [is_dockerfile()] for checking if an object is a dockerfile & 106 | #' [dockerfile()] for creating a dockerfile object 107 | #' 108 | #' @family dockerfile core functions 109 | #' @export 110 | check_dockerfile <- function(dockerfile) { 111 | if (!is_dockerfile(dockerfile)) { 112 | cli::cli_abort("Expected a dockerfile object, got {class(dockerfile)[1]}") 113 | } 114 | invisible(TRUE) 115 | } 116 | 117 | #' Print method for `dockerfile` objects 118 | #' 119 | #' Displays the contents of a `dockerfile` object in a readable format, 120 | #' showing each instruction on a new line as it would appear in an 121 | #' actual **Dockerfile**. 122 | #' 123 | #' @param x A `dockerfile` object 124 | #' @param ... Additional arguments (not used) 125 | #' 126 | #' @return 127 | #' Invisibly returns the `dockerfile` object 128 | #' 129 | #' @examples 130 | #' # Create a new dockerfile and add a couple of instructions 131 | #' df <- dockerfile() |> 132 | #' dfi_from("rocker/r-ver:latest") |> 133 | #' dfi_run("apt-get update") 134 | #' 135 | #' # Print the dockerfile 136 | #' print(df) 137 | #' 138 | #' @seealso 139 | #' [dockerfile()] for creating a `dockerfile` object 140 | #' 141 | #' @family dockerfile core functions 142 | #' @export 143 | print.dockerfile <- function(x, ...) { 144 | check_dockerfile(x) 145 | if (length(x$lines) == 0) { 146 | cli::cli_text("Empty Dockerfile") 147 | return(invisible(x)) 148 | } 149 | 150 | cat(paste(x$lines, collapse = "\n"), "\n") 151 | invisible(x) 152 | } 153 | 154 | #' Add a line to a `dockerfile` and update metadata 155 | #' 156 | #' Adds a line to a `dockerfile` and updates its metadata based on the instruction. 157 | #' This is an internal function used by the more specific `dfi_*` functions. 158 | #' 159 | #' @param dockerfile A `dockerfile` object 160 | #' @param instruction Docker instruction (e.g., `"FROM"`, `"RUN"`) 161 | #' @param args Arguments for the instruction 162 | #' 163 | #' @return 164 | #' Updated `dockerfile` object with the new line and updated metadata 165 | #' 166 | #' @details 167 | #' This internal function handles: 168 | #' 169 | #' - Adding the instruction with proper formatting 170 | #' - Handling multi-line arguments with appropriate indentation 171 | #' - Updating metadata for special instructions like `FROM` 172 | #' 173 | #' For `FROM` instructions, it extracts and stores: 174 | #' 175 | #' - Base image name 176 | #' - Package manager 177 | #' - Operating system 178 | #' - R version (for `rocker/r-ver:version` images) 179 | #' 180 | #' @seealso 181 | #' [dfi_from()] for adding a FROM instruction & 182 | #' [dfi_run()] for adding a RUN instruction 183 | #' 184 | #' @family dockerfile core functions 185 | #' @keywords internal 186 | add_dockerfile_line <- function(dockerfile, instruction, args) { 187 | check_dockerfile(dockerfile) 188 | instruction <- toupper(instruction) 189 | 190 | # Handle multi-line arguments 191 | if (length(args) > 1) { 192 | # First line with instruction 193 | line1 <- paste0(instruction, " ", args[1]) 194 | # Other lines indented 195 | other_lines <- paste0(" ", args[-1]) 196 | lines <- c(line1, other_lines) 197 | dockerfile$lines <- c(dockerfile$lines, lines) 198 | } else { 199 | dockerfile$lines <- c(dockerfile$lines, paste0(instruction, " ", args)) 200 | } 201 | 202 | # Update metadata if necessary to extract 203 | # base image, package manager, and R version 204 | if (instruction == "FROM") { 205 | # Extract just the image part, not the "AS build" part 206 | base_image <- strsplit(args, " AS ")[[1]][1] 207 | dockerfile$metadata$base_image <- base_image 208 | dockerfile$metadata$package_manager <- determine_package_manager(base_image) 209 | dockerfile$metadata$distribution <- determine_linux_distribution(base_image) 210 | 211 | # Try to extract R version from rocker images 212 | if (grepl("^rocker/r-ver:", base_image)) { 213 | r_ver <- sub("^rocker/r-ver:", "", base_image) 214 | dockerfile$metadata$r_version <- r_ver 215 | } 216 | } 217 | 218 | dockerfile 219 | } 220 | -------------------------------------------------------------------------------- /R/dockerfile-io.R: -------------------------------------------------------------------------------- 1 | #' Read a Dockerfile from a file 2 | #' 3 | #' Parses a **Dockerfile** from disk into a `dockerfile` object that can be 4 | #' manipulated programmatically. 5 | #' 6 | #' @param file Path to **Dockerfile** 7 | #' 8 | #' @return 9 | #' A `dockerfile` object containing the parsed instructions and metadata 10 | #' 11 | #' @examples 12 | #' \dontrun{ 13 | #' # Read an existing Dockerfile 14 | #' df <- read_dockerfile("path/to/Dockerfile") 15 | #' 16 | #' # Modify it 17 | #' df <- dfi_run(df, "apt-get update") 18 | #' df 19 | #' } 20 | #' 21 | #' @details 22 | #' The function handles line continuations and extracts metadata like the 23 | #' base image, package manager, OS, and R version (if applicable). 24 | #' Comments and empty lines are skipped. 25 | #' 26 | #' @seealso 27 | #' [dockerfile()] for creating a new dockerfile object & 28 | #' [write_dockerfile()] for writing a dockerfile to disk 29 | #' 30 | #' @family dockerfile I/O functions 31 | #' @export 32 | read_dockerfile <- function(file) { 33 | if (!file.exists(file)) { 34 | cli::cli_abort("File not found: {file}") 35 | } 36 | 37 | # Read lines from file 38 | lines <- readLines(file) 39 | 40 | # Create a new dockerfile object 41 | df <- dockerfile() 42 | 43 | # Process continuation lines 44 | i <- 1 45 | while (i <= length(lines)) { 46 | line <- lines[i] 47 | 48 | # Skip empty lines and comments 49 | if (grepl("^\\s*$", line) || grepl("^\\s*#", line)) { 50 | i <- i + 1 51 | next 52 | } 53 | 54 | # Check for continuation character at the end 55 | while (grepl("\\\\\\s*$", line) && i < length(lines)) { 56 | # Remove continuation character 57 | line <- sub("\\\\\\s*$", " ", line) 58 | # Add next line 59 | i <- i + 1 60 | line <- paste0(line, lines[i]) 61 | } 62 | 63 | # Add processed line to dockerfile 64 | df$lines <- c(df$lines, line) 65 | 66 | # Update metadata 67 | if (grepl("^FROM ", line, ignore.case = TRUE)) { 68 | base_image <- sub("^FROM\\s+([^\\s]+).*$", "\\1", line, ignore.case = TRUE) 69 | df$metadata$base_image <- base_image 70 | df$metadata$package_manager <- determine_package_manager(base_image) 71 | df$metadata$distribution <- determine_linux_distribution(base_image) 72 | 73 | # Try to extract R version from rocker images 74 | if (grepl("^rocker/r-ver:", base_image)) { 75 | r_ver <- sub("^rocker/r-ver:", "", base_image) 76 | df$metadata$r_version <- r_ver 77 | } 78 | } 79 | 80 | i <- i + 1 81 | } 82 | 83 | df 84 | } 85 | 86 | #' Write a `dockerfile` to a file 87 | #' 88 | #' Writes a `dockerfile` object to disk as a **Dockerfile**. 89 | #' 90 | #' @param dockerfile A `dockerfile` object 91 | #' @param file Output file path (default: "Dockerfile") 92 | #' @param multiline Logical indicating if long RUN commands should be split (default: TRUE) 93 | #' 94 | #' @return 95 | #' Invisibly returns the `dockerfile` object 96 | #' 97 | #' @examples 98 | #' \dontrun{ 99 | #' # Create and write a simple Dockerfile 100 | #' dockerfile() |> 101 | #' dfi_from("rocker/r-ver:4.4.0") |> 102 | #' dfi_run("apt-get update") |> 103 | #' write_dockerfile() 104 | #' 105 | #' # Specify a different file name 106 | #' dockerfile() |> 107 | #' dfi_from("rocker/r-ver:4.4.0") |> 108 | #' write_dockerfile("Dockerfile.dev") 109 | #' } 110 | #' 111 | #' @details 112 | #' When `multiline = TRUE` (the default), long `RUN` commands with `&&` 113 | #' will be formatted with line continuations (`\`) for better readability. 114 | #' This makes the Dockerfile more maintainable without changing its functionality. 115 | #' 116 | #' @seealso 117 | #' [read_dockerfile()] for reading a Dockerfile from disk & 118 | #' [dockerfile()] for creating a new dockerfile object 119 | #' 120 | #' @family dockerfile I/O functions 121 | #' @export 122 | write_dockerfile <- function(dockerfile, file = "Dockerfile", multiline = TRUE) { 123 | check_dockerfile(dockerfile) 124 | 125 | if (multiline) { 126 | # Process lines for better formatting 127 | formatted_lines <- character(0) 128 | 129 | i <- 1 130 | while (i <= length(dockerfile$lines)) { 131 | line <- dockerfile$lines[i] 132 | 133 | # Check if it's a RUN command with && that could be split 134 | if (grepl("^RUN ", line) && nchar(line) > 80 && grepl(" && ", line)) { 135 | # Extract the command part (remove RUN prefix) 136 | command <- sub("^RUN\\s+", "", line) 137 | 138 | # Split by && and trim whitespace 139 | parts <- trimws(strsplit(command, " && ")[[1]]) 140 | 141 | # Filter out empty parts 142 | parts <- parts[parts != ""] 143 | 144 | # Format with correct continuation 145 | if (length(parts) > 1) { 146 | formatted_line <- paste0( 147 | "RUN ", parts[1], " && \\\n", 148 | paste0(" ", parts[-1], collapse = " && \\\n") 149 | ) 150 | } else { 151 | formatted_line <- paste0("RUN ", parts[1]) 152 | } 153 | 154 | formatted_lines <- c(formatted_lines, formatted_line) 155 | } else { 156 | formatted_lines <- c(formatted_lines, line) 157 | } 158 | 159 | i <- i + 1 160 | } 161 | 162 | # Write to file 163 | writeLines(formatted_lines, file) 164 | } else { 165 | # Write directly without formatting 166 | writeLines(dockerfile$lines, file) 167 | } 168 | 169 | cli::cli_alert_success("Dockerfile written to {file}") 170 | invisible(dockerfile) 171 | } -------------------------------------------------------------------------------- /R/dockerignore-core.R: -------------------------------------------------------------------------------- 1 | #' Create a new `dockerignore` object 2 | #' 3 | #' Creates an empty `dockerignore`` object that can be populated with patterns 4 | #' to ignore during Docker builds. 5 | #' 6 | #' @return 7 | #' A `dockerignore` object with a `patterns` character vector 8 | #' 9 | #' @examples 10 | #' # Create a new dockerignore object 11 | #' di <- dockerignore() 12 | #' 13 | #' # Add patterns 14 | #' di <- di_add(di, c(".git/", "*.log")) 15 | #' 16 | #' @seealso 17 | #' [di_add()] for adding patterns, 18 | #' [write_dockerignore()] for writing to a .dockerignore file, & 19 | #' [dk_template_ignore_common()] for adding common patterns 20 | #' 21 | #' @family dockerignore core functions 22 | #' @export 23 | dockerignore <- function() { 24 | structure( 25 | list( 26 | patterns = character() 27 | ), 28 | class = "dockerignore" 29 | ) 30 | } 31 | 32 | #' Combine multiple `dockerignore` objects 33 | #' 34 | #' Merges patterns from multiple `dockerignore` objects into a single one. 35 | #' This is useful for combining different template patterns. 36 | #' 37 | #' @param ... `dockerignore` objects to combine 38 | #' 39 | #' @return 40 | #' A new `dockerignore` object with combined patterns from all inputs 41 | #' 42 | #' @examples 43 | #' # Create dockerignore objects with different patterns 44 | #' di_git <- dk_template_ignore_git() 45 | #' di_r <- dk_template_ignore_r() 46 | #' 47 | #' # Combine them 48 | #' di_combined <- c(di_git, di_r) 49 | #' 50 | #' @seealso 51 | #' [dockerignore()] for creating a new `dockerignore` object & 52 | #' [dk_template_ignore_common()] for adding common patterns 53 | #' 54 | #' @family dockerignore core functions 55 | #' @export 56 | c.dockerignore <- function(...) { 57 | args <- list(...) 58 | 59 | # Ensure all arguments are dockerignore objects 60 | is_di <- vapply(args, is_dockerignore, logical(1)) 61 | if (!all(is_di)) { 62 | non_di <- which(!is_di) 63 | cli::cli_abort("All arguments must be dockerignore objects (argument {non_di} is not)") 64 | } 65 | 66 | # Create a new dockerignore object 67 | result <- dockerignore() 68 | 69 | # Combine patterns from all objects 70 | for (di in args) { 71 | result <- di_add(result, di$patterns) 72 | } 73 | 74 | result 75 | } 76 | 77 | #' Test if an object is a dockerignore 78 | #' 79 | #' Checks whether the provided object is a valid `dockerignore` class object. 80 | #' 81 | #' @param x Object to test 82 | #' 83 | #' @return 84 | #' `TRUE` if `x` is a dockerignore object, `FALSE` otherwise 85 | #' 86 | #' @examples 87 | #' di <- dockerignore() 88 | #' is_dockerignore(di) # TRUE 89 | #' is_dockerignore(list()) # FALSE 90 | #' 91 | #' @seealso 92 | #' [dockerignore()] for creating a dockerignore object & 93 | #' [check_dockerignore()] for ensuring an object is a dockerignore (with error) 94 | #' 95 | #' @family dockerignore core functions 96 | #' @export 97 | is_dockerignore <- function(x) { 98 | inherits(x, "dockerignore") 99 | } 100 | 101 | #' Ensure an object is a `dockerignore` 102 | #' 103 | #' Verifies that the provided object is a valid `dockerignore` class object, 104 | #' throwing an error if not. Useful for validation inside functions that 105 | #' expect `dockerignore` objects. 106 | #' 107 | #' @param dockerignore Object to check 108 | #' 109 | #' @return 110 | #' Invisibly returns `TRUE` if valid, otherwise throws an error 111 | #' 112 | #' @examples 113 | #' di <- dockerignore() 114 | #' check_dockerignore(di) # Valid, returns TRUE invisibly 115 | #' 116 | #' \dontrun{ 117 | #' # This would throw an error 118 | #' check_dockerignore(list()) 119 | #' } 120 | #' 121 | #' @seealso 122 | #' [is_dockerignore()] for checking if an object is a dockerignore & 123 | #' [dockerignore()] for creating a dockerignore object 124 | #' 125 | #' @family dockerignore core functions 126 | #' @export 127 | check_dockerignore <- function(dockerignore) { 128 | if (!is_dockerignore(dockerignore)) { 129 | cli::cli_abort("Expected a dockerignore object, got {class(dockerignore)[1]}") 130 | } 131 | invisible(TRUE) 132 | } 133 | 134 | #' Print method for dockerignore objects 135 | #' 136 | #' Displays the contents of a dockerignore object in a readable format, 137 | #' showing each pattern on a new line as it would appear in an 138 | #' actual .dockerignore file. 139 | #' 140 | #' @param x A `dockerignore` object 141 | #' @param ... Additional arguments (not used) 142 | #' 143 | #' @return 144 | #' Invisibly returns the dockerignore object 145 | #' 146 | #' @examples 147 | #' di <- dockerignore() |> 148 | #' di_add(c(".git/", "*.log", "node_modules/")) 149 | #' print(di) 150 | #' 151 | #' @seealso 152 | #' [dockerignore()] for creating a dockerignore object & 153 | #' [write_dockerignore()] for writing to a .dockerignore file 154 | #' 155 | #' @family dockerignore core functions 156 | #' @export 157 | print.dockerignore <- function(x, ...) { 158 | check_dockerignore(x) 159 | if (length(x$patterns) == 0) { 160 | cli::cli_text("Empty .dockerignore") 161 | return(invisible(x)) 162 | } 163 | 164 | cat(paste(x$patterns, collapse = "\n"), "\n") 165 | invisible(x) 166 | } -------------------------------------------------------------------------------- /R/dockerignore-instructions.R: -------------------------------------------------------------------------------- 1 | #' Add patterns to a dockerignore object 2 | #' 3 | #' Adds one or more patterns to a `dockerignore` object, avoiding duplicates. 4 | #' 5 | #' @param dockerignore A `dockerignore` object 6 | #' @param pattern Character vector of patterns to add 7 | #' 8 | #' @return 9 | #' An updated `dockerignore` object with the new patterns added 10 | #' 11 | #' @examples 12 | #' di <- dockerignore() 13 | #' 14 | #' # Add a single pattern 15 | #' di <- di_add(di, ".git/") 16 | #' 17 | #' # Add multiple patterns 18 | #' di <- di_add(di, c("*.log", "node_modules/", "*.tmp")) 19 | #' 20 | #' @details 21 | #' Patterns follow the same syntax as `.gitignore` files: 22 | #' * Lines starting with `#` are comments 23 | #' * Blank lines are ignored 24 | #' * Trailing slashes `/` specify directories 25 | #' * Patterns with special characters like `*`, `?`, and `[]` use glob syntax 26 | #' * Lines starting with `!` negate a pattern (include a file that would otherwise be ignored) 27 | #' 28 | #' @seealso 29 | #' [di_remove()] for removing patterns & 30 | #' [di_replace()] for replacing patterns 31 | #' 32 | #' @family dockerignore instruction functions 33 | #' @export 34 | di_add <- function(dockerignore, pattern) { 35 | check_dockerignore(dockerignore) 36 | 37 | # Handle vector input 38 | for (p in pattern) { 39 | # Add pattern if not already present 40 | if (!p %in% dockerignore$patterns) { 41 | dockerignore$patterns <- c(dockerignore$patterns, p) 42 | } 43 | } 44 | 45 | dockerignore 46 | } 47 | 48 | #' Remove patterns from a `dockerignore` object 49 | #' 50 | #' Removes one or more patterns from a `dockerignore` object. 51 | #' 52 | #' @param dockerignore A `dockerignore` object 53 | #' @param pattern Character vector of patterns to remove 54 | #' 55 | #' @return 56 | #' An updated `dockerignore` object with the specified patterns removed 57 | #' 58 | #' @examples 59 | #' # Create a dockerignore object and add some patterns 60 | #' di <- dockerignore() |> 61 | #' di_add(c(".git/", "*.log", "node_modules/")) 62 | #' 63 | #' # Remove a pattern 64 | #' di <- di_remove(di, "*.log") 65 | #' 66 | #' @seealso 67 | #' [di_add()] for adding patterns & 68 | #' [di_replace()] for replacing patterns 69 | #' 70 | #' @family dockerignore instruction functions 71 | #' @export 72 | di_remove <- function(dockerignore, pattern) { 73 | check_dockerignore(dockerignore) 74 | 75 | # Remove patterns if present 76 | dockerignore$patterns <- dockerignore$patterns[!dockerignore$patterns %in% pattern] 77 | 78 | dockerignore 79 | } 80 | 81 | #' Replace patterns in a dockerignore object 82 | #' 83 | #' Replaces one or more patterns in a dockerignore object with new patterns. 84 | #' 85 | #' @param dockerignore A `dockerignore` object 86 | #' @param old_pattern Pattern(s) to replace 87 | #' @param new_pattern New pattern(s) 88 | #' 89 | #' @return 90 | #' An updated `dockerignore` object with the specified patterns replaced 91 | #' 92 | #' @examples 93 | #' # Create a dockerignore object and add some patterns 94 | #' di <- dockerignore() |> 95 | #' di_add(c("*.log", "*.tmp", "node_modules/")) 96 | #' 97 | #' # Replace a single pattern 98 | #' di <- di_replace(di, "*.log", "logs/") 99 | #' 100 | #' # Replace multiple patterns with a single pattern 101 | #' di <- di_replace(di, c("*.tmp", "node_modules/"), "temp/") 102 | #' 103 | #' # Replace patterns one-to-one 104 | #' di <- di_replace(di, 105 | #' c("*.log", "*.tmp"), 106 | #' c("logs/*", "temp/*")) 107 | #' 108 | #' @details 109 | #' This function allows you to replace patterns in a dockerignore object. 110 | #' Three modes of operation are supported: 111 | #' 112 | #' 1. Replace a single pattern with a single pattern 113 | #' 2. Replace multiple patterns with a single pattern 114 | #' 3. Replace multiple patterns with corresponding new patterns (one-to-one) 115 | #' 116 | #' For the third mode, `old_pattern` and `new_pattern` must have the same length. 117 | #' 118 | #' @seealso 119 | #' [di_add()] for adding patterns & 120 | #' [di_remove()] for removing patterns 121 | #' 122 | #' @family dockerignore instruction functions 123 | #' @export 124 | di_replace <- function(dockerignore, old_pattern, new_pattern) { 125 | check_dockerignore(dockerignore) 126 | 127 | # Handle different input cases 128 | if (length(old_pattern) == 1 && length(new_pattern) == 1) { 129 | # Simple case: replace single pattern with single pattern 130 | idx <- which(dockerignore$patterns == old_pattern) 131 | if (length(idx) > 0) { 132 | dockerignore$patterns[idx] <- new_pattern 133 | } 134 | } else if (length(old_pattern) > 1 && length(new_pattern) == 1) { 135 | # Replace multiple patterns with a single pattern 136 | for (op in old_pattern) { 137 | idx <- which(dockerignore$patterns == op) 138 | if (length(idx) > 0) { 139 | dockerignore$patterns[idx] <- new_pattern 140 | } 141 | } 142 | } else if (length(old_pattern) == length(new_pattern)) { 143 | # Replace each old pattern with corresponding new pattern 144 | for (i in seq_along(old_pattern)) { 145 | idx <- which(dockerignore$patterns == old_pattern[i]) 146 | if (length(idx) > 0) { 147 | dockerignore$patterns[idx] <- new_pattern[i] 148 | } 149 | } 150 | } else { 151 | cli::cli_abort("old_pattern and new_pattern must have the same length or new_pattern must be length 1") 152 | } 153 | 154 | dockerignore 155 | } 156 | -------------------------------------------------------------------------------- /R/dockerignore-io.R: -------------------------------------------------------------------------------- 1 | #' Read a **.dockerignore** file 2 | #' 3 | #' Reads a **.dockerignore** file from disk into a `dockerignore` object that 4 | #' can be manipulated programmatically. 5 | #' 6 | #' @param file Path to **.dockerignore** file (default: `".dockerignore"`) 7 | #' 8 | #' @return 9 | #' A `dockerignore` object containing the parsed patterns 10 | #' 11 | #' @examples 12 | #' \dontrun{ 13 | #' # Read an existing .dockerignore file 14 | #' di <- read_dockerignore() 15 | #' 16 | #' # Add more patterns 17 | #' di <- di_add(di, "*.tmp") 18 | #' } 19 | #' 20 | #' @details 21 | #' Empty lines and comments (lines starting with `#`) are filtered out. 22 | #' 23 | #' @seealso 24 | #' [dockerignore()] for creating a new dockerignore object & 25 | #' [write_dockerignore()] for writing a dockerignore to disk 26 | #' 27 | #' @family dockerignore I/O functions 28 | #' @export 29 | read_dockerignore <- function(file = ".dockerignore") { 30 | if (!file.exists(file)) { 31 | cli::cli_abort("File not found: {file}") 32 | } 33 | 34 | # Read lines from file 35 | lines <- readLines(file) 36 | 37 | # Filter out empty lines and comments 38 | lines <- lines[!grepl("^\\s*$", lines) & !grepl("^\\s*#", lines)] 39 | 40 | # Create a new dockerignore object 41 | di <- dockerignore() 42 | di$patterns <- lines 43 | 44 | di 45 | } 46 | 47 | #' Write a `dockerignore` object to a file 48 | #' 49 | #' Writes a `dockerignore` object to disk as a formatted **.dockerignore** file. 50 | #' 51 | #' @param dockerignore A `dockerignore` object 52 | #' @param file Output file path (default: `".dockerignore"`) 53 | #' 54 | #' @return 55 | #' Invisibly returns the `dockerignore` object 56 | #' 57 | #' @examples 58 | #' \dontrun{ 59 | #' # Create and write a .dockerignore file 60 | #' dockerignore() |> 61 | #' di_add(c(".git/", "*.log")) |> 62 | #' write_dockerignore() 63 | #' } 64 | #' 65 | #' @seealso 66 | #' [read_dockerignore()] for reading a .dockerignore file from disk & 67 | #' [dockerignore()] for creating a new dockerignore object 68 | #' 69 | #' @family dockerignore I/O functions 70 | #' @export 71 | write_dockerignore <- function(dockerignore, file = ".dockerignore") { 72 | check_dockerignore(dockerignore) 73 | 74 | # Write to file 75 | writeLines(dockerignore$patterns, file) 76 | 77 | cli::cli_alert_success(".dockerignore written to {file}") 78 | invisible(dockerignore) 79 | } 80 | -------------------------------------------------------------------------------- /R/dockitect-package.R: -------------------------------------------------------------------------------- 1 | #' @section Dockerfile Instructions: 2 | #' Functions for adding Dockerfile instructions are prefixed with `dfi_*` and follow the 3 | #' pattern `dfi_instruction(.dockerfile, ...)`. 4 | #' 5 | #' @section Dockerfile Generators: 6 | #' Functions for generating Dockerfiles from various sources are prefixed with `dk_*` and 7 | #' can create Dockerfiles from an R session, renv lockfile, DESCRIPTION file, or R script. 8 | #' 9 | #' @section Dockerfile Modifiers: 10 | #' Functions for modifying Dockerfiles are prefixed with `dfm_*` and allow for adding, 11 | #' removing, replacing, and moving lines within a Dockerfile. 12 | #' 13 | #' @section Dockerignore Management: 14 | #' Functions for managing .dockerignore files are prefixed with `di_*` and allow for 15 | #' adding and removing patterns from a .dockerignore file. 16 | #' @keywords internal 17 | "_PACKAGE" 18 | 19 | ## usethis namespace: start 20 | ## usethis namespace: end 21 | NULL 22 | -------------------------------------------------------------------------------- /R/dockitect-templates.R: -------------------------------------------------------------------------------- 1 | #' Templates registry for storing custom templates 2 | #' 3 | #' @keywords internal 4 | template_registry <- new.env() 5 | 6 | #' Register a custom dockerfile template 7 | #' 8 | #' @param name Template name 9 | #' @param template_fn Function that returns a dockerfile 10 | #' @return Invisible TRUE if successful 11 | #' @export 12 | dk_register_template <- function(name, template_fn) { 13 | if (!is.function(template_fn)) { 14 | cli::cli_abort("template_fn must be a function that returns a dockerfile") 15 | } 16 | 17 | template_registry[[name]] <- template_fn 18 | cli::cli_alert_success("Template '{name}' registered successfully") 19 | invisible(TRUE) 20 | } 21 | 22 | #' Create a dockerfile from a custom template 23 | #' 24 | #' @param template_name Name of the template 25 | #' @param ... Arguments to pass to the template function 26 | #' @return A dockerfile object 27 | #' @export 28 | dk_template_custom <- function(template_name, ...) { 29 | if (!exists(template_name, envir = template_registry)) { 30 | cli::cli_abort("Template '{template_name}' not found. Use dk_register_template() to register it.") 31 | } 32 | 33 | template_fn <- get(template_name, envir = template_registry) 34 | template_fn(...) 35 | } 36 | 37 | #' Create a base R dockerfile template 38 | #' 39 | #' @param r_version R version to use (default: current version) 40 | #' @param additional_pkgs Additional R packages to install 41 | #' @return A dockerfile object 42 | #' @export 43 | dk_template_base <- function(r_version = NULL, additional_pkgs = NULL) { 44 | if (is.null(r_version)) { 45 | r_version <- paste(R.version$major, R.version$minor, sep = ".") 46 | } 47 | 48 | base_image <- paste0("rocker/r-ver:", r_version) 49 | 50 | df <- dockerfile() |> 51 | dfi_from(base_image) |> 52 | dfi_label( 53 | maintainer = Sys.getenv("USER", "unknown"), 54 | description = "Base R image for analysis" 55 | ) |> 56 | dfi_workdir("/app") 57 | 58 | # Add additional packages if specified 59 | if (!is.null(additional_pkgs) && length(additional_pkgs) > 0) { 60 | # Add system requirements 61 | df <- dk_add_sysreqs(df, additional_pkgs) 62 | 63 | # Install R packages 64 | pkg_list <- paste0(shQuote(additional_pkgs), collapse = ", ") 65 | df <- dfi_run(df, paste0("R -e \"install.packages(c(", pkg_list, "), repos='https://cloud.r-project.org/')\"")) 66 | } 67 | 68 | # Add script and data directories 69 | df <- df |> 70 | dfi_run("mkdir -p /app/scripts /app/data /app/output") |> 71 | dfi_volume("/app/data") |> 72 | dfi_volume("/app/output") |> 73 | dfi_cmd("R --no-save") 74 | 75 | df 76 | } 77 | 78 | #' Create a Shiny app dockerfile template 79 | #' 80 | #' @param r_version R version to use (default: current version) 81 | #' @param port Port to expose (default: 3838) 82 | #' @param app_dir Local directory with Shiny app (default: ".") 83 | #' @param additional_pkgs Additional R packages to install 84 | #' @return A dockerfile object 85 | #' @export 86 | dk_template_shiny <- function(r_version = NULL, port = 3838, app_dir = ".", additional_pkgs = NULL) { 87 | if (is.null(r_version)) { 88 | r_version <- paste(R.version$major, R.version$minor, sep = ".") 89 | } 90 | 91 | # Use rocker/shiny as the base image 92 | base_image <- paste0("rocker/shiny:", r_version) 93 | 94 | # Create base dockerfile 95 | df <- dockerfile() |> 96 | dfi_from(base_image) |> 97 | dfi_label( 98 | maintainer = Sys.getenv("USER", "unknown"), 99 | description = "Shiny application" 100 | ) 101 | 102 | # Required packages for Shiny 103 | required_pkgs <- c("shiny") 104 | 105 | # Combine with additional packages 106 | if (!is.null(additional_pkgs)) { 107 | all_pkgs <- c(required_pkgs, additional_pkgs) 108 | } else { 109 | all_pkgs <- required_pkgs 110 | } 111 | 112 | # Add system requirements 113 | df <- dk_add_sysreqs(df, all_pkgs) 114 | 115 | # Install R packages 116 | pkg_list <- paste0(shQuote(all_pkgs), collapse = ", ") 117 | df <- dfi_run(df, paste0("R -e \"install.packages(c(", pkg_list, "), repos='https://cloud.r-project.org/')\"")) 118 | 119 | # Copy app files and set up server 120 | df <- df |> 121 | dfi_copy(app_dir, "/srv/shiny-server/app") |> 122 | dfi_workdir("/srv/shiny-server/app") |> 123 | dfi_expose(port) |> 124 | dfi_cmd("shiny-server") 125 | 126 | df 127 | } 128 | 129 | #' Create a Plumber API dockerfile template 130 | #' 131 | #' @param r_version R version to use (default: current version) 132 | #' @param port Port to expose (default: 8000) 133 | #' @param api_file Path to plumber.R file (default: "plumber.R") 134 | #' @param additional_pkgs Additional R packages to install 135 | #' @return A dockerfile object 136 | #' @export 137 | dk_template_plumber <- function(r_version = NULL, port = 8000, api_file = "plumber.R", additional_pkgs = NULL) { 138 | if (is.null(r_version)) { 139 | r_version <- paste(R.version$major, R.version$minor, sep = ".") 140 | } 141 | 142 | # Use rocker/r-ver as the base image 143 | base_image <- paste0("rocker/r-ver:", r_version) 144 | 145 | # Create base dockerfile 146 | df <- dockerfile() |> 147 | dfi_from(base_image) |> 148 | dfi_label( 149 | maintainer = Sys.getenv("USER", "unknown"), 150 | description = "Plumber API" 151 | ) 152 | 153 | # Required packages for Plumber 154 | required_pkgs <- c("plumber") 155 | 156 | # Combine with additional packages 157 | if (!is.null(additional_pkgs)) { 158 | all_pkgs <- c(required_pkgs, additional_pkgs) 159 | } else { 160 | all_pkgs <- required_pkgs 161 | } 162 | 163 | # Add system requirements 164 | df <- dk_add_sysreqs(df, all_pkgs) 165 | 166 | # Install R packages 167 | pkg_list <- paste0(shQuote(all_pkgs), collapse = ", ") 168 | df <- dfi_run(df, paste0("R -e \"install.packages(c(", pkg_list, "), repos='https://cloud.r-project.org/')\"")) 169 | 170 | # Copy API file and set up server 171 | df <- df |> 172 | dfi_workdir("/app") |> 173 | dfi_copy(api_file, "/app/plumber.R") |> 174 | dfi_expose(port) |> 175 | dfi_cmd(c("R", "-e", paste0("pr <- plumber::plumb('/app/plumber.R'); pr$run(host='0.0.0.0', port=", port, ")"))) 176 | 177 | df 178 | } -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | ``` 15 | 16 | # dockitect 17 | 18 | 19 | [![R-CMD-check](https://github.com/coatless-rpkg/dockitect/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/coatless-rpkg/dockitect/actions/workflows/R-CMD-check.yaml) 20 | 21 | 22 | `dockitect` is an R package for programmatically creating, validating, and 23 | managing Dockerfiles using a pipe-friendly syntax. It bridges the gap between 24 | R development and containerization, enabling seamless Docker integration for 25 | data science workflows. 26 | 27 | > [!IMPORTANT] 28 | > 29 | > This package is currently in the prototype/experimental stage. It is 30 | > not yet available on CRAN and may have bugs or limitations. 31 | 32 | ## Installation 33 | 34 | You can install the development version of `dockitect` from 35 | [GitHub](https://github.com/coatless-rpkg/dockitect) with: 36 | 37 | ```{r} 38 | #| label: setup 39 | #| eval: false 40 | # install.packages("remotes") 41 | remotes::install_github("coatless-rpkg/dockitect") 42 | ``` 43 | 44 | 45 | ## Design Philosophy 46 | 47 | To make the API intuitive and discoverable, `dockitect` employs a naming 48 | convention across all its functions. Understanding these prefixes will 49 | help you navigate the package and find the functions you need: 50 | 51 | - `dockerfile()` - Create a new Dockerfile object 52 | - `dfi_*()` - **D**ockerfile **i**nstruction functions (e.g., `dfi_from()`, `dfi_run()`) 53 | - `dfm_*()` - **D**ockerfile **m**odification functions (e.g., `dfm_add_line()`, `dfm_group_similar()`) 54 | - `dockerignore()` - Create a new Dockerignore object 55 | - `di_*()` - **D**ockerignore functions (e.g., `di_add()`, `di_remove()`) 56 | - `dk_*()` - **D**oc**k**er configuration/template functions (e.g., `dk_from_session()`, `dk_template_shiny()`) 57 | 58 | ## Usage 59 | 60 | The following examples demonstrate how to use `dockitect` for various 61 | containerization scenarios. Each example showcases different aspects of the 62 | package's functionality, from basic Dockerfile creation to more advanced use cases. 63 | 64 | ### Dockerfile Creation 65 | 66 | Let's start with the fundamentals. Creating a Dockerfile typically involves 67 | specifying a base image, installing dependencies, copying files, and defining 68 | commands. With `dockitect`, this process becomes a series of intuitive pipe-chained functions. 69 | 70 | For example, let's create a Dockerfile for an R script: 71 | 72 | ```{r} 73 | #| label: basic-dockerfile 74 | library(dockitect) 75 | 76 | # Create a basic Dockerfile for an R script 77 | df_rscript <- dockerfile() |> 78 | dfi_from("rocker/r-ver:4.4.3") |> 79 | dfi_label(maintainer = "user@example.com") |> 80 | dfi_run("apt-get update && apt-get install -y libcurl4-openssl-dev") |> 81 | dfi_workdir("/app") |> 82 | dfi_copy("analysis.R", "/app/") |> 83 | dfi_cmd("Rscript /app/analysis.R") 84 | 85 | df_rscript 86 | 87 | ## Write the Dockerfile to disk 88 | # write_dockerfile(df_rscript) 89 | ``` 90 | 91 | ### Use Templates 92 | 93 | `dockitect` includes specialized templates for common R application types, 94 | saving you time and ensuring best practices are followed. These templates are 95 | fully customizable and provide a solid foundation for your projects. 96 | 97 | #### Shiny Application 98 | 99 | Creating a Docker container for a Shiny application requires specific 100 | configurations for ports, networking, and dependencies. The Shiny template 101 | handles these details automatically. For example, we can create a Dockerfile 102 | for a Shiny app with proper port configuration: 103 | 104 | ```{r} 105 | #| label: shiny-template-demo 106 | #| eval: false 107 | # Create a Dockerfile for a Shiny app 108 | dk_template_shiny( 109 | r_version = "4.4.3", # Specify R version 110 | port = 3838, # Expose Shiny port 111 | app_dir = "app/" # Location of app files 112 | ) |> 113 | dfi_env(SHINY_HOST = "0.0.0.0") |> # Configure Shiny to listen on all interfaces 114 | write_dockerfile() 115 | ``` 116 | 117 | ### Custom Templates 118 | 119 | While `dockitect` includes templates for common scenarios, your organization 120 | might have specific containerization patterns. The template system is 121 | extensible, allowing you to create, register, and reuse your own templates 122 | throughout your projects: 123 | 124 | ```{r} 125 | #| label: custom-template-demo 126 | #| eval: false 127 | # Create a custom template function 128 | my_template <- function(my_param = "default") { 129 | dockerfile() |> 130 | dfi_from("rocker/r-ver:4.4.3") |> 131 | dfi_run(paste0("echo ", my_param)) 132 | } 133 | 134 | # Register the template 135 | dk_register_template("my_template", my_template) 136 | 137 | # Use the template 138 | dk_template_custom("my_template", my_param = "hello") |> 139 | write_dockerfile() 140 | ``` 141 | 142 | 143 | ### Modify Existing Dockerfiles 144 | 145 | Sometimes you need to modify existing Dockerfiles rather than creating them 146 | from scratch. `dockitect` provides specialized functions for reading, modifying, 147 | and writing Dockerfiles, allowing for precise changes without manual text editing: 148 | 149 | ```{r} 150 | #| label: existing-dockerfile-modifications 151 | #| eval: false 152 | # Read an existing Dockerfile 153 | df <- read_dockerfile("path/to/Dockerfile") 154 | 155 | # Modify it 156 | df |> 157 | dfm_remove_line(5) |> # Remove line 5 158 | dfm_group_similar() |> # Group similar commands (e.g., RUN) 159 | write_dockerfile("Dockerfile.new") # Write to a new file 160 | ``` 161 | 162 | ### Create and Manage .dockerignore 163 | 164 | Docker builds can be slowed down by unnecessarily including large or irrelevant 165 | files in the build context. A properly configured `.dockerignore` file helps 166 | keep your builds fast and your images small. `dockitect` makes it easy to 167 | create and maintain a `.dockerignore` file through `dockerignore()`. 168 | 169 | ```{r} 170 | #| label: create-dockerignore 171 | #| eval: false 172 | # Create a .dockerignore file with common patterns 173 | dockerignore() |> 174 | dk_template_ignore_common(git = TRUE, r = TRUE) |> # Add common patterns for Git and R 175 | di_add("*.log") |> # Add custom patterns 176 | di_add("output/") |> 177 | write_dockerignore() 178 | ``` 179 | 180 | ## Related Packages 181 | 182 | `dockitect` is part of a broader ecosystem of tools for containerization and 183 | environment management in R. Depending on your specific needs, you might want 184 | to explore these complementary packages: 185 | 186 | - [`containerit`][containerit-pkg]: An alternative approach to generating 187 | Dockerfiles, with a focus on reproducible research workflows 188 | - [`dockerfiler`][dockerfiler-pkg]: Another R package for Dockerfile generation 189 | that uses a different syntax and approach 190 | - [`renv`][renv-pkg]: For R package dependency management, which pairs well 191 | with `dockitect` for fully reproducible environments 192 | 193 | ## Citation 194 | 195 | If you use `dockitect` in your research or project, please consider citing it: 196 | 197 | ```r 198 | citation("dockitect") 199 | ``` 200 | 201 | ## License 202 | 203 | AGPL (>=3) 204 | 205 | [containerit-pkg]: https://github.com/o2r-project/containerit 206 | [dockerfiler-pkg]: https://github.com/ThinkR-open/dockerfiler 207 | [renv-pkg]: https://github.com/rstudio/renv/ 208 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # dockitect 5 | 6 | 7 | 8 | [![R-CMD-check](https://github.com/coatless-rpkg/dockitect/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/coatless-rpkg/dockitect/actions/workflows/R-CMD-check.yaml) 9 | 10 | 11 | `dockitect` is an R package for programmatically creating, validating, 12 | and managing Dockerfiles using a pipe-friendly syntax. It bridges the 13 | gap between R development and containerization, enabling seamless Docker 14 | integration for data science workflows. 15 | 16 | > \[!IMPORTANT\] 17 | > 18 | > This package is currently in the prototype/experimental stage. It is 19 | > not yet available on CRAN and may have bugs or limitations. 20 | 21 | ## Installation 22 | 23 | You can install the development version of `dockitect` from 24 | [GitHub](https://github.com/coatless-rpkg/dockitect) with: 25 | 26 | ``` r 27 | # install.packages("remotes") 28 | remotes::install_github("coatless-rpkg/dockitect") 29 | ``` 30 | 31 | ## Design Philosophy 32 | 33 | To make the API intuitive and discoverable, `dockitect` employs a naming 34 | convention across all its functions. Understanding these prefixes will 35 | help you navigate the package and find the functions you need: 36 | 37 | - `dockerfile()` - Create a new Dockerfile object 38 | - `dfi_*()` - **D**ockerfile **i**nstruction functions (e.g., 39 | `dfi_from()`, `dfi_run()`) 40 | - `dfm_*()` - **D**ockerfile **m**odification functions (e.g., 41 | `dfm_add_line()`, `dfm_group_similar()`) 42 | - `dockerignore()` - Create a new Dockerignore object 43 | - `di_*()` - **D**ockerignore functions (e.g., `di_add()`, 44 | `di_remove()`) 45 | - `dk_*()` - **D**oc**k**er configuration/template functions (e.g., 46 | `dk_from_session()`, `dk_template_shiny()`) 47 | 48 | ## Usage 49 | 50 | The following examples demonstrate how to use `dockitect` for various 51 | containerization scenarios. Each example showcases different aspects of 52 | the package’s functionality, from basic Dockerfile creation to more 53 | advanced use cases. 54 | 55 | ### Dockerfile Creation 56 | 57 | Let’s start with the fundamentals. Creating a Dockerfile typically 58 | involves specifying a base image, installing dependencies, copying 59 | files, and defining commands. With `dockitect`, this process becomes a 60 | series of intuitive pipe-chained functions. 61 | 62 | For example, let’s create a Dockerfile for an R script: 63 | 64 | ``` r 65 | library(dockitect) 66 | 67 | # Create a basic Dockerfile for an R script 68 | df_rscript <- dockerfile() |> 69 | dfi_from("rocker/r-ver:4.4.3") |> 70 | dfi_label(maintainer = "user@example.com") |> 71 | dfi_run("apt-get update && apt-get install -y libcurl4-openssl-dev") |> 72 | dfi_workdir("/app") |> 73 | dfi_copy("analysis.R", "/app/") |> 74 | dfi_cmd("Rscript /app/analysis.R") 75 | 76 | df_rscript 77 | #> FROM rocker/r-ver:4.4.3 78 | #> LABEL maintainer="user@example.com" 79 | #> RUN apt-get update && apt-get install -y libcurl4-openssl-dev 80 | #> WORKDIR /app 81 | #> COPY analysis.R /app/ 82 | #> CMD Rscript /app/analysis.R 83 | 84 | ## Write the Dockerfile to disk 85 | # write_dockerfile(df_rscript) 86 | ``` 87 | 88 | ### Use Templates 89 | 90 | `dockitect` includes specialized templates for common R application 91 | types, saving you time and ensuring best practices are followed. These 92 | templates are fully customizable and provide a solid foundation for your 93 | projects. 94 | 95 | #### Shiny Application 96 | 97 | Creating a Docker container for a Shiny application requires specific 98 | configurations for ports, networking, and dependencies. The Shiny 99 | template handles these details automatically. For example, we can create 100 | a Dockerfile for a Shiny app with proper port configuration: 101 | 102 | ``` r 103 | # Create a Dockerfile for a Shiny app 104 | dk_template_shiny( 105 | r_version = "4.4.3", # Specify R version 106 | port = 3838, # Expose Shiny port 107 | app_dir = "app/" # Location of app files 108 | ) |> 109 | dfi_env(SHINY_HOST = "0.0.0.0") |> # Configure Shiny to listen on all interfaces 110 | write_dockerfile() 111 | ``` 112 | 113 | ### Custom Templates 114 | 115 | While `dockitect` includes templates for common scenarios, your 116 | organization might have specific containerization patterns. The template 117 | system is extensible, allowing you to create, register, and reuse your 118 | own templates throughout your projects: 119 | 120 | ``` r 121 | # Create a custom template function 122 | my_template <- function(my_param = "default") { 123 | dockerfile() |> 124 | dfi_from("rocker/r-ver:4.4.3") |> 125 | dfi_run(paste0("echo ", my_param)) 126 | } 127 | 128 | # Register the template 129 | dk_register_template("my_template", my_template) 130 | 131 | # Use the template 132 | dk_template_custom("my_template", my_param = "hello") |> 133 | write_dockerfile() 134 | ``` 135 | 136 | ### Modify Existing Dockerfiles 137 | 138 | Sometimes you need to modify existing Dockerfiles rather than creating 139 | them from scratch. `dockitect` provides specialized functions for 140 | reading, modifying, and writing Dockerfiles, allowing for precise 141 | changes without manual text editing: 142 | 143 | ``` r 144 | # Read an existing Dockerfile 145 | df <- read_dockerfile("path/to/Dockerfile") 146 | 147 | # Modify it 148 | df |> 149 | dfm_remove_line(5) |> # Remove line 5 150 | dfm_group_similar() |> # Group similar commands (e.g., RUN) 151 | write_dockerfile("Dockerfile.new") # Write to a new file 152 | ``` 153 | 154 | ### Create and Manage .dockerignore 155 | 156 | Docker builds can be slowed down by unnecessarily including large or 157 | irrelevant files in the build context. A properly configured 158 | `.dockerignore` file helps keep your builds fast and your images small. 159 | `dockitect` makes it easy to create and maintain a `.dockerignore` file 160 | through `dockerignore()`. 161 | 162 | ``` r 163 | # Create a .dockerignore file with common patterns 164 | dockerignore() |> 165 | dk_template_ignore_common(git = TRUE, r = TRUE) |> # Add common patterns for Git and R 166 | di_add("*.log") |> # Add custom patterns 167 | di_add("output/") |> 168 | write_dockerignore() 169 | ``` 170 | 171 | ## Related Packages 172 | 173 | `dockitect` is part of a broader ecosystem of tools for containerization 174 | and environment management in R. Depending on your specific needs, you 175 | might want to explore these complementary packages: 176 | 177 | - [`containerit`](https://github.com/o2r-project/containerit): An 178 | alternative approach to generating Dockerfiles, with a focus on 179 | reproducible research workflows 180 | - [`dockerfiler`](https://github.com/ThinkR-open/dockerfiler): Another R 181 | package for Dockerfile generation that uses a different syntax and 182 | approach 183 | - [`renv`](https://github.com/rstudio/renv/): For R package dependency 184 | management, which pairs well with `dockitect` for fully reproducible 185 | environments 186 | 187 | ## Citation 188 | 189 | If you use `dockitect` in your research or project, please consider 190 | citing it: 191 | 192 | ``` r 193 | citation("dockitect") 194 | ``` 195 | 196 | ## License 197 | 198 | AGPL (\>=3) 199 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: ~ 2 | 3 | template: 4 | bootstrap: 5 5 | bslib: 6 | primary: "#0078D7" # Docker-like blue 7 | border-radius: 0.5rem 8 | btn-border-radius: 0.25rem 9 | opengraph: 10 | image: 11 | src: man/figures/dockitect-logo.svg 12 | alt: "dockitect: An R package for programmatically creating Dockerfiles" 13 | twitter: 14 | creator: "@" 15 | card: summary_large_image 16 | 17 | navbar: 18 | structure: 19 | left: [intro, reference, articles, tutorials, news] 20 | right: [search, github] 21 | components: 22 | github: 23 | icon: fab fa-github 24 | href: https://github.com/coatless-rpkg/dockitect 25 | 26 | reference: 27 | - title: "Package Overview" 28 | desc: "Introduction to the dockitect package and its core concepts" 29 | contents: 30 | - dockitect-package 31 | 32 | - title: "Core Dockerfile Functions" 33 | desc: "Essential functions for creating and managing Dockerfiles" 34 | contents: 35 | - dockerfile 36 | - is_dockerfile 37 | - has_instruction 38 | - check_dockerfile 39 | - print.dockerfile 40 | 41 | - title: "Creating Dockerfile Instructions" 42 | desc: "Functions for adding different Docker instructions to a Dockerfile" 43 | contents: 44 | - starts_with("dfi_") 45 | 46 | - title: "Dockerfile Input/Output" 47 | desc: "Functions for reading and writing Dockerfiles" 48 | contents: 49 | - read_dockerfile 50 | - write_dockerfile 51 | 52 | - title: "Dockerfile Modification" 53 | desc: "Functions for modifying Dockerfiles" 54 | contents: 55 | - starts_with("dfm_") 56 | 57 | - title: "Core Dockerignore Functions" 58 | desc: "Essential functions for creating and managing .dockerignore files" 59 | contents: 60 | - dockerignore 61 | - is_dockerignore 62 | - check_dockerignore 63 | - print.dockerignore 64 | - c.dockerignore 65 | 66 | - title: "Dockerignore Pattern Instruction Management" 67 | desc: "Functions for adding and removing patterns in .dockerignore files" 68 | contents: 69 | - starts_with("di_") 70 | 71 | - title: "Dockerignore Input/Output" 72 | desc: "Functions for reading and writing .dockerignore files" 73 | contents: 74 | - read_dockerignore 75 | - write_dockerignore 76 | 77 | - title: "Dockerfile Generation from Environments" 78 | desc: "Functions for generating Dockerfiles from various sources" 79 | contents: 80 | - starts_with("dk_from_") 81 | - dk_add_sysreqs 82 | 83 | - title: "Dockerfile Templates" 84 | desc: "Ready-to-use templates for common R container scenarios" 85 | contents: 86 | - dk_template_base 87 | - dk_template_shiny 88 | - dk_template_plumber 89 | - dk_register_template 90 | - dk_template_custom 91 | 92 | - title: "Dockerignore Templates" 93 | desc: "Ready-to-use templates for common .dockerignore patterns" 94 | contents: 95 | - starts_with("dk_template_ignore_") 96 | 97 | - title: "Utility Functions" 98 | desc: "Helper functions for working with Docker environments" 99 | contents: 100 | - determine_package_manager 101 | - determine_linux_distribution 102 | - map_to_sysreqs_platform 103 | - generate_pkg_install_cmd 104 | 105 | 106 | articles: 107 | - title: "Getting Started" 108 | desc: > 109 | Learn how to use dockitect to create and manage Docker files for R projects 110 | contents: 111 | - getting-started-with-dockitect 112 | - making-a-dockitect-dockerfile-into-a-running-container 113 | 114 | home: 115 | sidebar: 116 | structure: [links, license, community, citation, authors, dev] 117 | links: 118 | - text: Rocker Project Images 119 | href: https://rocker-project.org/images/ 120 | - text: Dockerfile documentation 121 | href: https://docs.docker.com/reference/dockerfile/ 122 | - text: Dockerignore documentation 123 | href: https://docs.docker.com/build/concepts/context/#dockerignore-files 124 | 125 | development: 126 | mode: auto 127 | -------------------------------------------------------------------------------- /dockitect.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: 6cc78c13-076f-4926-8eb4-f4053616786d 3 | 4 | RestoreWorkspace: Default 5 | SaveWorkspace: Default 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: Sweave 14 | LaTeX: pdfLaTeX 15 | 16 | AutoAppendNewline: Yes 17 | StripTrailingWhitespace: Yes 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /man/add_dockerfile_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-core.R 3 | \name{add_dockerfile_line} 4 | \alias{add_dockerfile_line} 5 | \title{Add a line to a \code{dockerfile} and update metadata} 6 | \usage{ 7 | add_dockerfile_line(dockerfile, instruction, args) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{instruction}{Docker instruction (e.g., \code{"FROM"}, \code{"RUN"})} 13 | 14 | \item{args}{Arguments for the instruction} 15 | } 16 | \value{ 17 | Updated \code{dockerfile} object with the new line and updated metadata 18 | } 19 | \description{ 20 | Adds a line to a \code{dockerfile} and updates its metadata based on the instruction. 21 | This is an internal function used by the more specific \verb{dfi_*} functions. 22 | } 23 | \details{ 24 | This internal function handles: 25 | \itemize{ 26 | \item Adding the instruction with proper formatting 27 | \item Handling multi-line arguments with appropriate indentation 28 | \item Updating metadata for special instructions like \code{FROM} 29 | } 30 | 31 | For \code{FROM} instructions, it extracts and stores: 32 | \itemize{ 33 | \item Base image name 34 | \item Package manager 35 | \item Operating system 36 | \item R version (for \code{rocker/r-ver:version} images) 37 | } 38 | } 39 | \seealso{ 40 | \code{\link[=dfi_from]{dfi_from()}} for adding a FROM instruction & 41 | \code{\link[=dfi_run]{dfi_run()}} for adding a RUN instruction 42 | 43 | Other dockerfile core functions: 44 | \code{\link{check_dockerfile}()}, 45 | \code{\link{dockerfile}()}, 46 | \code{\link{is_dockerfile}()}, 47 | \code{\link{print.dockerfile}()} 48 | } 49 | \concept{dockerfile core functions} 50 | \keyword{internal} 51 | -------------------------------------------------------------------------------- /man/c.dockerignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-core.R 3 | \name{c.dockerignore} 4 | \alias{c.dockerignore} 5 | \title{Combine multiple \code{dockerignore} objects} 6 | \usage{ 7 | \method{c}{dockerignore}(...) 8 | } 9 | \arguments{ 10 | \item{...}{\code{dockerignore} objects to combine} 11 | } 12 | \value{ 13 | A new \code{dockerignore} object with combined patterns from all inputs 14 | } 15 | \description{ 16 | Merges patterns from multiple \code{dockerignore} objects into a single one. 17 | This is useful for combining different template patterns. 18 | } 19 | \examples{ 20 | # Create dockerignore objects with different patterns 21 | di_git <- dk_template_ignore_git() 22 | di_r <- dk_template_ignore_r() 23 | 24 | # Combine them 25 | di_combined <- c(di_git, di_r) 26 | 27 | } 28 | \seealso{ 29 | \code{\link[=dockerignore]{dockerignore()}} for creating a new \code{dockerignore} object & 30 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for adding common patterns 31 | 32 | Other dockerignore core functions: 33 | \code{\link{check_dockerignore}()}, 34 | \code{\link{dockerignore}()}, 35 | \code{\link{is_dockerignore}()}, 36 | \code{\link{print.dockerignore}()} 37 | } 38 | \concept{dockerignore core functions} 39 | -------------------------------------------------------------------------------- /man/check_dockerfile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-core.R 3 | \name{check_dockerfile} 4 | \alias{check_dockerfile} 5 | \title{Ensure an object is a \code{dockerfile}} 6 | \usage{ 7 | check_dockerfile(dockerfile) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{Object to check} 11 | } 12 | \value{ 13 | Invisibly returns \code{TRUE} if valid, otherwise throws an error 14 | } 15 | \description{ 16 | Verifies that the provided object is a valid \code{dockerfile} class object, 17 | throwing an error if not. Useful for validation inside functions that 18 | expect \code{dockerfile} objects. 19 | } 20 | \examples{ 21 | df <- dockerfile() 22 | check_dockerfile(df) 23 | \dontrun{ 24 | # This would throw an error 25 | check_dockerfile(list()) 26 | } 27 | 28 | } 29 | \seealso{ 30 | \code{\link[=is_dockerfile]{is_dockerfile()}} for checking if an object is a dockerfile & 31 | \code{\link[=dockerfile]{dockerfile()}} for creating a dockerfile object 32 | 33 | Other dockerfile core functions: 34 | \code{\link{add_dockerfile_line}()}, 35 | \code{\link{dockerfile}()}, 36 | \code{\link{is_dockerfile}()}, 37 | \code{\link{print.dockerfile}()} 38 | } 39 | \concept{dockerfile core functions} 40 | -------------------------------------------------------------------------------- /man/check_dockerignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-core.R 3 | \name{check_dockerignore} 4 | \alias{check_dockerignore} 5 | \title{Ensure an object is a \code{dockerignore}} 6 | \usage{ 7 | check_dockerignore(dockerignore) 8 | } 9 | \arguments{ 10 | \item{dockerignore}{Object to check} 11 | } 12 | \value{ 13 | Invisibly returns \code{TRUE} if valid, otherwise throws an error 14 | } 15 | \description{ 16 | Verifies that the provided object is a valid \code{dockerignore} class object, 17 | throwing an error if not. Useful for validation inside functions that 18 | expect \code{dockerignore} objects. 19 | } 20 | \examples{ 21 | di <- dockerignore() 22 | check_dockerignore(di) # Valid, returns TRUE invisibly 23 | 24 | \dontrun{ 25 | # This would throw an error 26 | check_dockerignore(list()) 27 | } 28 | 29 | } 30 | \seealso{ 31 | \code{\link[=is_dockerignore]{is_dockerignore()}} for checking if an object is a dockerignore & 32 | \code{\link[=dockerignore]{dockerignore()}} for creating a dockerignore object 33 | 34 | Other dockerignore core functions: 35 | \code{\link{c.dockerignore}()}, 36 | \code{\link{dockerignore}()}, 37 | \code{\link{is_dockerignore}()}, 38 | \code{\link{print.dockerignore}()} 39 | } 40 | \concept{dockerignore core functions} 41 | -------------------------------------------------------------------------------- /man/determine_linux_distribution.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{determine_linux_distribution} 4 | \alias{determine_linux_distribution} 5 | \title{Determine the Linux Distribution from a base image} 6 | \usage{ 7 | determine_linux_distribution(base_image) 8 | } 9 | \arguments{ 10 | \item{base_image}{Base image name} 11 | } 12 | \value{ 13 | Character string of OS type (e.g., "ubuntu", "centos", "debian", "alpine") 14 | } 15 | \description{ 16 | Analyzes a Docker base image name to determine the underlying distribution 17 | } 18 | \details{ 19 | This function parses the base image name to extract the underlying 20 | distribution. For Rocker Project images (which are based on Ubuntu/Debian), 21 | it returns "ubuntu". For other distributions, it attempts to identify 22 | common ones like Debian, CentOS, Fedora, Alpine, etc. 23 | } 24 | \examples{ 25 | determine_linux_distribution("rocker/r-ver:4.4.0") # Returns "ubuntu" 26 | determine_linux_distribution("alpine:3.16") # Returns "alpine" 27 | determine_linux_distribution("centos:7") # Returns "centos" 28 | 29 | } 30 | \seealso{ 31 | \code{\link[=determine_package_manager]{determine_package_manager()}} for determining the package manager & 32 | \code{\link[=map_to_sysreqs_platform]{map_to_sysreqs_platform()}} for mapping to sysreqs platform 33 | 34 | Other utility functions: 35 | \code{\link{determine_package_manager}()}, 36 | \code{\link{dk_add_sysreqs}()}, 37 | \code{\link{map_to_sysreqs_platform}()} 38 | } 39 | \concept{utility functions} 40 | -------------------------------------------------------------------------------- /man/determine_package_manager.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{determine_package_manager} 4 | \alias{determine_package_manager} 5 | \title{Determine the package manager from a base image} 6 | \usage{ 7 | determine_package_manager(base_image) 8 | } 9 | \arguments{ 10 | \item{base_image}{Base image name} 11 | } 12 | \value{ 13 | Character string of package manager type ("apt", "yum", "apk", "zypper", "pacman") 14 | } 15 | \description{ 16 | Analyzes a Docker base image name to determine the appropriate package manager. 17 | } 18 | \details{ 19 | This function first identifies the linux distribution using 20 | \code{\link[=determine_linux_distribution]{determine_linux_distribution()}}, then maps that to the appropriate 21 | package manager: 22 | \itemize{ 23 | \item Ubuntu/Debian → apt 24 | \item CentOS/Fedora/RHEL → yum 25 | \item Alpine → apk 26 | \item OpenSUSE → zypper 27 | \item Arch → pacman 28 | } 29 | } 30 | \examples{ 31 | determine_package_manager("rocker/r-ver:4.4.0") # Returns "apt" 32 | determine_package_manager("alpine:3.16") # Returns "apk" 33 | determine_package_manager("centos:7") # Returns "yum" 34 | 35 | } 36 | \seealso{ 37 | \code{\link[=determine_linux_distribution]{determine_linux_distribution()}} for determining the operating system & 38 | \code{\link[=generate_pkg_install_cmd]{generate_pkg_install_cmd()}} for generating package installation commands 39 | 40 | Other utility functions: 41 | \code{\link{determine_linux_distribution}()}, 42 | \code{\link{dk_add_sysreqs}()}, 43 | \code{\link{map_to_sysreqs_platform}()} 44 | } 45 | \concept{utility functions} 46 | -------------------------------------------------------------------------------- /man/dfi_add.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_add} 4 | \alias{dfi_add} 5 | \title{Add an \code{ADD} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_add(dockerfile, src, dest) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{src}{Source path (can be a URL or tar archive)} 13 | 14 | \item{dest}{Destination path in the container} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with the \code{ADD} instruction added 18 | } 19 | \description{ 20 | Adds an \code{ADD} instruction to copy files, directories, or remote files 21 | from source to the container's filesystem at destination. 22 | } 23 | \details{ 24 | \code{ADD} is similar to \code{COPY}, but with additional features: 25 | \itemize{ 26 | \item If \code{src} is a URL, the file is downloaded from the URL 27 | \item If \code{src} is a local tar archive, it will be automatically unpacked 28 | } 29 | 30 | Note that \code{COPY} is generally preferred for simple file copying because 31 | it's more explicit and has fewer side effects than \code{ADD}. 32 | } 33 | \examples{ 34 | # Add a local file 35 | df <- dockerfile() |> 36 | dfi_from("rocker/r-ver:4.4.0") |> 37 | dfi_add("local.txt", "/app/local.txt") 38 | 39 | # Add a file from a URL 40 | df <- dockerfile() |> 41 | dfi_from("rocker/r-ver:4.4.0") |> 42 | dfi_add("https://example.com/file.txt", "/app/file.txt") 43 | 44 | } 45 | \seealso{ 46 | \code{\link[=dfi_copy]{dfi_copy()}} for simpler file copying (generally preferred) & 47 | \href{https://docs.docker.com/engine/reference/builder/#add}{Official Docker \code{ADD} documentation} 48 | 49 | Other dockerfile instruction functions: 50 | \code{\link{dfi_arg}()}, 51 | \code{\link{dfi_cmd}()}, 52 | \code{\link{dfi_copy}()}, 53 | \code{\link{dfi_entrypoint}()}, 54 | \code{\link{dfi_env}()}, 55 | \code{\link{dfi_expose}()}, 56 | \code{\link{dfi_from}()}, 57 | \code{\link{dfi_healthcheck}()}, 58 | \code{\link{dfi_label}()}, 59 | \code{\link{dfi_maintainer}()}, 60 | \code{\link{dfi_onbuild}()}, 61 | \code{\link{dfi_run}()}, 62 | \code{\link{dfi_shell}()}, 63 | \code{\link{dfi_stopsignal}()}, 64 | \code{\link{dfi_user}()}, 65 | \code{\link{dfi_volume}()}, 66 | \code{\link{dfi_workdir}()} 67 | } 68 | \concept{dockerfile instruction functions} 69 | -------------------------------------------------------------------------------- /man/dfi_arg.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_arg} 4 | \alias{dfi_arg} 5 | \title{Add an \code{ARG} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_arg(dockerfile, name, default = NULL) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{name}{Argument name} 13 | 14 | \item{default}{Default value (optional)} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with the \code{ARG} instruction added 18 | } 19 | \description{ 20 | Adds an \code{ARG} instruction to define a variable that users can pass at build-time 21 | to the builder using the \code{--build-arg} flag. 22 | } 23 | \details{ 24 | Build arguments are only available during the build of a Docker image and 25 | not when a container is running. They can be used to parameterize the build 26 | process, allowing users to specify values like versions or configuration 27 | options at build time. 28 | 29 | When building the image, use: 30 | 31 | \if{html}{\out{
}}\preformatted{docker build --build-arg R_VERSION=4.4.0 -t my-image . 32 | }\if{html}{\out{
}} 33 | } 34 | \examples{ 35 | # Define an argument with no default 36 | df <- dockerfile() |> 37 | dfi_arg("R_VERSION") |> 38 | dfi_from(paste0("rocker/r-ver:", "$R_VERSION")) 39 | df 40 | 41 | # Define an argument with a default value 42 | df <- dockerfile() |> 43 | dfi_arg("R_VERSION", "4.4.0") |> 44 | dfi_from(paste0("rocker/r-ver:", "$R_VERSION")) 45 | df 46 | 47 | } 48 | \seealso{ 49 | \code{\link[=dfi_env]{dfi_env()}} for runtime environment variables & 50 | \href{https://docs.docker.com/engine/reference/builder/#arg}{Official Docker \code{ARG} documentation} 51 | 52 | Other dockerfile instruction functions: 53 | \code{\link{dfi_add}()}, 54 | \code{\link{dfi_cmd}()}, 55 | \code{\link{dfi_copy}()}, 56 | \code{\link{dfi_entrypoint}()}, 57 | \code{\link{dfi_env}()}, 58 | \code{\link{dfi_expose}()}, 59 | \code{\link{dfi_from}()}, 60 | \code{\link{dfi_healthcheck}()}, 61 | \code{\link{dfi_label}()}, 62 | \code{\link{dfi_maintainer}()}, 63 | \code{\link{dfi_onbuild}()}, 64 | \code{\link{dfi_run}()}, 65 | \code{\link{dfi_shell}()}, 66 | \code{\link{dfi_stopsignal}()}, 67 | \code{\link{dfi_user}()}, 68 | \code{\link{dfi_volume}()}, 69 | \code{\link{dfi_workdir}()} 70 | } 71 | \concept{dockerfile instruction functions} 72 | -------------------------------------------------------------------------------- /man/dfi_cmd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_cmd} 4 | \alias{dfi_cmd} 5 | \title{Add a \code{CMD} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_cmd(dockerfile, command) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{command}{Command to run (character vector or string)} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{CMD} instruction added 16 | } 17 | \description{ 18 | Adds a \code{CMD} instruction to provide defaults for an executing container. 19 | These defaults can be executable programs or commands to be executed when 20 | the container starts. 21 | } 22 | \details{ 23 | The function automatically converts the command to JSON array format, which 24 | is the recommended approach for better signal handling. 25 | Only one \code{CMD} instruction is effective in a \strong{Dockerfile}; if multiple are specified, 26 | only the last one will take effect. 27 | } 28 | \examples{ 29 | # Simple command 30 | df <- dockerfile() |> 31 | dfi_from("rocker/r-ver:4.4.0") |> 32 | dfi_copy("script.R", "/app/script.R") |> 33 | dfi_cmd("Rscript /app/script.R") 34 | 35 | # Array format (recommended) 36 | df <- dockerfile() |> 37 | dfi_from("rocker/r-ver:4.4.0") |> 38 | dfi_cmd(c("R", "--no-save")) 39 | 40 | } 41 | \seealso{ 42 | \code{\link[=dfi_entrypoint]{dfi_entrypoint()}} for defining the main executable of the container, 43 | \code{\link[=dfi_run]{dfi_run()}} for executing commands during the build, & 44 | \href{https://docs.docker.com/engine/reference/builder/#cmd}{Official Docker \code{CMD} documentation} 45 | 46 | Other dockerfile instruction functions: 47 | \code{\link{dfi_add}()}, 48 | \code{\link{dfi_arg}()}, 49 | \code{\link{dfi_copy}()}, 50 | \code{\link{dfi_entrypoint}()}, 51 | \code{\link{dfi_env}()}, 52 | \code{\link{dfi_expose}()}, 53 | \code{\link{dfi_from}()}, 54 | \code{\link{dfi_healthcheck}()}, 55 | \code{\link{dfi_label}()}, 56 | \code{\link{dfi_maintainer}()}, 57 | \code{\link{dfi_onbuild}()}, 58 | \code{\link{dfi_run}()}, 59 | \code{\link{dfi_shell}()}, 60 | \code{\link{dfi_stopsignal}()}, 61 | \code{\link{dfi_user}()}, 62 | \code{\link{dfi_volume}()}, 63 | \code{\link{dfi_workdir}()} 64 | } 65 | \concept{dockerfile instruction functions} 66 | -------------------------------------------------------------------------------- /man/dfi_copy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_copy} 4 | \alias{dfi_copy} 5 | \title{Add a \code{COPY} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_copy(dockerfile, src, dest, from = NULL) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{src}{Source path (relative to build context)} 13 | 14 | \item{dest}{Destination path (in the container)} 15 | 16 | \item{from}{Build stage to copy from (optional, for multi-stage builds)} 17 | } 18 | \value{ 19 | An updated \code{dockerfile} object with the \code{COPY} instruction added 20 | } 21 | \description{ 22 | Adds a \code{COPY} instruction to copy files or directories from the build context 23 | to the container's filesystem. 24 | } 25 | \details{ 26 | The \code{COPY} instruction copies new files or directories from \code{src} 27 | and adds them to the filesystem of the container at the path \code{dest}. 28 | When used with the \code{from} parameter, it can copy files from previous 29 | build stages in multi-stage builds. 30 | } 31 | \examples{ 32 | # Copy a single file 33 | df <- dockerfile() |> 34 | dfi_from("rocker/r-ver:4.4.0") |> 35 | dfi_copy("script.R", "/app/script.R") 36 | 37 | # Copy from a previous build stage 38 | df <- dockerfile() |> 39 | dfi_from("rocker/r-ver:4.4.0", as = "build") |> 40 | dfi_run("R -e \"install.packages('renv')\"") |> 41 | dfi_from("rocker/r-ver:4.4.0", as = "final") |> 42 | dfi_copy("/usr/local/lib/R/site-library/renv", 43 | "/usr/local/lib/R/site-library/renv", 44 | from = "build") 45 | 46 | } 47 | \seealso{ 48 | \code{\link[=dfi_add]{dfi_add()}} for similar functionality with additional features (like URL support), 49 | \code{\link[=dfi_workdir]{dfi_workdir()}} for setting the working directory, & 50 | \href{https://docs.docker.com/engine/reference/builder/#copy}{Official Docker \code{COPY} documentation} 51 | 52 | Other dockerfile instruction functions: 53 | \code{\link{dfi_add}()}, 54 | \code{\link{dfi_arg}()}, 55 | \code{\link{dfi_cmd}()}, 56 | \code{\link{dfi_entrypoint}()}, 57 | \code{\link{dfi_env}()}, 58 | \code{\link{dfi_expose}()}, 59 | \code{\link{dfi_from}()}, 60 | \code{\link{dfi_healthcheck}()}, 61 | \code{\link{dfi_label}()}, 62 | \code{\link{dfi_maintainer}()}, 63 | \code{\link{dfi_onbuild}()}, 64 | \code{\link{dfi_run}()}, 65 | \code{\link{dfi_shell}()}, 66 | \code{\link{dfi_stopsignal}()}, 67 | \code{\link{dfi_user}()}, 68 | \code{\link{dfi_volume}()}, 69 | \code{\link{dfi_workdir}()} 70 | } 71 | \concept{dockerfile instruction functions} 72 | -------------------------------------------------------------------------------- /man/dfi_entrypoint.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_entrypoint} 4 | \alias{dfi_entrypoint} 5 | \title{Add an \code{ENTRYPOINT} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_entrypoint(dockerfile, entrypoint) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{entrypoint}{Entrypoint command (character vector or string)} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{ENTRYPOINT} instruction added 16 | } 17 | \description{ 18 | Adds an \code{ENTRYPOINT} instruction to configure a container that will run as an executable. 19 | } 20 | \details{ 21 | The \code{ENTRYPOINT} instruction defines the executable that will be run when 22 | the container starts. Any command line arguments passed to \verb{docker run} 23 | will be appended to the entrypoint command. 24 | 25 | When used together with \code{CMD}, the \code{CMD} instruction provides default arguments 26 | to the \code{ENTRYPOINT} command that can be overridden at runtime. 27 | 28 | The function automatically converts the command to JSON array format if 29 | a vector is provided, which is the recommended approach for proper signal handling. 30 | } 31 | \examples{ 32 | # Simple entrypoint 33 | df <- dockerfile() |> 34 | dfi_from("rocker/r-ver:4.4.0") |> 35 | dfi_entrypoint("R") 36 | df 37 | 38 | # Array format (recommended) 39 | df <- dockerfile() |> 40 | dfi_from("rocker/r-ver:4.4.0") |> 41 | dfi_entrypoint(c("R", "--no-save")) 42 | df 43 | 44 | } 45 | \seealso{ 46 | \code{\link[=dfi_cmd]{dfi_cmd()}} for providing default arguments to the entrypoint & 47 | \href{https://docs.docker.com/engine/reference/builder/#entrypoint}{Official Docker \code{ENTRYPOINT} documentation} 48 | 49 | Other dockerfile instruction functions: 50 | \code{\link{dfi_add}()}, 51 | \code{\link{dfi_arg}()}, 52 | \code{\link{dfi_cmd}()}, 53 | \code{\link{dfi_copy}()}, 54 | \code{\link{dfi_env}()}, 55 | \code{\link{dfi_expose}()}, 56 | \code{\link{dfi_from}()}, 57 | \code{\link{dfi_healthcheck}()}, 58 | \code{\link{dfi_label}()}, 59 | \code{\link{dfi_maintainer}()}, 60 | \code{\link{dfi_onbuild}()}, 61 | \code{\link{dfi_run}()}, 62 | \code{\link{dfi_shell}()}, 63 | \code{\link{dfi_stopsignal}()}, 64 | \code{\link{dfi_user}()}, 65 | \code{\link{dfi_volume}()}, 66 | \code{\link{dfi_workdir}()} 67 | } 68 | \concept{dockerfile instruction functions} 69 | -------------------------------------------------------------------------------- /man/dfi_env.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_env} 4 | \alias{dfi_env} 5 | \title{Add an \code{ENV} instruction to a dockerfile} 6 | \usage{ 7 | dfi_env(dockerfile, ...) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{...}{Named environment variables} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with ENV instructions added 16 | } 17 | \description{ 18 | Adds one or more \code{ENV} instructions to set environment variables in the container. 19 | } 20 | \details{ 21 | Environment variables set with \code{ENV} persist throughout the container's runtime. 22 | Each variable is added as a separate \code{ENV} instruction in the \strong{Dockerfile}, 23 | making it easier to track changes in the Docker build history. 24 | } 25 | \examples{ 26 | # Add a single environment variable 27 | df <- dockerfile() |> 28 | dfi_from("rocker/r-ver:4.4.0") |> 29 | dfi_env(PATH = "/usr/local/bin:$PATH") 30 | df 31 | 32 | # Add multiple environment variables 33 | df <- dockerfile() |> 34 | dfi_from("rocker/r-ver:4.4.0") |> 35 | dfi_env( 36 | DEBIAN_FRONTEND = "noninteractive", 37 | TZ = "America/Chicago", 38 | LANG = "en_US.UTF-8" 39 | ) 40 | df 41 | 42 | } 43 | \seealso{ 44 | \code{\link[=dfi_arg]{dfi_arg()}} for build-time variables & 45 | \href{https://docs.docker.com/engine/reference/builder/#env}{Official Docker \code{ENV} documentation} 46 | 47 | Other dockerfile instruction functions: 48 | \code{\link{dfi_add}()}, 49 | \code{\link{dfi_arg}()}, 50 | \code{\link{dfi_cmd}()}, 51 | \code{\link{dfi_copy}()}, 52 | \code{\link{dfi_entrypoint}()}, 53 | \code{\link{dfi_expose}()}, 54 | \code{\link{dfi_from}()}, 55 | \code{\link{dfi_healthcheck}()}, 56 | \code{\link{dfi_label}()}, 57 | \code{\link{dfi_maintainer}()}, 58 | \code{\link{dfi_onbuild}()}, 59 | \code{\link{dfi_run}()}, 60 | \code{\link{dfi_shell}()}, 61 | \code{\link{dfi_stopsignal}()}, 62 | \code{\link{dfi_user}()}, 63 | \code{\link{dfi_volume}()}, 64 | \code{\link{dfi_workdir}()} 65 | } 66 | \concept{dockerfile instruction functions} 67 | -------------------------------------------------------------------------------- /man/dfi_expose.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_expose} 4 | \alias{dfi_expose} 5 | \title{Add an \code{EXPOSE} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_expose(dockerfile, ports) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{ports}{Ports to expose (numeric or character vector)} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{EXPOSE} instruction added 16 | } 17 | \description{ 18 | Adds an \code{EXPOSE} instruction to inform Docker that the container will listen 19 | on the specified network ports at runtime. 20 | } 21 | \details{ 22 | The \code{EXPOSE} instruction does not actually publish the port. It functions 23 | as documentation between the person who builds the image and the person who 24 | runs the container, about which ports are intended to be published. 25 | 26 | To actually publish the port when running the container, use the \code{-p} flag 27 | in the \verb{docker run} command. 28 | } 29 | \examples{ 30 | # Expose a single port 31 | df <- dockerfile() |> 32 | dfi_from("rocker/r-ver:4.4.0") |> 33 | dfi_expose(8080) 34 | 35 | # Expose multiple ports 36 | df <- dockerfile() |> 37 | dfi_from("rocker/shiny:4.4.0") |> 38 | dfi_expose(c(3838, 8080)) 39 | 40 | } 41 | \seealso{ 42 | \code{\link[=dk_template_shiny]{dk_template_shiny()}} for a template that exposes Shiny ports, 43 | \code{\link[=dk_template_plumber]{dk_template_plumber()}} for a template that exposes Plumber API ports, & 44 | \href{https://docs.docker.com/engine/reference/builder/#expose}{Official Docker \code{EXPOSE} documentation} 45 | 46 | Other dockerfile instruction functions: 47 | \code{\link{dfi_add}()}, 48 | \code{\link{dfi_arg}()}, 49 | \code{\link{dfi_cmd}()}, 50 | \code{\link{dfi_copy}()}, 51 | \code{\link{dfi_entrypoint}()}, 52 | \code{\link{dfi_env}()}, 53 | \code{\link{dfi_from}()}, 54 | \code{\link{dfi_healthcheck}()}, 55 | \code{\link{dfi_label}()}, 56 | \code{\link{dfi_maintainer}()}, 57 | \code{\link{dfi_onbuild}()}, 58 | \code{\link{dfi_run}()}, 59 | \code{\link{dfi_shell}()}, 60 | \code{\link{dfi_stopsignal}()}, 61 | \code{\link{dfi_user}()}, 62 | \code{\link{dfi_volume}()}, 63 | \code{\link{dfi_workdir}()} 64 | } 65 | \concept{dockerfile instruction functions} 66 | -------------------------------------------------------------------------------- /man/dfi_from.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_from} 4 | \alias{dfi_from} 5 | \title{Add a \code{FROM} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_from(dockerfile, image, as = NULL) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{image}{Base image name (e.g., "rocker/r-ver:4.4.0")} 13 | 14 | \item{as}{Name for this build stage (optional, for multi-stage builds)} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with the \code{FROM} instruction added 18 | } 19 | \description{ 20 | Adds a \code{FROM} instruction to specify the base image for the Docker build. 21 | This is typically the first instruction in a \strong{Dockerfile}. 22 | } 23 | \details{ 24 | The \code{FROM} instruction initializes a new build stage and sets the base image. 25 | The metadata for the \code{dockerfile} object (package manager, OS, and R version) 26 | is automatically updated based on the base image. 27 | } 28 | \examples{ 29 | # Use a specific R version 30 | df <- dockerfile() |> 31 | dfi_from("rocker/r-ver:4.4.0") 32 | df 33 | 34 | # Use a multi-stage build 35 | df <- dockerfile() |> 36 | dfi_from("rocker/r-ver:4.4.0", as = "build") 37 | df 38 | 39 | } 40 | \seealso{ 41 | \code{\link[=dockerfile]{dockerfile()}} for creating a dockerfile object, 42 | \code{\link[=dfi_run]{dfi_run()}} for adding commands to run in the container, & 43 | \href{https://docs.docker.com/engine/reference/builder/#from}{Official Docker \code{FROM} documentation} 44 | 45 | Other dockerfile instruction functions: 46 | \code{\link{dfi_add}()}, 47 | \code{\link{dfi_arg}()}, 48 | \code{\link{dfi_cmd}()}, 49 | \code{\link{dfi_copy}()}, 50 | \code{\link{dfi_entrypoint}()}, 51 | \code{\link{dfi_env}()}, 52 | \code{\link{dfi_expose}()}, 53 | \code{\link{dfi_healthcheck}()}, 54 | \code{\link{dfi_label}()}, 55 | \code{\link{dfi_maintainer}()}, 56 | \code{\link{dfi_onbuild}()}, 57 | \code{\link{dfi_run}()}, 58 | \code{\link{dfi_shell}()}, 59 | \code{\link{dfi_stopsignal}()}, 60 | \code{\link{dfi_user}()}, 61 | \code{\link{dfi_volume}()}, 62 | \code{\link{dfi_workdir}()} 63 | } 64 | \concept{dockerfile instruction functions} 65 | -------------------------------------------------------------------------------- /man/dfi_healthcheck.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_healthcheck} 4 | \alias{dfi_healthcheck} 5 | \title{Add a \code{HEALTHCHECK} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_healthcheck( 8 | dockerfile, 9 | command, 10 | interval = NULL, 11 | timeout = NULL, 12 | start_period = NULL, 13 | retries = NULL 14 | ) 15 | } 16 | \arguments{ 17 | \item{dockerfile}{A \code{dockerfile} object} 18 | 19 | \item{command}{Health check command} 20 | 21 | \item{interval}{Interval between checks (e.g., "30s")} 22 | 23 | \item{timeout}{Timeout for checks (e.g., "5s")} 24 | 25 | \item{start_period}{Initial grace period (e.g., "5s")} 26 | 27 | \item{retries}{Number of retries} 28 | } 29 | \value{ 30 | An updated \code{dockerfile} object with the \code{HEALTHCHECK} instruction added 31 | } 32 | \description{ 33 | Adds a \code{HEALTHCHECK} instruction to tell Docker how to test if a container is 34 | still working properly. 35 | } 36 | \details{ 37 | The \code{HEALTHCHECK} instruction tells Docker how to determine if a container 38 | is healthy. The command should exit with 0 if the container is healthy, or 39 | with 1 if it's unhealthy. This is particularly useful for web applications 40 | or services where you want to ensure they're running correctly. 41 | 42 | Parameter meanings: 43 | \itemize{ 44 | \item \code{interval}: How often to run the check (default: 30s) 45 | \item \code{timeout}: Maximum time the check can take (default: 30s) 46 | \item \code{start-period}: Grace period before counting retries (default: 0s) 47 | \item \code{retries}: Number of consecutive failures needed to mark unhealthy (default: 3) 48 | } 49 | } 50 | \examples{ 51 | # Simple health check using curl 52 | df <- dockerfile() |> 53 | dfi_from("rocker/shiny:4.4.0") |> 54 | dfi_healthcheck("curl -f http://localhost:3838/ || exit 1", 55 | interval = "30s", 56 | timeout = "10s", 57 | retries = 3) 58 | df 59 | 60 | } 61 | \seealso{ 62 | \code{\link[=dk_template_shiny]{dk_template_shiny()}} for a template for Shiny apps, 63 | \code{\link[=dk_template_plumber]{dk_template_plumber()}} for a template for Plumber APIs, & 64 | \href{https://docs.docker.com/engine/reference/builder/#healthcheck}{Official Docker \code{HEALTHCHECK} documentation} 65 | 66 | Other dockerfile instruction functions: 67 | \code{\link{dfi_add}()}, 68 | \code{\link{dfi_arg}()}, 69 | \code{\link{dfi_cmd}()}, 70 | \code{\link{dfi_copy}()}, 71 | \code{\link{dfi_entrypoint}()}, 72 | \code{\link{dfi_env}()}, 73 | \code{\link{dfi_expose}()}, 74 | \code{\link{dfi_from}()}, 75 | \code{\link{dfi_label}()}, 76 | \code{\link{dfi_maintainer}()}, 77 | \code{\link{dfi_onbuild}()}, 78 | \code{\link{dfi_run}()}, 79 | \code{\link{dfi_shell}()}, 80 | \code{\link{dfi_stopsignal}()}, 81 | \code{\link{dfi_user}()}, 82 | \code{\link{dfi_volume}()}, 83 | \code{\link{dfi_workdir}()} 84 | } 85 | \concept{dockerfile instruction functions} 86 | -------------------------------------------------------------------------------- /man/dfi_label.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_label} 4 | \alias{dfi_label} 5 | \title{Add a \code{LABEL} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_label(dockerfile, ...) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{...}{Named labels as key-value pairs} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{LABEL} instruction added 16 | } 17 | \description{ 18 | Adds a \code{LABEL} instruction to include metadata in the Docker image. 19 | } 20 | \details{ 21 | Labels are key-value pairs that add metadata to your image. They can be used 22 | to organize images, record licensing information, annotate build information, 23 | or help with image automation. 24 | 25 | \href{https://github.com/opencontainers/image-spec/blob/main/annotations.md}{Common label conventions} 26 | include: 27 | \itemize{ 28 | \item \code{maintainer}: The person responsible for the image 29 | \item \code{org.opencontainers.image.authors}: Image authors 30 | \item \code{org.opencontainers.image.version}: Version of the packaged software 31 | \item \code{org.opencontainers.image.source}: URL to the source code 32 | } 33 | } 34 | \examples{ 35 | # Add a single label 36 | df <- dockerfile() |> 37 | dfi_from("rocker/r-ver:4.4.0") |> 38 | dfi_label(maintainer = "user@example.com") 39 | df 40 | 41 | # Add multiple labels 42 | df <- dockerfile() |> 43 | dfi_from("rocker/r-ver:4.4.0") |> 44 | dfi_label( 45 | maintainer = "user@example.com", 46 | version = "1.0.0", 47 | description = "Example R application", 48 | org.opencontainers.image.source = "https://github.com/user/repo" 49 | ) 50 | df 51 | 52 | } 53 | \seealso{ 54 | \code{\link[=dfi_maintainer]{dfi_maintainer()}} for the deprecated maintainer instruction & 55 | \href{https://docs.docker.com/engine/reference/builder/#label}{Official Docker \code{LABEL} documentation} 56 | 57 | Other dockerfile instruction functions: 58 | \code{\link{dfi_add}()}, 59 | \code{\link{dfi_arg}()}, 60 | \code{\link{dfi_cmd}()}, 61 | \code{\link{dfi_copy}()}, 62 | \code{\link{dfi_entrypoint}()}, 63 | \code{\link{dfi_env}()}, 64 | \code{\link{dfi_expose}()}, 65 | \code{\link{dfi_from}()}, 66 | \code{\link{dfi_healthcheck}()}, 67 | \code{\link{dfi_maintainer}()}, 68 | \code{\link{dfi_onbuild}()}, 69 | \code{\link{dfi_run}()}, 70 | \code{\link{dfi_shell}()}, 71 | \code{\link{dfi_stopsignal}()}, 72 | \code{\link{dfi_user}()}, 73 | \code{\link{dfi_volume}()}, 74 | \code{\link{dfi_workdir}()} 75 | } 76 | \concept{dockerfile instruction functions} 77 | -------------------------------------------------------------------------------- /man/dfi_maintainer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_maintainer} 4 | \alias{dfi_maintainer} 5 | \title{Add a \code{MAINTAINER} instruction to a \code{dockerfile} (deprecated)} 6 | \usage{ 7 | dfi_maintainer(dockerfile, maintainer) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{maintainer}{Maintainer info (e.g., "Name \href{mailto:email@example.com}{email@example.com}")} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{MAINTAINER} instruction added 16 | } 17 | \description{ 18 | Adds a \code{MAINTAINER} instruction to specify the author of the image. 19 | This instruction is deprecated in favor of using \verb{LABEL maintainer=...}. 20 | } 21 | \details{ 22 | The \code{MAINTAINER} instruction has been deprecated since Docker 1.13.0 (2017) 23 | in favor of using \verb{LABEL maintainer=...}. This function is provided for 24 | compatibility with older Dockerfiles, but new \strong{Dockerfile}s should use 25 | \code{dfi_label(maintainer = ...)} instead. 26 | } 27 | \examples{ 28 | # Using the deprecated MAINTAINER instruction 29 | df <- dockerfile() |> 30 | dfi_from("rocker/r-ver:4.4.0") |> 31 | dfi_maintainer("John Doe ") 32 | df 33 | 34 | # Better approach using LABEL 35 | df <- dockerfile() |> 36 | dfi_from("rocker/r-ver:4.4.0") |> 37 | dfi_label(maintainer = "John Doe ") 38 | df 39 | 40 | } 41 | \seealso{ 42 | \code{\link[=dfi_label]{dfi_label()}} for the recommended way to specify the maintainer & 43 | \href{https://docs.docker.com/engine/reference/builder/#maintainer-deprecated}{Official Docker deprecated \code{MAINTAINER} documentation} 44 | 45 | Other dockerfile instruction functions: 46 | \code{\link{dfi_add}()}, 47 | \code{\link{dfi_arg}()}, 48 | \code{\link{dfi_cmd}()}, 49 | \code{\link{dfi_copy}()}, 50 | \code{\link{dfi_entrypoint}()}, 51 | \code{\link{dfi_env}()}, 52 | \code{\link{dfi_expose}()}, 53 | \code{\link{dfi_from}()}, 54 | \code{\link{dfi_healthcheck}()}, 55 | \code{\link{dfi_label}()}, 56 | \code{\link{dfi_onbuild}()}, 57 | \code{\link{dfi_run}()}, 58 | \code{\link{dfi_shell}()}, 59 | \code{\link{dfi_stopsignal}()}, 60 | \code{\link{dfi_user}()}, 61 | \code{\link{dfi_volume}()}, 62 | \code{\link{dfi_workdir}()} 63 | } 64 | \concept{dockerfile instruction functions} 65 | -------------------------------------------------------------------------------- /man/dfi_onbuild.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_onbuild} 4 | \alias{dfi_onbuild} 5 | \title{Add an \code{ONBUILD} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_onbuild(dockerfile, instruction) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{instruction}{Instruction to run on build (without the instruction name)} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{ONBUILD} instruction added 16 | } 17 | \description{ 18 | Adds an \code{ONBUILD} instruction to register trigger instructions to be 19 | executed later, when the image is used as the base for another build. 20 | } 21 | \details{ 22 | The \code{ONBUILD} instruction registers a trigger instruction that will be 23 | executed when the image is used as the base for another build. The trigger 24 | is executed in the context of the downstream build, as if it had been 25 | inserted immediately after the \code{FROM} instruction in the downstream \strong{Dockerfile}. 26 | 27 | This is useful for creating "builder" images that can set up a common build 28 | environment for applications. 29 | 30 | Note: \code{ONBUILD} instructions are not inherited by "grand-children" builds. 31 | } 32 | \examples{ 33 | # Add ONBUILD triggers for package installation 34 | df <- dockerfile() |> 35 | dfi_from("rocker/r-ver:4.4.0") |> 36 | dfi_onbuild("COPY renv.lock /app/renv.lock") |> 37 | dfi_onbuild("RUN R -e \"renv::restore()\"") 38 | df 39 | 40 | } 41 | \seealso{ 42 | \code{\link[=dfi_from]{dfi_from()}} for specifying the base image & 43 | \href{https://docs.docker.com/engine/reference/builder/#onbuild}{Official Docker \code{ONBUILD} documentation} 44 | 45 | Other dockerfile instruction functions: 46 | \code{\link{dfi_add}()}, 47 | \code{\link{dfi_arg}()}, 48 | \code{\link{dfi_cmd}()}, 49 | \code{\link{dfi_copy}()}, 50 | \code{\link{dfi_entrypoint}()}, 51 | \code{\link{dfi_env}()}, 52 | \code{\link{dfi_expose}()}, 53 | \code{\link{dfi_from}()}, 54 | \code{\link{dfi_healthcheck}()}, 55 | \code{\link{dfi_label}()}, 56 | \code{\link{dfi_maintainer}()}, 57 | \code{\link{dfi_run}()}, 58 | \code{\link{dfi_shell}()}, 59 | \code{\link{dfi_stopsignal}()}, 60 | \code{\link{dfi_user}()}, 61 | \code{\link{dfi_volume}()}, 62 | \code{\link{dfi_workdir}()} 63 | } 64 | \concept{dockerfile instruction functions} 65 | -------------------------------------------------------------------------------- /man/dfi_run.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_run} 4 | \alias{dfi_run} 5 | \title{Add a \code{RUN} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_run(dockerfile, commands) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{commands}{Commands to run (character vector for multiple commands)} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{RUN} instruction added 16 | } 17 | \description{ 18 | Adds a \code{RUN} instruction to execute commands in a new layer on top of the 19 | current image and commit the results. 20 | } 21 | \details{ 22 | When providing multiple commands as a character vector, they will be 23 | properly formatted with line continuations in the \strong{Dockerfile}. 24 | This is the recommended approach for package installations to reduce 25 | the number of layers in the final image. 26 | } 27 | \examples{ 28 | # Single command 29 | df <- dockerfile() |> 30 | dfi_from("rocker/r-ver:4.4.0") |> 31 | dfi_run("apt update") 32 | df 33 | 34 | # Multiple commands in a single RUN (better practice) 35 | df <- dockerfile() |> 36 | dfi_from("rocker/r-ver:4.4.0") |> 37 | dfi_run(c( 38 | "apt update", 39 | "apt install -y --no-install-recommends libcurl4-openssl-dev", 40 | "apt clean", 41 | "rm -rf /var/lib/apt/lists/*" 42 | )) 43 | 44 | } 45 | \seealso{ 46 | \code{\link[=dfi_from]{dfi_from()}} for setting the base image, 47 | \code{\link[=dfi_cmd]{dfi_cmd()}} for specifying the default command to run, & 48 | \href{https://docs.docker.com/engine/reference/builder/#run}{Official Docker \code{RUN} documentation} 49 | 50 | Other dockerfile instruction functions: 51 | \code{\link{dfi_add}()}, 52 | \code{\link{dfi_arg}()}, 53 | \code{\link{dfi_cmd}()}, 54 | \code{\link{dfi_copy}()}, 55 | \code{\link{dfi_entrypoint}()}, 56 | \code{\link{dfi_env}()}, 57 | \code{\link{dfi_expose}()}, 58 | \code{\link{dfi_from}()}, 59 | \code{\link{dfi_healthcheck}()}, 60 | \code{\link{dfi_label}()}, 61 | \code{\link{dfi_maintainer}()}, 62 | \code{\link{dfi_onbuild}()}, 63 | \code{\link{dfi_shell}()}, 64 | \code{\link{dfi_stopsignal}()}, 65 | \code{\link{dfi_user}()}, 66 | \code{\link{dfi_volume}()}, 67 | \code{\link{dfi_workdir}()} 68 | } 69 | \concept{dockerfile instruction functions} 70 | -------------------------------------------------------------------------------- /man/dfi_shell.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_shell} 4 | \alias{dfi_shell} 5 | \title{Add a \code{SHELL} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_shell(dockerfile, shell) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{shell}{Shell command and parameters (character vector or string)} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{SHELL} instruction added 16 | } 17 | \description{ 18 | Adds a \code{SHELL} instruction to override the default shell used for commands. 19 | } 20 | \details{ 21 | The \code{SHELL} instruction allows overriding the default shell used for the 22 | shell form of commands. The default shell on Linux is \verb{["/bin/sh", "-c"]}, 23 | and on Windows is \verb{["cmd", "/S", "/C"]}. 24 | 25 | This instruction is particularly useful for: 26 | \itemize{ 27 | \item Using bash-specific features 28 | \item Enabling better error handling with options like \code{-e} (exit on error) 29 | \item Setting up pipefail to catch errors in pipelines 30 | } 31 | 32 | The function automatically converts the shell command to JSON array format 33 | if provided as a vector. 34 | } 35 | \examples{ 36 | # Set shell to bash with expanded error messaging 37 | df <- dockerfile() |> 38 | dfi_from("rocker/r-ver:4.4.0") |> 39 | dfi_shell(c("/bin/bash", "-e", "-o", "pipefail", "-c")) 40 | df 41 | 42 | } 43 | \seealso{ 44 | \code{\link[=dfi_run]{dfi_run()}} for executing commands with the shell & 45 | \href{https://docs.docker.com/engine/reference/builder/#shell}{Official Docker \code{SHELL} documentation} 46 | 47 | Other dockerfile instruction functions: 48 | \code{\link{dfi_add}()}, 49 | \code{\link{dfi_arg}()}, 50 | \code{\link{dfi_cmd}()}, 51 | \code{\link{dfi_copy}()}, 52 | \code{\link{dfi_entrypoint}()}, 53 | \code{\link{dfi_env}()}, 54 | \code{\link{dfi_expose}()}, 55 | \code{\link{dfi_from}()}, 56 | \code{\link{dfi_healthcheck}()}, 57 | \code{\link{dfi_label}()}, 58 | \code{\link{dfi_maintainer}()}, 59 | \code{\link{dfi_onbuild}()}, 60 | \code{\link{dfi_run}()}, 61 | \code{\link{dfi_stopsignal}()}, 62 | \code{\link{dfi_user}()}, 63 | \code{\link{dfi_volume}()}, 64 | \code{\link{dfi_workdir}()} 65 | } 66 | \concept{dockerfile instruction functions} 67 | -------------------------------------------------------------------------------- /man/dfi_stopsignal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_stopsignal} 4 | \alias{dfi_stopsignal} 5 | \title{Add a \code{STOPSIGNAL} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_stopsignal(dockerfile, signal) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{signal}{Signal for stopping container (e.g., "SIGTERM", "9")} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{STOPSIGNAL} instruction added 16 | } 17 | \description{ 18 | Adds a \code{STOPSIGNAL} instruction to set the system call signal that will be 19 | sent to the container to exit. 20 | } 21 | \details{ 22 | The \code{STOPSIGNAL} instruction sets the system call signal that will be sent to 23 | the container to request it to exit. The signal can be specified as a signal name 24 | in the format \code{SIGNAME} (e.g., \code{SIGTERM}), or as an unsigned number (e.g., \code{15}). 25 | 26 | By default, Docker sends \code{SIGTERM} to containers when they need to be stopped. 27 | If the container doesn't exit within the timeout period (default 10 seconds), 28 | Docker sends \code{SIGKILL} to forcibly terminate it. 29 | } 30 | \examples{ 31 | # Set SIGTERM as the stop signal 32 | df <- dockerfile() |> 33 | dfi_from("rocker/r-ver:4.4.0") |> 34 | dfi_stopsignal("SIGTERM") 35 | df 36 | 37 | # Set using signal number 38 | df <- dockerfile() |> 39 | dfi_from("rocker/r-ver:4.4.0") |> 40 | dfi_stopsignal("15") 41 | df 42 | 43 | } 44 | \seealso{ 45 | \code{\link[=dfi_healthcheck]{dfi_healthcheck()}} for configuring container health checks & 46 | \href{https://docs.docker.com/engine/reference/builder/#stopsignal}{Official Docker \code{STOPSIGNAL} documentation} 47 | 48 | Other dockerfile instruction functions: 49 | \code{\link{dfi_add}()}, 50 | \code{\link{dfi_arg}()}, 51 | \code{\link{dfi_cmd}()}, 52 | \code{\link{dfi_copy}()}, 53 | \code{\link{dfi_entrypoint}()}, 54 | \code{\link{dfi_env}()}, 55 | \code{\link{dfi_expose}()}, 56 | \code{\link{dfi_from}()}, 57 | \code{\link{dfi_healthcheck}()}, 58 | \code{\link{dfi_label}()}, 59 | \code{\link{dfi_maintainer}()}, 60 | \code{\link{dfi_onbuild}()}, 61 | \code{\link{dfi_run}()}, 62 | \code{\link{dfi_shell}()}, 63 | \code{\link{dfi_user}()}, 64 | \code{\link{dfi_volume}()}, 65 | \code{\link{dfi_workdir}()} 66 | } 67 | \concept{dockerfile instruction functions} 68 | -------------------------------------------------------------------------------- /man/dfi_user.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_user} 4 | \alias{dfi_user} 5 | \title{Add a \code{USER} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_user(dockerfile, user, group = NULL) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{user}{Username or UID} 13 | 14 | \item{group}{Group or GID (optional)} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with the USER instruction added 18 | } 19 | \description{ 20 | Adds a \code{USER} instruction to set the user or UID to use when running 21 | subsequent instructions and the default user for the container. 22 | } 23 | \details{ 24 | The \code{USER} instruction sets the user and optionally the user group for 25 | subsequent instructions in the \strong{Dockerfile}, and as the default user for 26 | running the container. This is important for security, as it's a best 27 | practice to run containers with non-root users when possible. 28 | 29 | If the user specified does not exist in the container, you'll need to create 30 | it first using a \code{RUN} instruction. 31 | } 32 | \examples{ 33 | # Set user by name 34 | df <- dockerfile() |> 35 | dfi_from("rocker/r-ver:4.4.0") |> 36 | dfi_user("r-user") 37 | df 38 | 39 | # Set user and group by ID 40 | df <- dockerfile() |> 41 | dfi_from("rocker/r-ver:4.4.0") |> 42 | dfi_user(1000, 1000) 43 | df 44 | 45 | } 46 | \seealso{ 47 | \code{\link[=dfi_run]{dfi_run()}} for creating users & 48 | \href{https://docs.docker.com/engine/reference/builder/#user}{Official Docker \code{USER} documentation} 49 | 50 | Other dockerfile instruction functions: 51 | \code{\link{dfi_add}()}, 52 | \code{\link{dfi_arg}()}, 53 | \code{\link{dfi_cmd}()}, 54 | \code{\link{dfi_copy}()}, 55 | \code{\link{dfi_entrypoint}()}, 56 | \code{\link{dfi_env}()}, 57 | \code{\link{dfi_expose}()}, 58 | \code{\link{dfi_from}()}, 59 | \code{\link{dfi_healthcheck}()}, 60 | \code{\link{dfi_label}()}, 61 | \code{\link{dfi_maintainer}()}, 62 | \code{\link{dfi_onbuild}()}, 63 | \code{\link{dfi_run}()}, 64 | \code{\link{dfi_shell}()}, 65 | \code{\link{dfi_stopsignal}()}, 66 | \code{\link{dfi_volume}()}, 67 | \code{\link{dfi_workdir}()} 68 | } 69 | \concept{dockerfile instruction functions} 70 | -------------------------------------------------------------------------------- /man/dfi_volume.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_volume} 4 | \alias{dfi_volume} 5 | \title{Add a \code{VOLUME} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_volume(dockerfile, paths) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{paths}{Path(s) to create as volumes} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{VOLUME} instruction added 16 | } 17 | \description{ 18 | Adds a \code{VOLUME} instruction to create a mount point with the specified name 19 | and mark it as holding externally mounted volumes. 20 | } 21 | \details{ 22 | The \code{VOLUME} instruction creates a mount point and marks it as being externally 23 | mounted. This is useful for: 24 | \itemize{ 25 | \item Persistent data that should survive container restarts 26 | \item Data you want to share between containers 27 | \item Data you want to access from the host 28 | } 29 | 30 | Note that the actual binding of host directories happens at runtime using the 31 | \code{-v} flag with \verb{docker run}, not during the image build. 32 | } 33 | \examples{ 34 | # Create a single volume 35 | df <- dockerfile() |> 36 | dfi_from("rocker/r-ver:4.4.0") |> 37 | dfi_volume("/data") 38 | df 39 | 40 | # Create multiple volumes 41 | df <- dockerfile() |> 42 | dfi_from("rocker/r-ver:4.4.0") |> 43 | dfi_volume(c("/data", "/output", "/config")) 44 | df 45 | 46 | } 47 | \seealso{ 48 | \code{\link[=dk_template_base]{dk_template_base()}} for a template that sets up common volume patterns & 49 | \href{https://docs.docker.com/engine/reference/builder/#volume}{Official Docker \code{VOLUME} documentation} 50 | 51 | Other dockerfile instruction functions: 52 | \code{\link{dfi_add}()}, 53 | \code{\link{dfi_arg}()}, 54 | \code{\link{dfi_cmd}()}, 55 | \code{\link{dfi_copy}()}, 56 | \code{\link{dfi_entrypoint}()}, 57 | \code{\link{dfi_env}()}, 58 | \code{\link{dfi_expose}()}, 59 | \code{\link{dfi_from}()}, 60 | \code{\link{dfi_healthcheck}()}, 61 | \code{\link{dfi_label}()}, 62 | \code{\link{dfi_maintainer}()}, 63 | \code{\link{dfi_onbuild}()}, 64 | \code{\link{dfi_run}()}, 65 | \code{\link{dfi_shell}()}, 66 | \code{\link{dfi_stopsignal}()}, 67 | \code{\link{dfi_user}()}, 68 | \code{\link{dfi_workdir}()} 69 | } 70 | \concept{dockerfile instruction functions} 71 | -------------------------------------------------------------------------------- /man/dfi_workdir.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-instructions.R 3 | \name{dfi_workdir} 4 | \alias{dfi_workdir} 5 | \title{Add a \code{WORKDIR} instruction to a \code{dockerfile}} 6 | \usage{ 7 | dfi_workdir(dockerfile, path) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{path}{Working directory path in the container} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the \code{WORKDIR} instruction added 16 | } 17 | \description{ 18 | Adds a \code{WORKDIR} instruction to set the working directory for any subsequent 19 | \code{RUN}, \code{CMD}, \code{ENTRYPOINT}, \code{COPY}, and \code{ADD} instructions. 20 | } 21 | \details{ 22 | The \code{WORKDIR} instruction can be used multiple times in a \strong{Dockerfile}. 23 | If a relative path is provided, it will be relative to the previous 24 | \code{WORKDIR} instruction. If the directory doesn't exist, it will be created. 25 | } 26 | \examples{ 27 | df <- dockerfile() |> 28 | dfi_from("rocker/r-ver:4.4.0") |> 29 | dfi_workdir("/app") |> 30 | dfi_copy(".", "/app/") 31 | 32 | } 33 | \seealso{ 34 | \code{\link[=dfi_copy]{dfi_copy()}} for copying files into the container, 35 | \code{\link[=dfi_run]{dfi_run()}} for executing commands in the working directory, & 36 | \href{https://docs.docker.com/engine/reference/builder/#workdir}{Official Docker \code{WORKDIR} documentation} 37 | 38 | Other dockerfile instruction functions: 39 | \code{\link{dfi_add}()}, 40 | \code{\link{dfi_arg}()}, 41 | \code{\link{dfi_cmd}()}, 42 | \code{\link{dfi_copy}()}, 43 | \code{\link{dfi_entrypoint}()}, 44 | \code{\link{dfi_env}()}, 45 | \code{\link{dfi_expose}()}, 46 | \code{\link{dfi_from}()}, 47 | \code{\link{dfi_healthcheck}()}, 48 | \code{\link{dfi_label}()}, 49 | \code{\link{dfi_maintainer}()}, 50 | \code{\link{dfi_onbuild}()}, 51 | \code{\link{dfi_run}()}, 52 | \code{\link{dfi_shell}()}, 53 | \code{\link{dfi_stopsignal}()}, 54 | \code{\link{dfi_user}()}, 55 | \code{\link{dfi_volume}()} 56 | } 57 | \concept{dockerfile instruction functions} 58 | -------------------------------------------------------------------------------- /man/dfm_add_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-modifications.R 3 | \name{dfm_add_line} 4 | \alias{dfm_add_line} 5 | \title{Add a line to a \code{dockerfile} at a specific position} 6 | \usage{ 7 | dfm_add_line(dockerfile, line, after = NULL) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{line}{Line to add (raw text)} 13 | 14 | \item{after}{Position after which to add the line (default: end of file)} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with the new line added 18 | } 19 | \description{ 20 | Adds a raw line to a `dockerfile`` at a specified position. This is a lower-level 21 | function typically used internally by higher-level functions. 22 | } 23 | \details{ 24 | Unlike the instruction-specific functions (\verb{dfi_*}), this function adds 25 | raw text without any formatting or validation. It's useful for adding 26 | comments or custom instructions not covered by the built-in functions. 27 | } 28 | \examples{ 29 | df <- dockerfile() |> 30 | dfi_from("rocker/r-ver:4.4.0") 31 | 32 | # Add a comment after the FROM instruction 33 | df <- dfm_add_line(df, "# This is a comment", after = 1) 34 | 35 | } 36 | \seealso{ 37 | \code{\link[=dfm_remove_line]{dfm_remove_line()}} for removing a line & 38 | \code{\link[=dfm_replace_line]{dfm_replace_line()}} for replacing a line 39 | 40 | Other dockerfile modification functions: 41 | \code{\link{dfm_group_similar}()}, 42 | \code{\link{dfm_move_line}()}, 43 | \code{\link{dfm_remove_line}()}, 44 | \code{\link{dfm_replace_line}()}, 45 | \code{\link{dfm_sort_by_instruction}()} 46 | } 47 | \concept{dockerfile modification functions} 48 | -------------------------------------------------------------------------------- /man/dfm_group_similar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-modifications.R 3 | \name{dfm_group_similar} 4 | \alias{dfm_group_similar} 5 | \title{Group similar instructions in a \code{dockerfile}} 6 | \usage{ 7 | dfm_group_similar(dockerfile) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | } 12 | \value{ 13 | A new \code{dockerfile} object with similar instructions grouped 14 | } 15 | \description{ 16 | Optimizes a \code{dockerfile} by grouping similar consecutive instructions 17 | into single multi-command instructions where appropriate. This can reduce 18 | the number of layers in the final Docker image. 19 | } 20 | \details{ 21 | This function primarily targets \code{RUN} instructions, combining them with \code{&&} 22 | to create single multi-command instructions. This follows Docker best practices 23 | by reducing the number of layers in the final image. Instructions like \code{FROM}, 24 | \code{WORKDIR}, \code{USER}, \code{ENTRYPOINT}, and \code{CMD} are left as separate instructions. 25 | } 26 | \examples{ 27 | df <- dockerfile() |> 28 | dfi_from("rocker/r-ver:4.4.0") |> 29 | dfi_run("apt-get update") |> 30 | dfi_run("apt-get install -y curl") |> 31 | dfi_run("apt-get clean") 32 | 33 | # Group the three RUN instructions into one 34 | df <- dfm_group_similar(df) 35 | 36 | } 37 | \seealso{ 38 | \code{\link[=dfm_sort_by_instruction]{dfm_sort_by_instruction()}} for sorting instructions by type 39 | 40 | Other dockerfile modification functions: 41 | \code{\link{dfm_add_line}()}, 42 | \code{\link{dfm_move_line}()}, 43 | \code{\link{dfm_remove_line}()}, 44 | \code{\link{dfm_replace_line}()}, 45 | \code{\link{dfm_sort_by_instruction}()} 46 | } 47 | \concept{dockerfile modification functions} 48 | -------------------------------------------------------------------------------- /man/dfm_move_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-modifications.R 3 | \name{dfm_move_line} 4 | \alias{dfm_move_line} 5 | \title{Move a line in a \code{dockerfile}} 6 | \usage{ 7 | dfm_move_line(dockerfile, from, to) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{from}{Source line number} 13 | 14 | \item{to}{Target position} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with the line moved to the new position 18 | } 19 | \description{ 20 | Moves a line from one position to another in a \code{dockerfile}. 21 | } 22 | \details{ 23 | This function allows for reorganizing instructions in a \strong{Dockerfile} by moving 24 | lines to different positions. It's useful for correcting the order of 25 | instructions without having to recreate the entire \strong{Dockerfile}. 26 | 27 | Note that moving certain instructions to incompatible positions can make 28 | the \strong{Dockerfile} invalid (e.g., moving a \code{FROM} instruction after a \code{RUN}). 29 | Consider using \code{\link[=dfm_sort_by_instruction]{dfm_sort_by_instruction()}} to follow Docker best practices. 30 | } 31 | \examples{ 32 | df <- dockerfile() |> 33 | dfi_from("rocker/r-ver:4.4.0") |> 34 | dfi_workdir("/app") |> 35 | dfi_run("apt-get update") |> 36 | dfi_copy(".", "/app/") 37 | 38 | df 39 | 40 | # Move the RUN instruction to be after COPY 41 | df <- dfm_move_line(df, 3, 4) 42 | df 43 | 44 | } 45 | \seealso{ 46 | \code{\link[=dfm_add_line]{dfm_add_line()}} for adding a line, 47 | \code{\link[=dfm_remove_line]{dfm_remove_line()}} for removing a line, & 48 | \code{\link[=dfm_sort_by_instruction]{dfm_sort_by_instruction()}} for sorting instructions by type 49 | 50 | Other dockerfile modification functions: 51 | \code{\link{dfm_add_line}()}, 52 | \code{\link{dfm_group_similar}()}, 53 | \code{\link{dfm_remove_line}()}, 54 | \code{\link{dfm_replace_line}()}, 55 | \code{\link{dfm_sort_by_instruction}()} 56 | } 57 | \concept{dockerfile modification functions} 58 | -------------------------------------------------------------------------------- /man/dfm_remove_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-modifications.R 3 | \name{dfm_remove_line} 4 | \alias{dfm_remove_line} 5 | \title{Remove a line from a \code{dockerfile}} 6 | \usage{ 7 | dfm_remove_line(dockerfile, line_num) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{line_num}{Line number to remove} 13 | } 14 | \value{ 15 | An updated \code{dockerfile} object with the specified line removed 16 | } 17 | \description{ 18 | Removes a line at the specified position from a \code{dockerfile}. 19 | } 20 | \examples{ 21 | df <- dockerfile() |> 22 | dfi_from("rocker/r-ver:4.4.0") |> 23 | dfi_run("apt-get update") |> 24 | dfi_run("apt-get install -y libcurl4-openssl-dev") 25 | 26 | # Remove the second RUN instruction (line 3) 27 | df <- dfm_remove_line(df, 3) 28 | 29 | } 30 | \seealso{ 31 | \code{\link[=dfm_add_line]{dfm_add_line()}} for adding a line & 32 | \code{\link[=dfm_replace_line]{dfm_replace_line()}} for replacing a line 33 | 34 | Other dockerfile modification functions: 35 | \code{\link{dfm_add_line}()}, 36 | \code{\link{dfm_group_similar}()}, 37 | \code{\link{dfm_move_line}()}, 38 | \code{\link{dfm_replace_line}()}, 39 | \code{\link{dfm_sort_by_instruction}()} 40 | } 41 | \concept{dockerfile modification functions} 42 | -------------------------------------------------------------------------------- /man/dfm_replace_line.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-modifications.R 3 | \name{dfm_replace_line} 4 | \alias{dfm_replace_line} 5 | \title{Replace a line in a \code{dockerfile}} 6 | \usage{ 7 | dfm_replace_line(dockerfile, line_num, new_line) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{line_num}{Line number to replace} 13 | 14 | \item{new_line}{New line content} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with the specified line replaced 18 | } 19 | \description{ 20 | Replaces a line at the specified position with new content. 21 | } 22 | \examples{ 23 | df <- dockerfile() |> 24 | dfi_from("rocker/r-ver:4.4.0") |> 25 | dfi_run("apt-get update") 26 | 27 | # Replace the RUN instruction with a more comprehensive one 28 | df <- dfm_replace_line(df, 2, 29 | "RUN apt-get update && apt-get install -y libcurl4-openssl-dev && apt-get clean") 30 | 31 | } 32 | \seealso{ 33 | \code{\link[=dfm_add_line]{dfm_add_line()}} for adding a line & 34 | \code{\link[=dfm_remove_line]{dfm_remove_line()}} for removing a line 35 | 36 | Other dockerfile modification functions: 37 | \code{\link{dfm_add_line}()}, 38 | \code{\link{dfm_group_similar}()}, 39 | \code{\link{dfm_move_line}()}, 40 | \code{\link{dfm_remove_line}()}, 41 | \code{\link{dfm_sort_by_instruction}()} 42 | } 43 | \concept{dockerfile modification functions} 44 | -------------------------------------------------------------------------------- /man/dfm_sort_by_instruction.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-modifications.R 3 | \name{dfm_sort_by_instruction} 4 | \alias{dfm_sort_by_instruction} 5 | \title{Sort instructions in a \code{dockerfile} by type} 6 | \usage{ 7 | dfm_sort_by_instruction(dockerfile, order = NULL) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{order}{Custom order for instructions (optional)} 13 | } 14 | \value{ 15 | A new \code{dockerfile} object with instructions sorted by type 16 | } 17 | \description{ 18 | Reorders the instructions in a \code{dockerfile} according to Docker best practices 19 | or a custom order specification. 20 | } 21 | \details{ 22 | The default order follows Docker best practices, with instructions that change 23 | less frequently appearing first (e.g., \code{FROM}, \code{ARG}, \code{LABEL}), and instructions 24 | that change more frequently appearing later (e.g., \code{COPY}, \code{RUN}). This improves 25 | caching and build performance. 26 | } 27 | \examples{ 28 | df <- dockerfile() |> 29 | dfi_cmd("R --no-save") |> 30 | dfi_run("apt-get update") |> 31 | dfi_from("rocker/r-ver:4.4.0") 32 | 33 | # Sort according to best practices (FROM first, etc.) 34 | df <- dfm_sort_by_instruction(df) 35 | 36 | # Use a custom order 37 | df <- dfm_sort_by_instruction(df, 38 | order = c("FROM", "RUN", "WORKDIR", "CMD")) 39 | 40 | } 41 | \seealso{ 42 | \code{\link[=dfm_group_similar]{dfm_group_similar()}} for grouping similar instructions 43 | 44 | Other dockerfile modification functions: 45 | \code{\link{dfm_add_line}()}, 46 | \code{\link{dfm_group_similar}()}, 47 | \code{\link{dfm_move_line}()}, 48 | \code{\link{dfm_remove_line}()}, 49 | \code{\link{dfm_replace_line}()} 50 | } 51 | \concept{dockerfile modification functions} 52 | -------------------------------------------------------------------------------- /man/di_add.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-instructions.R 3 | \name{di_add} 4 | \alias{di_add} 5 | \title{Add patterns to a dockerignore object} 6 | \usage{ 7 | di_add(dockerignore, pattern) 8 | } 9 | \arguments{ 10 | \item{dockerignore}{A \code{dockerignore} object} 11 | 12 | \item{pattern}{Character vector of patterns to add} 13 | } 14 | \value{ 15 | An updated \code{dockerignore} object with the new patterns added 16 | } 17 | \description{ 18 | Adds one or more patterns to a \code{dockerignore} object, avoiding duplicates. 19 | } 20 | \details{ 21 | Patterns follow the same syntax as \code{.gitignore} files: 22 | \itemize{ 23 | \item Lines starting with \verb{#} are comments 24 | \item Blank lines are ignored 25 | \item Trailing slashes \code{/} specify directories 26 | \item Patterns with special characters like \code{*}, \verb{?}, and \verb{[]} use glob syntax 27 | \item Lines starting with \code{!} negate a pattern (include a file that would otherwise be ignored) 28 | } 29 | } 30 | \examples{ 31 | di <- dockerignore() 32 | 33 | # Add a single pattern 34 | di <- di_add(di, ".git/") 35 | 36 | # Add multiple patterns 37 | di <- di_add(di, c("*.log", "node_modules/", "*.tmp")) 38 | 39 | } 40 | \seealso{ 41 | \code{\link[=di_remove]{di_remove()}} for removing patterns & 42 | \code{\link[=di_replace]{di_replace()}} for replacing patterns 43 | 44 | Other dockerignore instruction functions: 45 | \code{\link{di_remove}()}, 46 | \code{\link{di_replace}()} 47 | } 48 | \concept{dockerignore instruction functions} 49 | -------------------------------------------------------------------------------- /man/di_remove.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-instructions.R 3 | \name{di_remove} 4 | \alias{di_remove} 5 | \title{Remove patterns from a \code{dockerignore} object} 6 | \usage{ 7 | di_remove(dockerignore, pattern) 8 | } 9 | \arguments{ 10 | \item{dockerignore}{A \code{dockerignore} object} 11 | 12 | \item{pattern}{Character vector of patterns to remove} 13 | } 14 | \value{ 15 | An updated \code{dockerignore} object with the specified patterns removed 16 | } 17 | \description{ 18 | Removes one or more patterns from a \code{dockerignore} object. 19 | } 20 | \examples{ 21 | # Create a dockerignore object and add some patterns 22 | di <- dockerignore() |> 23 | di_add(c(".git/", "*.log", "node_modules/")) 24 | 25 | # Remove a pattern 26 | di <- di_remove(di, "*.log") 27 | 28 | } 29 | \seealso{ 30 | \code{\link[=di_add]{di_add()}} for adding patterns & 31 | \code{\link[=di_replace]{di_replace()}} for replacing patterns 32 | 33 | Other dockerignore instruction functions: 34 | \code{\link{di_add}()}, 35 | \code{\link{di_replace}()} 36 | } 37 | \concept{dockerignore instruction functions} 38 | -------------------------------------------------------------------------------- /man/di_replace.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-instructions.R 3 | \name{di_replace} 4 | \alias{di_replace} 5 | \title{Replace patterns in a dockerignore object} 6 | \usage{ 7 | di_replace(dockerignore, old_pattern, new_pattern) 8 | } 9 | \arguments{ 10 | \item{dockerignore}{A \code{dockerignore} object} 11 | 12 | \item{old_pattern}{Pattern(s) to replace} 13 | 14 | \item{new_pattern}{New pattern(s)} 15 | } 16 | \value{ 17 | An updated \code{dockerignore} object with the specified patterns replaced 18 | } 19 | \description{ 20 | Replaces one or more patterns in a dockerignore object with new patterns. 21 | } 22 | \details{ 23 | This function allows you to replace patterns in a dockerignore object. 24 | Three modes of operation are supported: 25 | \enumerate{ 26 | \item Replace a single pattern with a single pattern 27 | \item Replace multiple patterns with a single pattern 28 | \item Replace multiple patterns with corresponding new patterns (one-to-one) 29 | } 30 | 31 | For the third mode, \code{old_pattern} and \code{new_pattern} must have the same length. 32 | } 33 | \examples{ 34 | # Create a dockerignore object and add some patterns 35 | di <- dockerignore() |> 36 | di_add(c("*.log", "*.tmp", "node_modules/")) 37 | 38 | # Replace a single pattern 39 | di <- di_replace(di, "*.log", "logs/") 40 | 41 | # Replace multiple patterns with a single pattern 42 | di <- di_replace(di, c("*.tmp", "node_modules/"), "temp/") 43 | 44 | # Replace patterns one-to-one 45 | di <- di_replace(di, 46 | c("*.log", "*.tmp"), 47 | c("logs/*", "temp/*")) 48 | 49 | } 50 | \seealso{ 51 | \code{\link[=di_add]{di_add()}} for adding patterns & 52 | \code{\link[=di_remove]{di_remove()}} for removing patterns 53 | 54 | Other dockerignore instruction functions: 55 | \code{\link{di_add}()}, 56 | \code{\link{di_remove}()} 57 | } 58 | \concept{dockerignore instruction functions} 59 | -------------------------------------------------------------------------------- /man/dk_add_sysreqs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{dk_add_sysreqs} 4 | \alias{dk_add_sysreqs} 5 | \title{Add system requirements for R packages to a \code{dockerfile}} 6 | \usage{ 7 | dk_add_sysreqs(dockerfile, packages, package_manager = "auto") 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{packages}{Character vector of package names} 13 | 14 | \item{package_manager}{Package manager to use (default: \code{"auto"})} 15 | } 16 | \value{ 17 | An updated \code{dockerfile} object with system requirements added 18 | } 19 | \description{ 20 | Identifies and adds the necessary system requirements for R packages 21 | to a \code{dockerfile} using the \code{pak} package to determine dependencies. 22 | } 23 | \details{ 24 | This function uses the pak package to determine the system requirements 25 | for the specified R packages. It then formats the appropriate installation 26 | commands for the detected package manager and adds them as \code{RUN} instructions 27 | to the \code{dockerfile}. 28 | 29 | The \code{pak} package must be installed for this function to work. 30 | } 31 | \examples{ 32 | \dontrun{ 33 | # Create a dockerfile 34 | df <- dockerfile() |> 35 | dfi_from("rocker/r-ver:4.4.0") 36 | 37 | # Add system requirements for packages 38 | df <- dk_add_sysreqs(df, c("xml2", "RPostgreSQL", "rJava")) 39 | } 40 | 41 | } 42 | \seealso{ 43 | \code{\link[=generate_pkg_install_cmd]{generate_pkg_install_cmd()}} for generating package installation commands & 44 | \code{\link[=determine_package_manager]{determine_package_manager()}} for determining the package manager 45 | 46 | Other utility functions: 47 | \code{\link{determine_linux_distribution}()}, 48 | \code{\link{determine_package_manager}()}, 49 | \code{\link{map_to_sysreqs_platform}()} 50 | } 51 | \concept{utility functions} 52 | -------------------------------------------------------------------------------- /man/dk_from_description.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-from-environment.R 3 | \name{dk_from_description} 4 | \alias{dk_from_description} 5 | \title{Create a \code{dockerfile} from a \strong{DESCRIPTION} file} 6 | \usage{ 7 | dk_from_description( 8 | description_file = "DESCRIPTION", 9 | r_version = NULL, 10 | base_image = NULL, 11 | include_sysreqs = TRUE 12 | ) 13 | } 14 | \arguments{ 15 | \item{description_file}{Path to \strong{DESCRIPTION} file} 16 | 17 | \item{r_version}{R version to use (default: from DESCRIPTION)} 18 | 19 | \item{base_image}{Base image to use (default: determined from R version)} 20 | 21 | \item{include_sysreqs}{Include system requirements (default: TRUE)} 22 | } 23 | \value{ 24 | A \code{dockerfile} object configured based on the DESCRIPTION file 25 | } 26 | \description{ 27 | Generates a `dockerfile`` based on a package \strong{DESCRIPTION} file, ensuring all 28 | package dependencies are installed in the container. 29 | } 30 | \details{ 31 | This function: 32 | \itemize{ 33 | \item Extracts the R version from the \strong{DESCRIPTION}'s \code{Depends} field (if available) 34 | \item Uses the appropriate \code{rocker/r-ver} base image 35 | \item Extracts package dependencies from \code{Depends}, \code{Imports}, and \code{Suggests} fields 36 | \item Adds system requirements for those packages 37 | \item Sets up the package installation 38 | } 39 | 40 | The resulting \code{dockerfile} will install all the dependencies required by 41 | your package and then install the package itself from the source. 42 | } 43 | \examples{ 44 | \dontrun{ 45 | # Create a dockerfile from a DESCRIPTION file 46 | df <- dk_from_description("DESCRIPTION") 47 | } 48 | 49 | } 50 | \seealso{ 51 | \code{\link[=dk_from_session]{dk_from_session()}} for creating from the current session, 52 | \code{\link[=dk_from_renv]{dk_from_renv()}} for creating from renv.lock files, & 53 | \code{\link[=dk_add_sysreqs]{dk_add_sysreqs()}} for adding system requirements 54 | 55 | Other dockerfile from environment functions: 56 | \code{\link{dk_from_renv}()}, 57 | \code{\link{dk_from_script}()}, 58 | \code{\link{dk_from_session}()} 59 | } 60 | \concept{dockerfile from environment functions} 61 | -------------------------------------------------------------------------------- /man/dk_from_renv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-from-environment.R 3 | \name{dk_from_renv} 4 | \alias{dk_from_renv} 5 | \title{Create a \code{dockerfile} from an \strong{renv.lock} file} 6 | \usage{ 7 | dk_from_renv( 8 | lock_file = "renv.lock", 9 | r_version = NULL, 10 | base_image = NULL, 11 | include_sysreqs = TRUE 12 | ) 13 | } 14 | \arguments{ 15 | \item{lock_file}{Path to \strong{renv.lock} file} 16 | 17 | \item{r_version}{R version to use (default: from lock file)} 18 | 19 | \item{base_image}{Base image to use (default: determined from R version)} 20 | 21 | \item{include_sysreqs}{Include system requirements (default: \code{TRUE})} 22 | } 23 | \value{ 24 | A \code{dockerfile} object configured based on the renv.lock file 25 | } 26 | \description{ 27 | Generates a \code{dockerfile} based on an \strong{renv.lock} file, ensuring reproducible 28 | package dependencies in the container. 29 | } 30 | \details{ 31 | This function: 32 | \itemize{ 33 | \item Extracts the R version from the lock file (if available) 34 | \item Uses the appropriate rocker/r-ver base image 35 | \item Adds system requirements for the packages in the lock file 36 | \item Sets up renv and restores the packages from the lock file 37 | } 38 | 39 | The resulting dockerfile will recreate the exact environment specified 40 | in your renv.lock file, ensuring reproducible results. 41 | } 42 | \examples{ 43 | \dontrun{ 44 | # Create a dockerfile from an renv.lock file 45 | df <- dk_from_renv("renv.lock") 46 | 47 | # Specify a different R version 48 | df <- dk_from_renv("renv.lock", r_version = "4.4.0") 49 | } 50 | 51 | } 52 | \seealso{ 53 | \code{\link[=dk_from_session]{dk_from_session()}} for creating from the current session, 54 | \code{\link[=dk_from_description]{dk_from_description()}} for creating from DESCRIPTION files, & 55 | \code{\link[=dk_add_sysreqs]{dk_add_sysreqs()}} for adding system requirements 56 | 57 | Other dockerfile from environment functions: 58 | \code{\link{dk_from_description}()}, 59 | \code{\link{dk_from_script}()}, 60 | \code{\link{dk_from_session}()} 61 | } 62 | \concept{dockerfile from environment functions} 63 | -------------------------------------------------------------------------------- /man/dk_from_script.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-from-environment.R 3 | \name{dk_from_script} 4 | \alias{dk_from_script} 5 | \title{Create a \code{dockerfile} from an R script} 6 | \usage{ 7 | dk_from_script( 8 | script_file, 9 | base_image = "rocker/r-ver:latest", 10 | include_sysreqs = TRUE 11 | ) 12 | } 13 | \arguments{ 14 | \item{script_file}{Path to R script} 15 | 16 | \item{base_image}{Base image to use (default: latest \code{rocker/r-ver})} 17 | 18 | \item{include_sysreqs}{Include system requirements (default: \code{TRUE})} 19 | } 20 | \value{ 21 | A \code{dockerfile} object configured to run the specified R script 22 | } 23 | \description{ 24 | Generates a \code{dockerfile} based on an R script, analyzing its dependencies 25 | and creating a container that can run the script. 26 | } 27 | \details{ 28 | This function analyzes the R script to identify package dependencies by 29 | scanning for \code{library()} and \code{require()} calls. It then: 30 | \itemize{ 31 | \item Creates a dockerfile with the specified base image 32 | \item Adds necessary system requirements for the detected packages 33 | \item Installs the required R packages 34 | \item Copies the script to the container 35 | \item Sets up a command to run the script 36 | } 37 | 38 | The \code{dockerfile} can be customized further after creation if needed. 39 | } 40 | \examples{ 41 | \dontrun{ 42 | # Create a dockerfile for an R script 43 | df <- dk_from_script("analysis.R") 44 | 45 | # Use a specific base image 46 | df <- dk_from_script("analysis.R", base_image = "rocker/tidyverse:4.4.0") 47 | } 48 | 49 | } 50 | \seealso{ 51 | \code{\link[=dk_from_session]{dk_from_session()}} for creating from the current session, 52 | \code{\link[=dk_from_renv]{dk_from_renv()}} for creating from renv.lock files, & 53 | \code{\link[=dk_from_description]{dk_from_description()}} for creating from DESCRIPTION files 54 | 55 | Other dockerfile from environment functions: 56 | \code{\link{dk_from_description}()}, 57 | \code{\link{dk_from_renv}()}, 58 | \code{\link{dk_from_session}()} 59 | } 60 | \concept{dockerfile from environment functions} 61 | -------------------------------------------------------------------------------- /man/dk_from_session.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-from-environment.R 3 | \name{dk_from_session} 4 | \alias{dk_from_session} 5 | \title{Create a \code{dockerfile} from the current R session} 6 | \usage{ 7 | dk_from_session( 8 | base_image = NULL, 9 | include_packages = TRUE, 10 | include_sysreqs = TRUE, 11 | package_manager = "auto" 12 | ) 13 | } 14 | \arguments{ 15 | \item{base_image}{Base image to use 16 | (default: \code{"rocker/r-ver"} with current R version)} 17 | 18 | \item{include_packages}{Include loaded packages (default: \code{TRUE})} 19 | 20 | \item{include_sysreqs}{Include system requirements for packages (default: \code{TRUE})} 21 | 22 | \item{package_manager}{Package manager to use (default: \code{"auto"})} 23 | } 24 | \value{ 25 | A \code{dockerfile} object based on the current R session 26 | } 27 | \description{ 28 | Generates a \code{dockerfile} based on the current R session's loaded packages 29 | and environment, making it easy to containerize your current workflow. 30 | } 31 | \details{ 32 | This function: 33 | \itemize{ 34 | \item Uses the current R version by default (or a specified base image) 35 | \item Detects loaded packages in the current session 36 | \item Adds necessary system requirements using the pak package 37 | \item Adds commands to install the detected R packages 38 | } 39 | 40 | The resulting \code{dockerfile} will recreate an environment similar to your 41 | current R session, making it easier to containerize your work. 42 | } 43 | \examples{ 44 | \dontrun{ 45 | # Create a dockerfile from the current session 46 | df <- dk_from_session() 47 | } 48 | 49 | } 50 | \seealso{ 51 | \code{\link[=dk_from_renv]{dk_from_renv()}} for creating from renv.lock files, 52 | \code{\link[=dk_from_description]{dk_from_description()}} for creating from DESCRIPTION files, & 53 | \code{\link[=dk_add_sysreqs]{dk_add_sysreqs()}} for adding system requirements 54 | 55 | Other dockerfile from environment functions: 56 | \code{\link{dk_from_description}()}, 57 | \code{\link{dk_from_renv}()}, 58 | \code{\link{dk_from_script}()} 59 | } 60 | \concept{dockerfile from environment functions} 61 | -------------------------------------------------------------------------------- /man/dk_register_template.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-templates.R 3 | \name{dk_register_template} 4 | \alias{dk_register_template} 5 | \title{Register a custom dockerfile template} 6 | \usage{ 7 | dk_register_template(name, template_fn) 8 | } 9 | \arguments{ 10 | \item{name}{Template name} 11 | 12 | \item{template_fn}{Function that returns a dockerfile} 13 | } 14 | \value{ 15 | Invisible TRUE if successful 16 | } 17 | \description{ 18 | Register a custom dockerfile template 19 | } 20 | -------------------------------------------------------------------------------- /man/dk_template_base.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-templates.R 3 | \name{dk_template_base} 4 | \alias{dk_template_base} 5 | \title{Create a base R dockerfile template} 6 | \usage{ 7 | dk_template_base(r_version = NULL, additional_pkgs = NULL) 8 | } 9 | \arguments{ 10 | \item{r_version}{R version to use (default: current version)} 11 | 12 | \item{additional_pkgs}{Additional R packages to install} 13 | } 14 | \value{ 15 | A dockerfile object 16 | } 17 | \description{ 18 | Create a base R dockerfile template 19 | } 20 | -------------------------------------------------------------------------------- /man/dk_template_custom.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-templates.R 3 | \name{dk_template_custom} 4 | \alias{dk_template_custom} 5 | \title{Create a dockerfile from a custom template} 6 | \usage{ 7 | dk_template_custom(template_name, ...) 8 | } 9 | \arguments{ 10 | \item{template_name}{Name of the template} 11 | 12 | \item{...}{Arguments to pass to the template function} 13 | } 14 | \value{ 15 | A dockerfile object 16 | } 17 | \description{ 18 | Create a dockerfile from a custom template 19 | } 20 | -------------------------------------------------------------------------------- /man/dk_template_ignore_common.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_common} 4 | \alias{dk_template_ignore_common} 5 | \title{Create a \code{dockerignore} template for common ignore patterns} 6 | \usage{ 7 | dk_template_ignore_common( 8 | .dockerignore = NULL, 9 | git = TRUE, 10 | r = TRUE, 11 | os = TRUE, 12 | editor = FALSE, 13 | node = FALSE, 14 | python = FALSE, 15 | data = FALSE 16 | ) 17 | } 18 | \arguments{ 19 | \item{.dockerignore}{Optional existing dockerignore object to add patterns to} 20 | 21 | \item{git}{Include Git-related files (default: TRUE)} 22 | 23 | \item{r}{Include R-related files (default: TRUE)} 24 | 25 | \item{os}{Include OS-specific files (default: TRUE)} 26 | 27 | \item{editor}{Include editor-specific files (default: FALSE)} 28 | 29 | \item{node}{Include Node.js-related files (default: FALSE)} 30 | 31 | \item{python}{Include Python-related files (default: FALSE)} 32 | 33 | \item{data}{Include data-related files (default: FALSE)} 34 | } 35 | \value{ 36 | A \code{dockerignore} object with selected ignore patterns 37 | } 38 | \description{ 39 | Creates a comprehensive \strong{.dockerignore} template with patterns for various 40 | file categories based on the selected options. 41 | } 42 | \details{ 43 | This function provides a convenient way to create a comprehensive .dockerignore 44 | file tailored to your project's needs. Each category adds patterns relevant to 45 | specific types of files: 46 | \itemize{ 47 | \item \code{git}: Git repositories, .gitignore, etc. 48 | \item \code{r}: R history, RData, Rproj.user, etc. 49 | \item \code{os}: .DS_Store, Thumbs.db, etc. 50 | \item \code{editor}: .vscode, .idea, *.swp, etc. 51 | \item \code{node}: node_modules, package-lock.json, etc. 52 | \item \code{python}: \strong{pycache}, *.pyc, venv, etc. 53 | \item \code{data}: *.csv, *.json, *.xlsx, etc. 54 | } 55 | } 56 | \examples{ 57 | # Basic template with Git, R, and OS patterns 58 | di <- dk_template_ignore_common() 59 | 60 | # Customize with additional categories 61 | di <- dk_template_ignore_common( 62 | git = TRUE, 63 | r = TRUE, 64 | os = TRUE, 65 | editor = TRUE, 66 | data = TRUE 67 | ) 68 | 69 | } 70 | \seealso{ 71 | \code{\link[=dk_template_ignore_git]{dk_template_ignore_git()}} for Git-specific patterns, 72 | \code{\link[=dk_template_ignore_r]{dk_template_ignore_r()}} for R-specific patterns, & 73 | \code{\link[=di_add]{di_add()}} for adding custom patterns 74 | 75 | Other dockerignore template functions: 76 | \code{\link{dk_template_ignore_data}()}, 77 | \code{\link{dk_template_ignore_editor}()}, 78 | \code{\link{dk_template_ignore_git}()}, 79 | \code{\link{dk_template_ignore_node}()}, 80 | \code{\link{dk_template_ignore_os}()}, 81 | \code{\link{dk_template_ignore_packrat}()}, 82 | \code{\link{dk_template_ignore_python}()}, 83 | \code{\link{dk_template_ignore_r}()}, 84 | \code{\link{dk_template_ignore_raw_data}()}, 85 | \code{\link{dk_template_ignore_renv}()} 86 | } 87 | \concept{dockerignore template functions} 88 | -------------------------------------------------------------------------------- /man/dk_template_ignore_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_data} 4 | \alias{dk_template_ignore_data} 5 | \title{Create a \code{dockerignore} template for data-related files} 6 | \usage{ 7 | dk_template_ignore_data(.dockerignore = NULL, raw = TRUE) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing dockerignore object to add patterns to} 11 | 12 | \item{raw}{Include raw data directories (default: TRUE)} 13 | } 14 | \value{ 15 | A \code{dockerignore} object with data-related ignore patterns 16 | } 17 | \description{ 18 | Creates a `dockerignore`` template with patterns to ignore common data files 19 | and directories. 20 | } 21 | \details{ 22 | This template adds patterns to ignore common data files and directories that 23 | are often large and can significantly slow down Docker builds. It includes 24 | patterns for various data file formats: 25 | \itemize{ 26 | \item \verb{data/}: Data directories 27 | \item \verb{*.csv}, \verb{*.tsv}: CSV and TSV files 28 | \item \verb{*.xls*}: Excel files 29 | \item \verb{*.db}, \verb{*.sqlite*}: Database files 30 | \item \verb{*.h5}, \verb{*.hdf5}: HDF5 files 31 | \item \verb{*.parquet}, \verb{*.feather}: Columnar storage formats 32 | \item \verb{*.json}: JSON files 33 | \item \verb{*.pickle}: Python pickle files 34 | \item \verb{*.rdata}, \verb{*.rda}: R data files 35 | } 36 | 37 | If \code{raw = TRUE}, it also ignores common data directories: 38 | \itemize{ 39 | \item \verb{data-raw/}, \verb{data/raw/}: Raw data 40 | \item \verb{data/interim/}: Intermediate processed data 41 | \item \verb{data/processed/}: Final processed data 42 | \item \verb{data/external/}: Data from external sources 43 | } 44 | } 45 | \examples{ 46 | # Create a new dockerignore with data patterns 47 | di <- dk_template_ignore_data() 48 | 49 | # Exclude raw data directories 50 | di <- dk_template_ignore_data(raw = FALSE) 51 | 52 | } 53 | \seealso{ 54 | \code{\link[=dk_template_ignore_raw_data]{dk_template_ignore_raw_data()}} for raw data directories only & 55 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 56 | 57 | Other dockerignore template functions: 58 | \code{\link{dk_template_ignore_common}()}, 59 | \code{\link{dk_template_ignore_editor}()}, 60 | \code{\link{dk_template_ignore_git}()}, 61 | \code{\link{dk_template_ignore_node}()}, 62 | \code{\link{dk_template_ignore_os}()}, 63 | \code{\link{dk_template_ignore_packrat}()}, 64 | \code{\link{dk_template_ignore_python}()}, 65 | \code{\link{dk_template_ignore_r}()}, 66 | \code{\link{dk_template_ignore_raw_data}()}, 67 | \code{\link{dk_template_ignore_renv}()} 68 | } 69 | \concept{dockerignore template functions} 70 | -------------------------------------------------------------------------------- /man/dk_template_ignore_editor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_editor} 4 | \alias{dk_template_ignore_editor} 5 | \title{Create a dockerignore template for editor-related files} 6 | \usage{ 7 | dk_template_ignore_editor(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing \code{dockerignore} object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with editor-related ignore patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore files and directories 17 | created by common code editors and IDEs. 18 | } 19 | \details{ 20 | This template adds patterns to ignore files and directories created by 21 | common code editors and IDEs, including: 22 | \itemize{ 23 | \item VS Code: \verb{.vscode/}, \verb{*.code-workspace} 24 | \item JetBrains IDEs (e.g., RStudio, PyCharm): \verb{.idea/}, \verb{*.iml}, \verb{*.iws} 25 | \item Sublime Text: \verb{*.sublime-workspace}, \verb{*.sublime-project} 26 | \item Vim: \verb{*.swp}, \verb{*.swo}, \verb{*~} 27 | \item Emacs: \verb{#*#}, \code{.#*}, \code{.projectile} 28 | \item Eclipse: \code{.classpath}, \code{.project}, \verb{.settings/} 29 | \item Visual Studio: \verb{.vs/}, \verb{*.suo}, \verb{*.njsproj}, \verb{*.sln} 30 | } 31 | 32 | These files are typically not needed in a Docker image and can reduce the 33 | build context size. 34 | } 35 | \examples{ 36 | # Create a new dockerignore with editor patterns 37 | di <- dk_template_ignore_editor() 38 | di 39 | 40 | # Add editor patterns to an existing dockerignore 41 | di <- dockerignore() |> 42 | di_add("*.log") |> 43 | dk_template_ignore_editor() 44 | di 45 | 46 | } 47 | \seealso{ 48 | \code{\link[=dk_template_ignore_os]{dk_template_ignore_os()}} for OS-specific patterns & 49 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 50 | 51 | Other dockerignore template functions: 52 | \code{\link{dk_template_ignore_common}()}, 53 | \code{\link{dk_template_ignore_data}()}, 54 | \code{\link{dk_template_ignore_git}()}, 55 | \code{\link{dk_template_ignore_node}()}, 56 | \code{\link{dk_template_ignore_os}()}, 57 | \code{\link{dk_template_ignore_packrat}()}, 58 | \code{\link{dk_template_ignore_python}()}, 59 | \code{\link{dk_template_ignore_r}()}, 60 | \code{\link{dk_template_ignore_raw_data}()}, 61 | \code{\link{dk_template_ignore_renv}()} 62 | } 63 | \concept{dockerignore template functions} 64 | -------------------------------------------------------------------------------- /man/dk_template_ignore_git.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_git} 4 | \alias{dk_template_ignore_git} 5 | \title{Create a \code{dockerignore} template for Git-related files} 6 | \usage{ 7 | dk_template_ignore_git(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing \code{dockerignore} object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with Git-related ignore patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore common Git-related files 17 | and directories. 18 | } 19 | \details{ 20 | This template adds patterns to ignore common Git-related files and directories, 21 | including: 22 | \itemize{ 23 | \item \verb{.git/}: The Git repository directory 24 | \item \code{.gitignore}: Git ignore files 25 | \item \code{.gitattributes}: Git attributes file 26 | \item \verb{.github/}: GitHub-specific files 27 | \item \code{.gitlab-ci.yml}: GitLab CI configuration 28 | } 29 | 30 | These files are typically not needed in a Docker image and can reduce the 31 | build context size. 32 | } 33 | \examples{ 34 | # Create a new dockerignore with Git patterns 35 | di <- dk_template_ignore_git() 36 | di 37 | 38 | # Add Git patterns to an existing dockerignore 39 | di <- dockerignore() |> 40 | di_add("*.log") |> 41 | dk_template_ignore_git() 42 | di 43 | 44 | } 45 | \seealso{ 46 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template & 47 | \code{\link[=di_add]{di_add()}} for adding custom patterns 48 | 49 | Other dockerignore template functions: 50 | \code{\link{dk_template_ignore_common}()}, 51 | \code{\link{dk_template_ignore_data}()}, 52 | \code{\link{dk_template_ignore_editor}()}, 53 | \code{\link{dk_template_ignore_node}()}, 54 | \code{\link{dk_template_ignore_os}()}, 55 | \code{\link{dk_template_ignore_packrat}()}, 56 | \code{\link{dk_template_ignore_python}()}, 57 | \code{\link{dk_template_ignore_r}()}, 58 | \code{\link{dk_template_ignore_raw_data}()}, 59 | \code{\link{dk_template_ignore_renv}()} 60 | } 61 | \concept{dockerignore template functions} 62 | -------------------------------------------------------------------------------- /man/dk_template_ignore_node.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_node} 4 | \alias{dk_template_ignore_node} 5 | \title{Create a \code{dockerignore} template for Node.js/JavaScript projects} 6 | \usage{ 7 | dk_template_ignore_node(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing \code{dockerignore} object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with Node.js-related ignore patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore Node.js and 17 | JavaScript related files and directories. 18 | ` 19 | } 20 | \details{ 21 | This template adds patterns to ignore Node.js and JavaScript related files 22 | and directories, including: 23 | \itemize{ 24 | \item \verb{node_modules/}: Package dependencies 25 | \item \verb{npm-debug.log*}, \verb{yarn-error.log*}: Package manager logs 26 | \item \code{package-lock.json}, \code{yarn.lock}: Lock files 27 | \item \verb{.npm/}, \verb{.yarn/}: Cache directories 28 | \item \verb{*.tgz}: Packaged modules 29 | \item \verb{.pnp.*}: Plug'n'Play files 30 | \item \verb{.cache/}: Build cache 31 | \item \code{.eslintcache}: ESLint cache 32 | } 33 | 34 | These files are typically not needed in a Docker image or can be regenerated 35 | during the build process. Ignoring them can significantly reduce the build 36 | context size, especially \verb{node_modules/} which can be very large. 37 | } 38 | \examples{ 39 | # Create a new dockerignore with Node.js patterns 40 | di <- dk_template_ignore_node() 41 | di 42 | 43 | # Add Node.js patterns to an existing dockerignore 44 | di <- dockerignore() |> 45 | di_add("*.log") |> 46 | dk_template_ignore_node() 47 | di 48 | 49 | } 50 | \seealso{ 51 | \code{\link[=dk_template_ignore_python]{dk_template_ignore_python()}} for Python-specific patterns & 52 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 53 | 54 | Other dockerignore template functions: 55 | \code{\link{dk_template_ignore_common}()}, 56 | \code{\link{dk_template_ignore_data}()}, 57 | \code{\link{dk_template_ignore_editor}()}, 58 | \code{\link{dk_template_ignore_git}()}, 59 | \code{\link{dk_template_ignore_os}()}, 60 | \code{\link{dk_template_ignore_packrat}()}, 61 | \code{\link{dk_template_ignore_python}()}, 62 | \code{\link{dk_template_ignore_r}()}, 63 | \code{\link{dk_template_ignore_raw_data}()}, 64 | \code{\link{dk_template_ignore_renv}()} 65 | } 66 | \concept{dockerignore template functions} 67 | -------------------------------------------------------------------------------- /man/dk_template_ignore_os.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_os} 4 | \alias{dk_template_ignore_os} 5 | \title{Create a \code{dockerignore} template for OS-related files} 6 | \usage{ 7 | dk_template_ignore_os(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing \code{dockerignore} object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with OS-related ignore patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore operating system 17 | specific files and directories. 18 | } 19 | \details{ 20 | This template adds patterns to ignore operating system specific files 21 | that aren't needed in a Docker image, including: 22 | \itemize{ 23 | \item \code{.DS_Store}: macOS folder metadata 24 | \item \code{Thumbs.db}: Windows thumbnail cache 25 | \item \code{desktop.ini}: Windows folder configuration 26 | \item \verb{*.swp}, \verb{*~}: Temporary editor files 27 | \item \code{.directory}: KDE folder metadata 28 | \item \verb{Icon?}: macOS icon files 29 | \item \verb{*.lnk}: Windows shortcuts 30 | } 31 | 32 | These files are typically not needed in a Docker image and can reduce the 33 | build context size. 34 | } 35 | \examples{ 36 | # Create a new dockerignore with OS patterns 37 | di <- dk_template_ignore_os() 38 | di 39 | 40 | # Add OS patterns to an existing dockerignore 41 | di <- dockerignore() |> 42 | di_add("*.log") |> 43 | dk_template_ignore_os() 44 | di 45 | 46 | } 47 | \seealso{ 48 | \code{\link[=dk_template_ignore_editor]{dk_template_ignore_editor()}} for editor-specific patterns & 49 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 50 | 51 | Other dockerignore template functions: 52 | \code{\link{dk_template_ignore_common}()}, 53 | \code{\link{dk_template_ignore_data}()}, 54 | \code{\link{dk_template_ignore_editor}()}, 55 | \code{\link{dk_template_ignore_git}()}, 56 | \code{\link{dk_template_ignore_node}()}, 57 | \code{\link{dk_template_ignore_packrat}()}, 58 | \code{\link{dk_template_ignore_python}()}, 59 | \code{\link{dk_template_ignore_r}()}, 60 | \code{\link{dk_template_ignore_raw_data}()}, 61 | \code{\link{dk_template_ignore_renv}()} 62 | } 63 | \concept{dockerignore template functions} 64 | -------------------------------------------------------------------------------- /man/dk_template_ignore_packrat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_packrat} 4 | \alias{dk_template_ignore_packrat} 5 | \title{Create a \code{dockerignore} template for \code{{packrat}}-related files} 6 | \usage{ 7 | dk_template_ignore_packrat(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing \code{dockerignore} object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with \code{{packrat}}-related ignore patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore \code{{packrat}} library and 17 | source directories. 18 | } 19 | \details{ 20 | This template adds patterns to ignore \code{{packrat}} library and source directories, 21 | which are typically not needed in a Docker image. These include: 22 | \itemize{ 23 | \item \verb{packrat/lib*/}: Package libraries 24 | \item \verb{packrat/src/}: Package sources 25 | } 26 | 27 | When using \code{{packrat}} in a \strong{Dockerfile}, you typically want to copy just the 28 | \code{{packrat}} configuration files and use \code{{packrat}}'s restore functionality to 29 | rebuild the library inside the container, rather than copying the entire 30 | library. 31 | } 32 | \examples{ 33 | # Create a new dockerignore with packrat patterns 34 | di <- dk_template_ignore_packrat() 35 | 36 | # Add packrat patterns to an existing dockerignore 37 | di <- dockerignore() |> 38 | di_add("*.log") |> 39 | dk_template_ignore_packrat() 40 | 41 | } 42 | \seealso{ 43 | \code{\link[=dk_template_ignore_renv]{dk_template_ignore_renv()}} for renv-specific patterns, 44 | \code{\link[=dk_template_ignore_r]{dk_template_ignore_r()}} for R-specific patterns, & 45 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 46 | 47 | Other dockerignore template functions: 48 | \code{\link{dk_template_ignore_common}()}, 49 | \code{\link{dk_template_ignore_data}()}, 50 | \code{\link{dk_template_ignore_editor}()}, 51 | \code{\link{dk_template_ignore_git}()}, 52 | \code{\link{dk_template_ignore_node}()}, 53 | \code{\link{dk_template_ignore_os}()}, 54 | \code{\link{dk_template_ignore_python}()}, 55 | \code{\link{dk_template_ignore_r}()}, 56 | \code{\link{dk_template_ignore_raw_data}()}, 57 | \code{\link{dk_template_ignore_renv}()} 58 | } 59 | \concept{dockerignore template functions} 60 | -------------------------------------------------------------------------------- /man/dk_template_ignore_python.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_python} 4 | \alias{dk_template_ignore_python} 5 | \title{Create a \code{dockerignore} template for Python projects} 6 | \usage{ 7 | dk_template_ignore_python(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing \code{dockerignore} object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with Python-related ignore patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore Python related files 17 | and directories. 18 | } 19 | \details{ 20 | This template adds patterns to ignore Python related files and directories, 21 | including: 22 | \itemize{ 23 | \item \verb{__pycache__/}: Compiled Python files 24 | \item \verb{*.py[cod]}: Python compiled files 25 | \item \verb{.pytest_cache/}: PyTest cache 26 | \item \code{.coverage}, \verb{htmlcov/}: Coverage reports 27 | \item \verb{.tox/}, \verb{.nox/}: Testing environments 28 | \item \verb{.venv/}, \verb{venv/}, \verb{ENV/}: Virtual environments 29 | \item \code{.Python}, \verb{build/}, \verb{dist/}: Build artifacts 30 | \item \verb{.egg-info/}, \verb{*.egg}: Package metadata 31 | \item \verb{.ipynb_checkpoints/}: Jupyter notebook checkpoints 32 | } 33 | 34 | These files are typically not needed in a Docker image or can be regenerated 35 | during the build process. Ignoring them can significantly reduce the build 36 | context size. 37 | } 38 | \examples{ 39 | # Create a new dockerignore with Python patterns 40 | di <- dk_template_ignore_python() 41 | 42 | # Add Python patterns to an existing dockerignore 43 | di <- dockerignore() |> 44 | di_add("*.log") |> 45 | dk_template_ignore_python() 46 | 47 | } 48 | \seealso{ 49 | \code{\link[=dk_template_ignore_node]{dk_template_ignore_node()}} for Node.js-specific patterns & 50 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 51 | 52 | Other dockerignore template functions: 53 | \code{\link{dk_template_ignore_common}()}, 54 | \code{\link{dk_template_ignore_data}()}, 55 | \code{\link{dk_template_ignore_editor}()}, 56 | \code{\link{dk_template_ignore_git}()}, 57 | \code{\link{dk_template_ignore_node}()}, 58 | \code{\link{dk_template_ignore_os}()}, 59 | \code{\link{dk_template_ignore_packrat}()}, 60 | \code{\link{dk_template_ignore_r}()}, 61 | \code{\link{dk_template_ignore_raw_data}()}, 62 | \code{\link{dk_template_ignore_renv}()} 63 | } 64 | \concept{dockerignore template functions} 65 | -------------------------------------------------------------------------------- /man/dk_template_ignore_r.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_r} 4 | \alias{dk_template_ignore_r} 5 | \title{Create a \code{dockerignore} template for R-related files} 6 | \usage{ 7 | dk_template_ignore_r(.dockerignore = NULL, renv = TRUE, packrat = TRUE) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing dockerignore object to add patterns to} 11 | 12 | \item{renv}{Include renv folders (default: TRUE)} 13 | 14 | \item{packrat}{Include packrat folders (default: TRUE)} 15 | } 16 | \value{ 17 | A \code{dockerignore} object with R-related ignore patterns 18 | } 19 | \description{ 20 | Creates a \code{dockerignore} template with patterns to ignore common R-related files 21 | and directories. 22 | } 23 | \details{ 24 | This template adds patterns to ignore common R-related files and directories 25 | that aren't needed in a Docker image, including: 26 | \itemize{ 27 | \item \verb{.Rproj.user/}: RStudio user settings 28 | \item \code{.Rhistory}: R command history 29 | \item \code{.RData}: R workspace data 30 | \item \code{.Ruserdata}: R user data 31 | \item \verb{*.Rproj}: RStudio project files 32 | \item \verb{*.rds}: R serialized data files 33 | \item \verb{.Rcheck/}: R package check directories 34 | } 35 | 36 | If \code{renv = TRUE}, it also adds patterns to ignore \code{{renv}} library 37 | directories, which should be rebuilt inside the container. 38 | 39 | If \code{packrat = TRUE}, it adds patterns to ignore \code{{packrat}} library 40 | directories. 41 | } 42 | \examples{ 43 | # Create a new dockerignore with R patterns 44 | di <- dk_template_ignore_r() 45 | di 46 | 47 | # Include R patterns but exclude package managers 48 | di <- dk_template_ignore_r(renv = FALSE, packrat = FALSE) 49 | di 50 | } 51 | \seealso{ 52 | \code{\link[=dk_template_ignore_renv]{dk_template_ignore_renv()}} for renv-specific patterns, 53 | \code{\link[=dk_template_ignore_packrat]{dk_template_ignore_packrat()}} for packrat-specific patterns, & 54 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 55 | 56 | Other dockerignore template functions: 57 | \code{\link{dk_template_ignore_common}()}, 58 | \code{\link{dk_template_ignore_data}()}, 59 | \code{\link{dk_template_ignore_editor}()}, 60 | \code{\link{dk_template_ignore_git}()}, 61 | \code{\link{dk_template_ignore_node}()}, 62 | \code{\link{dk_template_ignore_os}()}, 63 | \code{\link{dk_template_ignore_packrat}()}, 64 | \code{\link{dk_template_ignore_python}()}, 65 | \code{\link{dk_template_ignore_raw_data}()}, 66 | \code{\link{dk_template_ignore_renv}()} 67 | } 68 | \concept{dockerignore template functions} 69 | -------------------------------------------------------------------------------- /man/dk_template_ignore_raw_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_raw_data} 4 | \alias{dk_template_ignore_raw_data} 5 | \title{Create a \code{dockerignore} template for raw data directories} 6 | \usage{ 7 | dk_template_ignore_raw_data(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing dockerignore object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with raw data directory patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore common raw data 17 | directories. 18 | } 19 | \details{ 20 | This template adds patterns to ignore common raw data directories following 21 | the \href{https://usethis.r-lib.org/reference/use_data.html}{\code{usethis}} 22 | and \href{https://cookiecutter-data-science.drivendata.org/#directory-structure}{Cookiecutter Data Science} conventions: 23 | \itemize{ 24 | \item \verb{data-raw/} 25 | \item \verb{data/raw/}: Raw, immutable data 26 | \item \verb{data/interim/}: Intermediate data that has been transformed 27 | \item \verb{data/processed/}: The final, canonical data sets for modeling 28 | \item \verb{data/external/}: Data from third party sources 29 | } 30 | 31 | Raw data is often large and not needed in the Docker image. Instead, it's 32 | usually better to mount the data as a volume at runtime. 33 | } 34 | \examples{ 35 | # Create a new dockerignore with raw data patterns 36 | di <- dk_template_ignore_raw_data() 37 | 38 | # Add raw data patterns to an existing dockerignore 39 | di <- dockerignore() |> 40 | di_add("*.log") |> 41 | dk_template_ignore_raw_data() 42 | 43 | } 44 | \seealso{ 45 | \code{\link[=dk_template_ignore_data]{dk_template_ignore_data()}} for ignoring data file formats, 46 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template, 47 | \href{https://cookiecutter-data-science.drivendata.org/#directory-structure}{Cookiecutter Data Science Directory Structure Overview}, & 48 | \href{https://usethis.r-lib.org/reference/use_data.html}{\code{usethis::use_raw_data()}} 49 | 50 | Other dockerignore template functions: 51 | \code{\link{dk_template_ignore_common}()}, 52 | \code{\link{dk_template_ignore_data}()}, 53 | \code{\link{dk_template_ignore_editor}()}, 54 | \code{\link{dk_template_ignore_git}()}, 55 | \code{\link{dk_template_ignore_node}()}, 56 | \code{\link{dk_template_ignore_os}()}, 57 | \code{\link{dk_template_ignore_packrat}()}, 58 | \code{\link{dk_template_ignore_python}()}, 59 | \code{\link{dk_template_ignore_r}()}, 60 | \code{\link{dk_template_ignore_renv}()} 61 | } 62 | \concept{dockerignore template functions} 63 | -------------------------------------------------------------------------------- /man/dk_template_ignore_renv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-templates.R 3 | \name{dk_template_ignore_renv} 4 | \alias{dk_template_ignore_renv} 5 | \title{Create a dockerignore template for \code{{renv}}-related files} 6 | \usage{ 7 | dk_template_ignore_renv(.dockerignore = NULL) 8 | } 9 | \arguments{ 10 | \item{.dockerignore}{Optional existing \code{dockerignore} object to add patterns to} 11 | } 12 | \value{ 13 | A \code{dockerignore} object with \code{{renv}}-related ignore patterns 14 | } 15 | \description{ 16 | Creates a \code{dockerignore} template with patterns to ignore \code{{renv}} library and cache 17 | directories. 18 | } 19 | \details{ 20 | This template adds patterns to ignore \code{{renv}} library and cache directories, 21 | which are typically not needed in a Docker image. These include: 22 | \itemize{ 23 | \item \verb{renv/library/}: Package library 24 | \item \verb{renv/staging/}: Staging area for packages 25 | \item \verb{renv/python/}: Python libraries 26 | \item \verb{renv/local/}: Local cache 27 | } 28 | 29 | When using \code{{renv}} in a Dockerfile, you typically want to copy just the 30 | \code{renv.lock} file and use \code{renv::restore()} to rebuild the library inside 31 | the container, rather than copying the entire library. 32 | } 33 | \examples{ 34 | # Create a new dockerignore with renv patterns 35 | di <- dk_template_ignore_renv() 36 | di 37 | 38 | # Add renv patterns to an existing dockerignore 39 | di <- dockerignore() |> 40 | di_add("*.log") |> 41 | dk_template_ignore_renv() 42 | di 43 | 44 | } 45 | \seealso{ 46 | \code{\link[=dk_template_ignore_r]{dk_template_ignore_r()}} for R-specific patterns, 47 | \code{\link[=dk_from_renv]{dk_from_renv()}} for creating a Dockerfile from an renv.lock file, & 48 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for a more comprehensive template 49 | 50 | Other dockerignore template functions: 51 | \code{\link{dk_template_ignore_common}()}, 52 | \code{\link{dk_template_ignore_data}()}, 53 | \code{\link{dk_template_ignore_editor}()}, 54 | \code{\link{dk_template_ignore_git}()}, 55 | \code{\link{dk_template_ignore_node}()}, 56 | \code{\link{dk_template_ignore_os}()}, 57 | \code{\link{dk_template_ignore_packrat}()}, 58 | \code{\link{dk_template_ignore_python}()}, 59 | \code{\link{dk_template_ignore_r}()}, 60 | \code{\link{dk_template_ignore_raw_data}()} 61 | } 62 | \concept{dockerignore template functions} 63 | -------------------------------------------------------------------------------- /man/dk_template_plumber.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-templates.R 3 | \name{dk_template_plumber} 4 | \alias{dk_template_plumber} 5 | \title{Create a Plumber API dockerfile template} 6 | \usage{ 7 | dk_template_plumber( 8 | r_version = NULL, 9 | port = 8000, 10 | api_file = "plumber.R", 11 | additional_pkgs = NULL 12 | ) 13 | } 14 | \arguments{ 15 | \item{r_version}{R version to use (default: current version)} 16 | 17 | \item{port}{Port to expose (default: 8000)} 18 | 19 | \item{api_file}{Path to plumber.R file (default: "plumber.R")} 20 | 21 | \item{additional_pkgs}{Additional R packages to install} 22 | } 23 | \value{ 24 | A dockerfile object 25 | } 26 | \description{ 27 | Create a Plumber API dockerfile template 28 | } 29 | -------------------------------------------------------------------------------- /man/dk_template_shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-templates.R 3 | \name{dk_template_shiny} 4 | \alias{dk_template_shiny} 5 | \title{Create a Shiny app dockerfile template} 6 | \usage{ 7 | dk_template_shiny( 8 | r_version = NULL, 9 | port = 3838, 10 | app_dir = ".", 11 | additional_pkgs = NULL 12 | ) 13 | } 14 | \arguments{ 15 | \item{r_version}{R version to use (default: current version)} 16 | 17 | \item{port}{Port to expose (default: 3838)} 18 | 19 | \item{app_dir}{Local directory with Shiny app (default: ".")} 20 | 21 | \item{additional_pkgs}{Additional R packages to install} 22 | } 23 | \value{ 24 | A dockerfile object 25 | } 26 | \description{ 27 | Create a Shiny app dockerfile template 28 | } 29 | -------------------------------------------------------------------------------- /man/dockerfile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-core.R 3 | \name{dockerfile} 4 | \alias{dockerfile} 5 | \title{Create a new \code{dockerfile} object} 6 | \usage{ 7 | dockerfile() 8 | } 9 | \value{ 10 | A \code{dockerfile} object with the following structure: 11 | \itemize{ 12 | \item \code{lines}: Character vector containing Dockerfile instructions 13 | \item \code{metadata}: List containing metadata about the Dockerfile: 14 | \itemize{ 15 | \item \code{base_image}: Base image name 16 | \item \code{package_manager}: Package manager type (e.g., "apt", "yum") 17 | \item \code{r_version}: R version (if using a rocker image) 18 | \item \code{distribution}: Linux distribution flavor 19 | } 20 | } 21 | } 22 | \description{ 23 | Creates an empty \code{dockerfile} object that can be populated with Docker instructions. 24 | } 25 | \examples{ 26 | # Create a new dockerfile 27 | df <- dockerfile() 28 | 29 | # Add instruction for a base image 30 | df <- dfi_from(df, "rocker/r-ver:4.4.0") 31 | df 32 | 33 | # Add an instruction to run a command to update system packages 34 | df <- dfi_run(df, "apt update") 35 | df 36 | 37 | } 38 | \seealso{ 39 | \code{\link[=is_dockerfile]{is_dockerfile()}} for checking if an object is a dockerfile, 40 | \code{\link[=dfi_from]{dfi_from()}} for adding a base image, & 41 | \code{\link[=write_dockerfile]{write_dockerfile()}} for writing a dockerfile to disk 42 | 43 | Other dockerfile core functions: 44 | \code{\link{add_dockerfile_line}()}, 45 | \code{\link{check_dockerfile}()}, 46 | \code{\link{is_dockerfile}()}, 47 | \code{\link{print.dockerfile}()} 48 | } 49 | \concept{dockerfile core functions} 50 | -------------------------------------------------------------------------------- /man/dockerignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-core.R 3 | \name{dockerignore} 4 | \alias{dockerignore} 5 | \title{Create a new \code{dockerignore} object} 6 | \usage{ 7 | dockerignore() 8 | } 9 | \value{ 10 | A \code{dockerignore} object with a \code{patterns} character vector 11 | } 12 | \description{ 13 | Creates an empty `dockerignore`` object that can be populated with patterns 14 | to ignore during Docker builds. 15 | } 16 | \examples{ 17 | # Create a new dockerignore object 18 | di <- dockerignore() 19 | 20 | # Add patterns 21 | di <- di_add(di, c(".git/", "*.log")) 22 | 23 | } 24 | \seealso{ 25 | \code{\link[=di_add]{di_add()}} for adding patterns, 26 | \code{\link[=write_dockerignore]{write_dockerignore()}} for writing to a .dockerignore file, & 27 | \code{\link[=dk_template_ignore_common]{dk_template_ignore_common()}} for adding common patterns 28 | 29 | Other dockerignore core functions: 30 | \code{\link{c.dockerignore}()}, 31 | \code{\link{check_dockerignore}()}, 32 | \code{\link{is_dockerignore}()}, 33 | \code{\link{print.dockerignore}()} 34 | } 35 | \concept{dockerignore core functions} 36 | -------------------------------------------------------------------------------- /man/dockitect-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-package.R 3 | \docType{package} 4 | \name{dockitect-package} 5 | \alias{dockitect} 6 | \alias{dockitect-package} 7 | \title{dockitect: Create and Validate Dockerfiles Programmatically} 8 | \description{ 9 | A toolkit for programmatically creating, modifying, and validating Dockerfiles in R. Provides a pipe-friendly interface for building Docker environments from R sessions, packages, and scripts, with support for templates and automatic system requirement detection. 10 | } 11 | \section{Dockerfile Instructions}{ 12 | 13 | Functions for adding Dockerfile instructions are prefixed with \verb{dfi_*} and follow the 14 | pattern \code{dfi_instruction(.dockerfile, ...)}. 15 | } 16 | 17 | \section{Dockerfile Generators}{ 18 | 19 | Functions for generating Dockerfiles from various sources are prefixed with \verb{dk_*} and 20 | can create Dockerfiles from an R session, renv lockfile, DESCRIPTION file, or R script. 21 | } 22 | 23 | \section{Dockerfile Modifiers}{ 24 | 25 | Functions for modifying Dockerfiles are prefixed with \verb{dfm_*} and allow for adding, 26 | removing, replacing, and moving lines within a Dockerfile. 27 | } 28 | 29 | \section{Dockerignore Management}{ 30 | 31 | Functions for managing .dockerignore files are prefixed with \verb{di_*} and allow for 32 | adding and removing patterns from a .dockerignore file. 33 | } 34 | 35 | \seealso{ 36 | Useful links: 37 | \itemize{ 38 | \item \url{https://r-pkg.thecoatlessprofessor.com/dockitect/} 39 | \item \url{https://github.com/coatless-rpkg/dockitect} 40 | \item Report bugs at \url{https://github.com/coatless-rpkg/dockitect/issues} 41 | } 42 | 43 | } 44 | \author{ 45 | \strong{Maintainer}: James Joseph Balamuta \email{james.balamuta@gmail.com} (\href{https://orcid.org/0000-0003-2826-8458}{ORCID}) 46 | 47 | } 48 | \keyword{internal} 49 | -------------------------------------------------------------------------------- /man/generate_pkg_install_cmd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{generate_pkg_install_cmd} 4 | \alias{generate_pkg_install_cmd} 5 | \title{Generate package installation commands for different package managers} 6 | \usage{ 7 | generate_pkg_install_cmd(package_manager, packages) 8 | } 9 | \arguments{ 10 | \item{package_manager}{Character string specifying the package manager to use} 11 | 12 | \item{packages}{Character vector of packages to install} 13 | } 14 | \value{ 15 | Character vector of installation commands 16 | } 17 | \description{ 18 | Generate package installation commands for different package managers 19 | } 20 | -------------------------------------------------------------------------------- /man/has_instruction.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-core.R 3 | \name{has_instruction} 4 | \alias{has_instruction} 5 | \title{Check if a dockerfile has a specific instruction} 6 | \usage{ 7 | has_instruction(dockerfile, instruction) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A dockerfile object} 11 | 12 | \item{instruction}{Instruction to check for (e.g., "FROM", "RUN")} 13 | } 14 | \value{ 15 | TRUE if instruction exists, FALSE otherwise 16 | } 17 | \description{ 18 | Check if a dockerfile has a specific instruction 19 | } 20 | -------------------------------------------------------------------------------- /man/is_dockerfile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-core.R 3 | \name{is_dockerfile} 4 | \alias{is_dockerfile} 5 | \title{Test if an object is a \code{dockerfile}} 6 | \usage{ 7 | is_dockerfile(x) 8 | } 9 | \arguments{ 10 | \item{x}{Object to test} 11 | } 12 | \value{ 13 | \code{TRUE} if \code{x} is a \code{dockerfile} object, \code{FALSE} otherwise 14 | } 15 | \description{ 16 | Checks whether the provided object is a valid \code{dockerfile} class object. 17 | } 18 | \examples{ 19 | df <- dockerfile() 20 | is_dockerfile(df) 21 | is_dockerfile(list()) 22 | 23 | } 24 | \seealso{ 25 | \code{\link[=dockerfile]{dockerfile()}} for creating a \code{dockerfile} object & 26 | \code{\link[=check_dockerfile]{check_dockerfile()}} for ensuring an object is a \code{dockerfile} (with error) 27 | 28 | Other dockerfile core functions: 29 | \code{\link{add_dockerfile_line}()}, 30 | \code{\link{check_dockerfile}()}, 31 | \code{\link{dockerfile}()}, 32 | \code{\link{print.dockerfile}()} 33 | } 34 | \concept{dockerfile core functions} 35 | -------------------------------------------------------------------------------- /man/is_dockerignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-core.R 3 | \name{is_dockerignore} 4 | \alias{is_dockerignore} 5 | \title{Test if an object is a dockerignore} 6 | \usage{ 7 | is_dockerignore(x) 8 | } 9 | \arguments{ 10 | \item{x}{Object to test} 11 | } 12 | \value{ 13 | \code{TRUE} if \code{x} is a dockerignore object, \code{FALSE} otherwise 14 | } 15 | \description{ 16 | Checks whether the provided object is a valid \code{dockerignore} class object. 17 | } 18 | \examples{ 19 | di <- dockerignore() 20 | is_dockerignore(di) # TRUE 21 | is_dockerignore(list()) # FALSE 22 | 23 | } 24 | \seealso{ 25 | \code{\link[=dockerignore]{dockerignore()}} for creating a dockerignore object & 26 | \code{\link[=check_dockerignore]{check_dockerignore()}} for ensuring an object is a dockerignore (with error) 27 | 28 | Other dockerignore core functions: 29 | \code{\link{c.dockerignore}()}, 30 | \code{\link{check_dockerignore}()}, 31 | \code{\link{dockerignore}()}, 32 | \code{\link{print.dockerignore}()} 33 | } 34 | \concept{dockerignore core functions} 35 | -------------------------------------------------------------------------------- /man/map_to_sysreqs_platform.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{map_to_sysreqs_platform} 4 | \alias{map_to_sysreqs_platform} 5 | \title{Map package manager to sysreqs platform} 6 | \usage{ 7 | map_to_sysreqs_platform(package_manager, os = NULL) 8 | } 9 | \arguments{ 10 | \item{package_manager}{Package manager type (e.g., "apt", "yum")} 11 | 12 | \item{os}{Operating system (if known)} 13 | } 14 | \value{ 15 | Character string of platform for sysreqs 16 | } 17 | \description{ 18 | Maps a package manager to the corresponding platform identifier used by 19 | the pak package's system requirements feature. 20 | } 21 | \details{ 22 | This internal function maps package managers to platform identifiers 23 | understood by the pak package's system requirements feature. It uses 24 | the following mappings: 25 | \itemize{ 26 | \item apt → ubuntu (or debian if specified) 27 | \item yum → centos (or fedora, redhat, rockylinux if specified) 28 | \item zypper → opensuse (or sle if specified) 29 | \item apk → ubuntu (Alpine not directly supported) 30 | \item pacman → ubuntu (Arch not directly supported) 31 | } 32 | 33 | If the OS is explicitly provided and supported by pak, that platform 34 | is used directly. 35 | } 36 | \seealso{ 37 | \code{\link[=determine_package_manager]{determine_package_manager()}} for determining the package manager & 38 | \code{\link[=dk_add_sysreqs]{dk_add_sysreqs()}} for adding system requirements to a dockerfile 39 | 40 | Other utility functions: 41 | \code{\link{determine_linux_distribution}()}, 42 | \code{\link{determine_package_manager}()}, 43 | \code{\link{dk_add_sysreqs}()} 44 | } 45 | \concept{utility functions} 46 | \keyword{internal} 47 | -------------------------------------------------------------------------------- /man/print.dockerfile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-core.R 3 | \name{print.dockerfile} 4 | \alias{print.dockerfile} 5 | \title{Print method for \code{dockerfile} objects} 6 | \usage{ 7 | \method{print}{dockerfile}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{dockerfile} object} 11 | 12 | \item{...}{Additional arguments (not used)} 13 | } 14 | \value{ 15 | Invisibly returns the \code{dockerfile} object 16 | } 17 | \description{ 18 | Displays the contents of a \code{dockerfile} object in a readable format, 19 | showing each instruction on a new line as it would appear in an 20 | actual \strong{Dockerfile}. 21 | } 22 | \examples{ 23 | # Create a new dockerfile and add a couple of instructions 24 | df <- dockerfile() |> 25 | dfi_from("rocker/r-ver:latest") |> 26 | dfi_run("apt-get update") 27 | 28 | # Print the dockerfile 29 | print(df) 30 | 31 | } 32 | \seealso{ 33 | \code{\link[=dockerfile]{dockerfile()}} for creating a \code{dockerfile} object 34 | 35 | Other dockerfile core functions: 36 | \code{\link{add_dockerfile_line}()}, 37 | \code{\link{check_dockerfile}()}, 38 | \code{\link{dockerfile}()}, 39 | \code{\link{is_dockerfile}()} 40 | } 41 | \concept{dockerfile core functions} 42 | -------------------------------------------------------------------------------- /man/print.dockerignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-core.R 3 | \name{print.dockerignore} 4 | \alias{print.dockerignore} 5 | \title{Print method for dockerignore objects} 6 | \usage{ 7 | \method{print}{dockerignore}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{dockerignore} object} 11 | 12 | \item{...}{Additional arguments (not used)} 13 | } 14 | \value{ 15 | Invisibly returns the dockerignore object 16 | } 17 | \description{ 18 | Displays the contents of a dockerignore object in a readable format, 19 | showing each pattern on a new line as it would appear in an 20 | actual .dockerignore file. 21 | } 22 | \examples{ 23 | di <- dockerignore() |> 24 | di_add(c(".git/", "*.log", "node_modules/")) 25 | print(di) 26 | 27 | } 28 | \seealso{ 29 | \code{\link[=dockerignore]{dockerignore()}} for creating a dockerignore object & 30 | \code{\link[=write_dockerignore]{write_dockerignore()}} for writing to a .dockerignore file 31 | 32 | Other dockerignore core functions: 33 | \code{\link{c.dockerignore}()}, 34 | \code{\link{check_dockerignore}()}, 35 | \code{\link{dockerignore}()}, 36 | \code{\link{is_dockerignore}()} 37 | } 38 | \concept{dockerignore core functions} 39 | -------------------------------------------------------------------------------- /man/read_dockerfile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-io.R 3 | \name{read_dockerfile} 4 | \alias{read_dockerfile} 5 | \title{Read a Dockerfile from a file} 6 | \usage{ 7 | read_dockerfile(file) 8 | } 9 | \arguments{ 10 | \item{file}{Path to \strong{Dockerfile}} 11 | } 12 | \value{ 13 | A \code{dockerfile} object containing the parsed instructions and metadata 14 | } 15 | \description{ 16 | Parses a \strong{Dockerfile} from disk into a \code{dockerfile} object that can be 17 | manipulated programmatically. 18 | } 19 | \details{ 20 | The function handles line continuations and extracts metadata like the 21 | base image, package manager, OS, and R version (if applicable). 22 | Comments and empty lines are skipped. 23 | } 24 | \examples{ 25 | \dontrun{ 26 | # Read an existing Dockerfile 27 | df <- read_dockerfile("path/to/Dockerfile") 28 | 29 | # Modify it 30 | df <- dfi_run(df, "apt-get update") 31 | df 32 | } 33 | 34 | } 35 | \seealso{ 36 | \code{\link[=dockerfile]{dockerfile()}} for creating a new dockerfile object & 37 | \code{\link[=write_dockerfile]{write_dockerfile()}} for writing a dockerfile to disk 38 | 39 | Other dockerfile I/O functions: 40 | \code{\link{write_dockerfile}()} 41 | } 42 | \concept{dockerfile I/O functions} 43 | -------------------------------------------------------------------------------- /man/read_dockerignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-io.R 3 | \name{read_dockerignore} 4 | \alias{read_dockerignore} 5 | \title{Read a \strong{.dockerignore} file} 6 | \usage{ 7 | read_dockerignore(file = ".dockerignore") 8 | } 9 | \arguments{ 10 | \item{file}{Path to \strong{.dockerignore} file (default: \code{".dockerignore"})} 11 | } 12 | \value{ 13 | A \code{dockerignore} object containing the parsed patterns 14 | } 15 | \description{ 16 | Reads a \strong{.dockerignore} file from disk into a \code{dockerignore} object that 17 | can be manipulated programmatically. 18 | } 19 | \details{ 20 | Empty lines and comments (lines starting with \verb{#}) are filtered out. 21 | } 22 | \examples{ 23 | \dontrun{ 24 | # Read an existing .dockerignore file 25 | di <- read_dockerignore() 26 | 27 | # Add more patterns 28 | di <- di_add(di, "*.tmp") 29 | } 30 | 31 | } 32 | \seealso{ 33 | \code{\link[=dockerignore]{dockerignore()}} for creating a new dockerignore object & 34 | \code{\link[=write_dockerignore]{write_dockerignore()}} for writing a dockerignore to disk 35 | 36 | Other dockerignore I/O functions: 37 | \code{\link{write_dockerignore}()} 38 | } 39 | \concept{dockerignore I/O functions} 40 | -------------------------------------------------------------------------------- /man/template_registry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockitect-templates.R 3 | \docType{data} 4 | \name{template_registry} 5 | \alias{template_registry} 6 | \title{Templates registry for storing custom templates} 7 | \format{ 8 | An object of class \code{environment} of length 0. 9 | } 10 | \usage{ 11 | template_registry 12 | } 13 | \description{ 14 | Templates registry for storing custom templates 15 | } 16 | \keyword{internal} 17 | -------------------------------------------------------------------------------- /man/write_dockerfile.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerfile-io.R 3 | \name{write_dockerfile} 4 | \alias{write_dockerfile} 5 | \title{Write a \code{dockerfile} to a file} 6 | \usage{ 7 | write_dockerfile(dockerfile, file = "Dockerfile", multiline = TRUE) 8 | } 9 | \arguments{ 10 | \item{dockerfile}{A \code{dockerfile} object} 11 | 12 | \item{file}{Output file path (default: "Dockerfile")} 13 | 14 | \item{multiline}{Logical indicating if long RUN commands should be split (default: TRUE)} 15 | } 16 | \value{ 17 | Invisibly returns the \code{dockerfile} object 18 | } 19 | \description{ 20 | Writes a \code{dockerfile} object to disk as a \strong{Dockerfile}. 21 | } 22 | \details{ 23 | When \code{multiline = TRUE} (the default), long \code{RUN} commands with \code{&&} 24 | will be formatted with line continuations (\verb{\\}) for better readability. 25 | This makes the Dockerfile more maintainable without changing its functionality. 26 | } 27 | \examples{ 28 | \dontrun{ 29 | # Create and write a simple Dockerfile 30 | dockerfile() |> 31 | dfi_from("rocker/r-ver:4.4.0") |> 32 | dfi_run("apt-get update") |> 33 | write_dockerfile() 34 | 35 | # Specify a different file name 36 | dockerfile() |> 37 | dfi_from("rocker/r-ver:4.4.0") |> 38 | write_dockerfile("Dockerfile.dev") 39 | } 40 | 41 | } 42 | \seealso{ 43 | \code{\link[=read_dockerfile]{read_dockerfile()}} for reading a Dockerfile from disk & 44 | \code{\link[=dockerfile]{dockerfile()}} for creating a new dockerfile object 45 | 46 | Other dockerfile I/O functions: 47 | \code{\link{read_dockerfile}()} 48 | } 49 | \concept{dockerfile I/O functions} 50 | -------------------------------------------------------------------------------- /man/write_dockerignore.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dockerignore-io.R 3 | \name{write_dockerignore} 4 | \alias{write_dockerignore} 5 | \title{Write a \code{dockerignore} object to a file} 6 | \usage{ 7 | write_dockerignore(dockerignore, file = ".dockerignore") 8 | } 9 | \arguments{ 10 | \item{dockerignore}{A \code{dockerignore} object} 11 | 12 | \item{file}{Output file path (default: \code{".dockerignore"})} 13 | } 14 | \value{ 15 | Invisibly returns the \code{dockerignore} object 16 | } 17 | \description{ 18 | Writes a \code{dockerignore} object to disk as a formatted \strong{.dockerignore} file. 19 | } 20 | \examples{ 21 | \dontrun{ 22 | # Create and write a .dockerignore file 23 | dockerignore() |> 24 | di_add(c(".git/", "*.log")) |> 25 | write_dockerignore() 26 | } 27 | 28 | } 29 | \seealso{ 30 | \code{\link[=read_dockerignore]{read_dockerignore()}} for reading a .dockerignore file from disk & 31 | \code{\link[=dockerignore]{dockerignore()}} for creating a new dockerignore object 32 | 33 | Other dockerignore I/O functions: 34 | \code{\link{read_dockerignore}()} 35 | } 36 | \concept{dockerignore I/O functions} 37 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # This file is part of the standard setup for testthat. 2 | # It is recommended that you do not modify it. 3 | # 4 | # Where should you do additional test configuration? 5 | # Learn more about the roles of various files in: 6 | # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview 7 | # * https://testthat.r-lib.org/articles/special-files.html 8 | 9 | library(testthat) 10 | library(dockitect) 11 | 12 | test_check("dockitect") 13 | -------------------------------------------------------------------------------- /tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | # c.f. https://github.com/r-lib/pkgcache/tree/main?tab=readme-ov-file#using-pkgcache-in-cran-packages 2 | 3 | # Temporary directory for R package cache 4 | # Workaround until going full toward renv 5 | Sys.setenv(R_USER_CACHE_DIR = tempfile()) 6 | -------------------------------------------------------------------------------- /tests/testthat/test-dockerfile-core.R: -------------------------------------------------------------------------------- 1 | # Test dockerfile() ---- 2 | test_that("dockerfile(): creates a valid empty dockerfile object", { 3 | df <- dockerfile() 4 | expect_true(is_dockerfile(df)) 5 | expect_type(df, "list") 6 | expect_equal(df$lines, character(0)) 7 | expect_type(df$metadata, "list") 8 | expect_null(df$metadata$base_image) 9 | expect_null(df$metadata$package_manager) 10 | expect_null(df$metadata$r_version) 11 | }) 12 | 13 | # Test is_dockerfile() ---- 14 | test_that("is_dockerfile(): correctly identifies dockerfile objects", { 15 | df <- dockerfile() 16 | expect_true(is_dockerfile(df)) 17 | expect_false(is_dockerfile(list())) 18 | expect_false(is_dockerfile(NULL)) 19 | expect_false(is_dockerfile("string")) 20 | expect_false(is_dockerfile(dockerignore())) 21 | }) 22 | 23 | # Test has_instruction() ---- 24 | test_that("has_instruction(): checks if an instruction exists in a dockerfile", { 25 | df <- dockerfile() 26 | df$lines <- c("FROM ubuntu:24.10", "RUN apt-get update") 27 | 28 | expect_true(has_instruction(df, "FROM")) 29 | expect_true(has_instruction(df, "RUN")) 30 | expect_true(has_instruction(df, "from")) # Case insensitive 31 | expect_false(has_instruction(df, "COPY")) 32 | expect_false(has_instruction(df, "WORKDIR")) 33 | 34 | expect_error(has_instruction("not a dockerfile", "FROM")) 35 | }) 36 | 37 | # Test check_dockerfile() ---- 38 | test_that("check_dockerfile(): validates dockerfile objects", { 39 | df <- dockerfile() 40 | expect_true(check_dockerfile(df)) 41 | expect_error(check_dockerfile("not a dockerfile"), "Expected a dockerfile object") 42 | expect_error(check_dockerfile(NULL), "Expected a dockerfile object") 43 | expect_error(check_dockerfile(dockerignore()), "Expected a dockerfile object") 44 | }) 45 | 46 | # Test check_dockerignore() ---- 47 | test_that("check_dockerignore(): validates dockerignore objects", { 48 | di <- dockerignore() 49 | expect_true(check_dockerignore(di)) 50 | expect_error(check_dockerignore("not a dockerignore"), "Expected a dockerignore object") 51 | expect_error(check_dockerignore(NULL), "Expected a dockerignore object") 52 | expect_error(check_dockerignore(dockerfile()), "Expected a dockerignore object") 53 | }) 54 | 55 | # Test print.dockerfile() ---- 56 | test_that("print.dockerfile(): prints correctly", { 57 | df <- dockerfile() 58 | df$lines <- c("FROM ubuntu:24.10", "RUN apt-get update") 59 | expect_output(print(df), "FROM ubuntu:24.10\nRUN apt-get update") 60 | }) 61 | 62 | # Test add_dockerfile_line() (internal function) ---- 63 | test_that("add_dockerfile_line(): adds line and updates metadata", { 64 | df <- dockerfile() 65 | 66 | # Test adding FROM 67 | df <- add_dockerfile_line(df, "FROM", "ubuntu:24.10") 68 | expect_equal(df$lines, "FROM ubuntu:24.10") 69 | expect_equal(df$metadata$base_image, "ubuntu:24.10") 70 | expect_equal(df$metadata$package_manager, "apt") 71 | 72 | # Test adding RUN 73 | df <- add_dockerfile_line(df, "RUN", "apt-get update") 74 | expect_equal(df$lines, c("FROM ubuntu:24.10", "RUN apt-get update")) 75 | 76 | # Test multi-line command 77 | df <- add_dockerfile_line(df, "RUN", c("apt-get update", "apt-get install -y curl")) 78 | expect_equal(df$lines, c("FROM ubuntu:24.10", "RUN apt-get update", "RUN apt-get update", " apt-get install -y curl")) 79 | 80 | # Test rocker/r-ver image for R version 81 | df <- dockerfile() 82 | df <- add_dockerfile_line(df, "FROM", "rocker/r-ver:4.4.0") 83 | expect_equal(df$metadata$base_image, "rocker/r-ver:4.4.0") 84 | expect_equal(df$metadata$package_manager, "apt") 85 | expect_equal(df$metadata$r_version, "4.4.0") 86 | }) 87 | -------------------------------------------------------------------------------- /tests/testthat/test-dockerfile-instructions.R: -------------------------------------------------------------------------------- 1 | # Test dfi_from() ---- 2 | test_that("dfi_from(): adds FROM instruction correctly", { 3 | df <- dockerfile() 4 | 5 | # Basic usage 6 | df <- dfi_from(df, "ubuntu:24.10") 7 | expect_equal(df$lines[1], "FROM ubuntu:24.10") 8 | 9 | # With AS option 10 | df <- dockerfile() 11 | df <- dfi_from(df, "ubuntu:24.10", as = "build") 12 | expect_equal(df$lines[1], "FROM ubuntu:24.10 AS build") 13 | 14 | # Updates metadata 15 | expect_equal(df$metadata$base_image, "ubuntu:24.10") 16 | expect_equal(df$metadata$package_manager, "apt") 17 | }) 18 | 19 | # Test dfi_run() ---- 20 | test_that("dfi_run(): adds RUN instruction correctly", { 21 | df <- dockerfile() 22 | 23 | # Single command 24 | df <- dfi_run(df, "apt-get update") 25 | expect_equal(df$lines[1], "RUN apt-get update") 26 | 27 | # Multiple commands 28 | df <- dfi_run(df, c("apt-get update", "apt-get install -y curl")) 29 | expect_equal(df$lines[2], "RUN apt-get update && apt-get install -y curl") 30 | }) 31 | 32 | # Test dfi_copy() ---- 33 | test_that("dfi_copy(): adds COPY instruction correctly", { 34 | df <- dockerfile() 35 | 36 | # Basic usage 37 | df <- dfi_copy(df, "src", "dest") 38 | expect_equal(df$lines[1], "COPY src dest") 39 | 40 | # With from option 41 | df <- dfi_copy(df, "src", "dest", from = "build") 42 | expect_equal(df$lines[2], "COPY --from=build src dest") 43 | }) 44 | 45 | # Test dfi_workdir() ---- 46 | test_that("dfi_workdir(): adds WORKDIR instruction correctly", { 47 | df <- dockerfile() 48 | df <- dfi_workdir(df, "/app") 49 | expect_equal(df$lines[1], "WORKDIR /app") 50 | }) 51 | 52 | # Test dfi_cmd() ---- 53 | test_that("dfi_cmd(): adds CMD instruction correctly", { 54 | df <- dockerfile() 55 | 56 | # Single command format 57 | df <- dfi_cmd(df, "echo hello") 58 | expect_equal(df$lines[1], 'CMD [\"echo\",\"hello\"]') 59 | 60 | # Array format 61 | df <- dfi_cmd(df, c("echo", "hello")) 62 | expect_match(df$lines[2], '^CMD \\["echo","hello"\\]$') 63 | }) 64 | 65 | # Test dfi_env() ---- 66 | test_that("dfi_env(): adds ENV instructions correctly", { 67 | df <- dockerfile() 68 | 69 | # Single env var 70 | df <- dfi_env(df, "PATH" = "/usr/local/bin") 71 | expect_equal(df$lines[1], "ENV PATH /usr/local/bin") 72 | 73 | # Multiple env vars 74 | df <- dfi_env(df, HOME = "/home/user", DEBUG = "true") 75 | expect_equal(df$lines[2], "ENV HOME /home/user") 76 | expect_equal(df$lines[3], "ENV DEBUG true") 77 | 78 | # Empty call should return unchanged 79 | df_before <- df 80 | df <- dfi_env(df) 81 | expect_equal(df, df_before) 82 | }) 83 | 84 | # Test dfi_expose() ---- 85 | test_that("dfi_expose(): adds EXPOSE instruction correctly", { 86 | df <- dockerfile() 87 | 88 | # Single port 89 | df <- dfi_expose(df, 8080) 90 | expect_equal(df$lines[1], "EXPOSE 8080") 91 | 92 | # Multiple ports 93 | df <- dfi_expose(df, c(80, 443)) 94 | expect_equal(df$lines[2], "EXPOSE 80 443") 95 | }) 96 | 97 | # Test dfi_label() ---- 98 | test_that("dfi_label(): adds LABEL instruction correctly", { 99 | df <- dockerfile() 100 | 101 | # Single label 102 | df <- dfi_label(df, maintainer = "user@example.com") 103 | expect_equal(df$lines[1], 'LABEL maintainer="user@example.com"') 104 | 105 | # Multiple labels 106 | df <- dfi_label(df, version = "1.0", description = "My image") 107 | expect_equal(df$lines[2], 'LABEL version="1.0" description="My image"') 108 | 109 | # Handle quotes in values 110 | df <- dfi_label(df, quote = 'Contains "quotes"') 111 | expect_equal(df$lines[3], 'LABEL quote=\"Contains \"quotes\"\"') 112 | 113 | # Empty call should return unchanged 114 | df_before <- df 115 | df <- dfi_label(df) 116 | expect_equal(df, df_before) 117 | }) 118 | 119 | # Test dfi_add() ---- 120 | test_that("dfi_add(): adds ADD instruction correctly", { 121 | df <- dockerfile() 122 | df <- dfi_add(df, "http://example.com/file.tar.gz", "/tmp/") 123 | expect_equal(df$lines[1], "ADD http://example.com/file.tar.gz /tmp/") 124 | }) 125 | 126 | # Test dfi_entrypoint() ---- 127 | test_that("dfi_entrypoint(): adds ENTRYPOINT instruction correctly", { 128 | df <- dockerfile() 129 | 130 | # Single command format 131 | df <- dfi_entrypoint(df, "/entrypoint.sh") 132 | expect_equal(df$lines[1], "ENTRYPOINT /entrypoint.sh") 133 | 134 | # Array format 135 | df <- dfi_entrypoint(df, c("/bin/bash", "-c")) 136 | expect_match(df$lines[2], '^ENTRYPOINT \\["/bin/bash","-c"\\]$') 137 | }) 138 | 139 | # Test dfi_user() ---- 140 | test_that("dfi_user(): adds USER instruction correctly", { 141 | df <- dockerfile() 142 | 143 | # Username only 144 | df <- dfi_user(df, "nobody") 145 | expect_equal(df$lines[1], "USER nobody") 146 | 147 | # Username and group 148 | df <- dfi_user(df, "www-data", "www-data") 149 | expect_equal(df$lines[2], "USER www-data:www-data") 150 | 151 | # Numeric UID 152 | df <- dfi_user(df, 1000) 153 | expect_equal(df$lines[3], "USER 1000") 154 | }) 155 | 156 | # Test dfi_volume() ---- 157 | test_that("dfi_volume(): adds VOLUME instruction correctly", { 158 | df <- dockerfile() 159 | 160 | # Single volume 161 | df <- dfi_volume(df, "/data") 162 | expect_equal(df$lines[1], "VOLUME /data") 163 | 164 | # Multiple volumes 165 | df <- dfi_volume(df, c("/data", "/logs")) 166 | expect_match(df$lines[2], '^VOLUME \\["/data","/logs"\\]$') 167 | }) 168 | 169 | # Test dfi_arg() ---- 170 | test_that("dfi_arg(): adds ARG instruction correctly", { 171 | df <- dockerfile() 172 | 173 | # Name only 174 | df <- dfi_arg(df, "VERSION") 175 | expect_equal(df$lines[1], "ARG VERSION") 176 | 177 | # Name with default value 178 | df <- dfi_arg(df, "DEBUG", "false") 179 | expect_equal(df$lines[2], "ARG DEBUG=false") 180 | }) 181 | 182 | # Test dfi_healthcheck() ---- 183 | test_that("dfi_healthcheck(): adds HEALTHCHECK instruction correctly", { 184 | df <- dockerfile() 185 | 186 | # Basic command 187 | df <- dfi_healthcheck(df, "curl -f http://localhost/ || exit 1") 188 | expect_equal(df$lines[1], "HEALTHCHECK CMD curl -f http://localhost/ || exit 1") 189 | 190 | # With options 191 | df <- dfi_healthcheck(df, 192 | "curl -f http://localhost/ || exit 1", 193 | interval = "30s", 194 | timeout = "5s", 195 | start_period = "5s", 196 | retries = 3) 197 | expect_equal(df$lines[2], "HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 CMD curl -f http://localhost/ || exit 1") 198 | }) 199 | 200 | # Test dfi_shell() ---- 201 | test_that("dfi_shell(): adds SHELL instruction correctly", { 202 | df <- dockerfile() 203 | 204 | # Array format directly 205 | df <- dfi_shell(df, '["/bin/bash", "-c"]') 206 | expect_equal(df$lines[1], 'SHELL ["/bin/bash", "-c"]') 207 | 208 | # Array created from vector 209 | df <- dfi_shell(df, c("/bin/sh", "-c")) 210 | expect_match(df$lines[2], '^SHELL \\["/bin/sh","-c"\\]$') 211 | 212 | # String parsed to array 213 | df <- dfi_shell(df, "/bin/bash -c") 214 | expect_match(df$lines[3], '^SHELL \\["[^"]+","[^"]+"\\]$') 215 | }) 216 | 217 | # Test dfi_stopsignal() ---- 218 | test_that("dfi_stopsignal(): adds STOPSIGNAL instruction correctly", { 219 | df <- dockerfile() 220 | df <- dfi_stopsignal(df, "SIGKILL") 221 | expect_equal(df$lines[1], "STOPSIGNAL SIGKILL") 222 | }) 223 | 224 | # Test dfi_maintainer() ---- 225 | test_that("dfi_maintainer(): adds MAINTAINER instruction with warning", { 226 | df <- dockerfile() 227 | expect_warning(df <- dfi_maintainer(df, "user@example.com"), "MAINTAINER is deprecated") 228 | expect_equal(df$lines[1], "MAINTAINER user@example.com") 229 | }) 230 | 231 | # Test dfi_onbuild() ---- 232 | test_that("dfi_onbuild(): adds ONBUILD instruction correctly", { 233 | df <- dockerfile() 234 | df <- dfi_onbuild(df, "RUN npm install") 235 | expect_equal(df$lines[1], "ONBUILD RUN npm install") 236 | }) 237 | -------------------------------------------------------------------------------- /tests/testthat/test-dockerfile-io.R: -------------------------------------------------------------------------------- 1 | # Test read_dockerfile() ---- 2 | test_that("read_dockerfile(): reads Dockerfile correctly", { 3 | # Create a temporary Dockerfile for testing 4 | dockerfile_path <- tempfile(fileext = "") 5 | writeLines(c( 6 | "FROM ubuntu:24.10", 7 | "RUN apt-get update && \\", 8 | " apt-get install -y curl", 9 | "WORKDIR /app", 10 | "COPY . /app/", 11 | "CMD [\"bash\"]" 12 | ), dockerfile_path) 13 | 14 | # Read the Dockerfile 15 | df <- read_dockerfile(dockerfile_path) 16 | expect_true(is_dockerfile(df)) 17 | expect_equal(length(df$lines), 5) # 5 lines after processing continuations 18 | expect_equal(df$metadata$base_image, "ubuntu:24.10") 19 | expect_equal(df$metadata$package_manager, "apt") 20 | 21 | # Test error for missing file 22 | expect_error(read_dockerfile("nonexistent_dockerfile"), "File not found") 23 | 24 | # Clean up 25 | unlink(dockerfile_path) 26 | }) 27 | 28 | # Test write_dockerfile() ---- 29 | test_that("write_dockerfile(): writes Dockerfile correctly", { 30 | # Create a dockerfile 31 | df <- dockerfile() |> 32 | dfi_from("ubuntu:24.10") |> 33 | dfi_run("apt-get update && apt-get install -y curl") |> 34 | dfi_workdir("/app") |> 35 | dfi_cmd("bash") 36 | 37 | # Write to temporary file 38 | dockerfile_path <- tempfile(fileext = "") 39 | expect_message( 40 | write_dockerfile(df, dockerfile_path) 41 | ) 42 | 43 | # Check that file exists 44 | expect_true(file.exists(dockerfile_path)) 45 | 46 | # Read the file back 47 | lines <- readLines(dockerfile_path) 48 | expect_true(any(grepl("^FROM ubuntu:24.10", lines))) 49 | expect_true(any(grepl("^RUN apt-get update", lines))) 50 | expect_true(any(grepl("^WORKDIR /app", lines))) 51 | expect_true(any(grepl('^CMD \\[\"bash\"\\]', lines))) 52 | 53 | # Test multiline formatting 54 | multiline_df <- dockerfile() |> 55 | dfi_from("ubuntu:24.10") |> 56 | dfi_run("apt-get update && apt-get install -y curl && apt-get clean && rm -rf /var/lib/apt/lists/*") 57 | 58 | multiline_path <- tempfile(fileext = "") 59 | expect_message( 60 | write_dockerfile(multiline_df, multiline_path, multiline = TRUE) 61 | ) 62 | 63 | # Check that the long RUN command was split 64 | multilines <- readLines(multiline_path) 65 | expect_true(any(grepl("\\\\$", multilines))) # Check for continuation characters 66 | 67 | # Clean up 68 | unlink(dockerfile_path) 69 | unlink(multiline_path) 70 | }) 71 | -------------------------------------------------------------------------------- /tests/testthat/test-dockerfile-modifications.R: -------------------------------------------------------------------------------- 1 | # Test dfm_add_line() ---- 2 | test_that("dfm_add_line(): adds line at specified position", { 3 | df <- dockerfile() 4 | df$lines <- c("FROM ubuntu:20.04", "RUN apt-get update") 5 | 6 | # Add at the end (default) 7 | df <- dfm_add_line(df, "CMD bash") 8 | expect_equal(df$lines, c("FROM ubuntu:20.04", "RUN apt-get update", "CMD bash")) 9 | 10 | # Add after specific position 11 | df <- dfm_add_line(df, "WORKDIR /app", after = 1) 12 | expect_equal(df$lines, c("FROM ubuntu:20.04", "WORKDIR /app", "RUN apt-get update", "CMD bash")) 13 | 14 | # Add at position out of range (should add at end) 15 | df <- dfm_add_line(df, "USER nobody", after = 10) 16 | expect_equal(df$lines, c("FROM ubuntu:20.04", "WORKDIR /app", "RUN apt-get update", "CMD bash", "USER nobody")) 17 | }) 18 | 19 | # Test dfm_remove_line() ---- 20 | test_that("dfm_remove_line(): removes line at specified position", { 21 | df <- dockerfile() 22 | df$lines <- c("FROM ubuntu:20.04", "WORKDIR /app", "RUN apt-get update", "CMD bash") 23 | 24 | # Remove line 25 | df <- dfm_remove_line(df, 2) 26 | expect_equal(df$lines, c("FROM ubuntu:20.04", "RUN apt-get update", "CMD bash")) 27 | 28 | # Try to remove line out of range (should warn and return unchanged) 29 | expect_warning(df2 <- dfm_remove_line(df, 10), "out of range") 30 | expect_equal(df, df2) 31 | }) 32 | 33 | # Test dfm_replace_line() ---- 34 | test_that("dfm_replace_line(): replaces line at specified position", { 35 | df <- dockerfile() 36 | df$lines <- c("FROM ubuntu:20.04", "WORKDIR /app", "RUN apt-get update") 37 | 38 | # Replace line 39 | df <- dfm_replace_line(df, 2, "WORKDIR /home/user") 40 | expect_equal(df$lines, c("FROM ubuntu:20.04", "WORKDIR /home/user", "RUN apt-get update")) 41 | 42 | # Try to replace line out of range (should warn and return unchanged) 43 | expect_warning(df2 <- dfm_replace_line(df, 10, "CMD bash"), "out of range") 44 | expect_equal(df, df2) 45 | }) 46 | 47 | # Test dfm_move_line() ---- 48 | test_that("dfm_move_line(): moves line from one position to another", { 49 | df <- dockerfile() 50 | df$lines <- c("FROM ubuntu:20.04", "WORKDIR /app", "RUN apt-get update", "CMD bash") 51 | 52 | # Move line up 53 | df <- dfm_move_line(df, 3, 2) 54 | expect_equal(df$lines, c("FROM ubuntu:20.04", "RUN apt-get update", "WORKDIR /app", "CMD bash")) 55 | 56 | # Move line down 57 | df <- dfm_move_line(df, 1, 3) 58 | expect_equal(df$lines, c("RUN apt-get update", "WORKDIR /app", "FROM ubuntu:20.04", "CMD bash")) 59 | 60 | # Try to move line with out of range source (should warn and return unchanged) 61 | expect_warning(df2 <- dfm_move_line(df, 10, 1), "Source line .* is out of range") 62 | expect_equal(df, df2) 63 | 64 | # Try to move line to out of range target (should warn and return unchanged) 65 | expect_warning(df2 <- dfm_move_line(df, 1, 10), "Target position .* is out of range") 66 | expect_equal(df, df2) 67 | }) 68 | 69 | # Test dfm_group_similar() ---- 70 | test_that("dfm_group_similar(): groups similar instructions", { 71 | df <- dockerfile() 72 | df$lines <- c( 73 | "FROM ubuntu:20.04", 74 | "RUN apt-get update", 75 | "RUN apt-get install -y curl", 76 | "WORKDIR /app", 77 | "COPY file1.txt /app/", 78 | "COPY file2.txt /app/" 79 | ) 80 | 81 | # Group similar instructions 82 | grouped <- dfm_group_similar(df) 83 | 84 | # FROM and WORKDIR should remain separate 85 | expect_true(any(grepl("^FROM ", grouped$lines))) 86 | expect_true(any(grepl("^WORKDIR ", grouped$lines))) 87 | 88 | # RUN commands should be combined with && 89 | expect_true(any(grepl("^RUN apt-get update.*&&.*apt-get install", grouped$lines))) 90 | 91 | # COPY commands should remain separate 92 | expect_equal(sum(grepl("^COPY ", grouped$lines)), 2) 93 | 94 | # Test with continuation lines 95 | df <- dockerfile() 96 | df$lines <- c( 97 | "FROM ubuntu:20.04", 98 | "RUN apt-get update \\", 99 | " && apt-get install -y curl", 100 | "RUN echo 'done'" 101 | ) 102 | 103 | grouped <- dfm_group_similar(df) 104 | # The continuation line should be preserved 105 | expect_true(any(grepl("apt-get update", grouped$lines))) 106 | expect_true(any(grepl("echo 'done'", grouped$lines))) 107 | }) 108 | 109 | # Test dfm_sort_by_instruction() ---- 110 | test_that("dfm_sort_by_instruction(): sorts instructions by type", { 111 | df <- dockerfile() 112 | df$lines <- c( 113 | "LABEL maintainer=user@example.com", 114 | "RUN apt-get update", 115 | "FROM ubuntu:20.04", 116 | "WORKDIR /app", 117 | "ENV PATH=/usr/local/bin", 118 | "CMD bash" 119 | ) 120 | 121 | # Sort with default order 122 | sorted <- dfm_sort_by_instruction(df) 123 | 124 | # Check the order of instructions 125 | from_idx <- grep("^FROM ", sorted$lines) 126 | label_idx <- grep("^LABEL ", sorted$lines) 127 | env_idx <- grep("^ENV ", sorted$lines) 128 | workdir_idx <- grep("^WORKDIR ", sorted$lines) 129 | run_idx <- grep("^RUN ", sorted$lines) 130 | cmd_idx <- grep("^CMD ", sorted$lines) 131 | 132 | expect_true(from_idx < label_idx) 133 | expect_true(label_idx < env_idx) 134 | expect_true(env_idx < workdir_idx) 135 | expect_true(workdir_idx < run_idx) 136 | expect_true(run_idx < cmd_idx) 137 | 138 | # Test with custom order 139 | custom_sorted <- dfm_sort_by_instruction(df, order = c("FROM", "WORKDIR", "RUN", "ENV", "LABEL", "CMD")) 140 | 141 | # Check the custom order 142 | from_idx <- grep("^FROM ", custom_sorted$lines) 143 | workdir_idx <- grep("^WORKDIR ", custom_sorted$lines) 144 | run_idx <- grep("^RUN ", custom_sorted$lines) 145 | env_idx <- grep("^ENV ", custom_sorted$lines) 146 | label_idx <- grep("^LABEL ", custom_sorted$lines) 147 | cmd_idx <- grep("^CMD ", custom_sorted$lines) 148 | 149 | expect_true(from_idx < workdir_idx) 150 | expect_true(workdir_idx < run_idx) 151 | expect_true(run_idx < env_idx) 152 | expect_true(env_idx < label_idx) 153 | expect_true(label_idx < cmd_idx) 154 | }) 155 | -------------------------------------------------------------------------------- /tests/testthat/test-dockerignore-core.R: -------------------------------------------------------------------------------- 1 | # Test dockerignore() ---- 2 | test_that("dockerignore(): creates a valid empty dockerignore object", { 3 | di <- dockerignore() 4 | expect_true(is_dockerignore(di)) 5 | expect_type(di, "list") 6 | expect_equal(di$patterns, character(0)) 7 | }) 8 | 9 | # Test is_dockerignore() ---- 10 | test_that("is_dockerignore(): correctly identifies dockerignore objects", { 11 | di <- dockerignore() 12 | expect_true(is_dockerignore(di)) 13 | expect_false(is_dockerignore(list())) 14 | expect_false(is_dockerignore(NULL)) 15 | expect_false(is_dockerignore("string")) 16 | expect_false(is_dockerignore(dockerfile())) 17 | }) 18 | 19 | # Test check_dockerignore() ---- 20 | test_that("check_dockerignore(): validates dockerignore objects", { 21 | di <- dockerignore() 22 | expect_true(check_dockerignore(di)) 23 | expect_error(check_dockerignore("not a dockerignore"), "Expected a dockerignore object") 24 | expect_error(check_dockerignore(NULL), "Expected a dockerignore object") 25 | expect_error(check_dockerignore(dockerfile()), "Expected a dockerignore object") 26 | }) 27 | 28 | # Test print.dockerignore ---- 29 | test_that("print.dockerignore(): prints correctly", { 30 | di <- dockerignore() 31 | di$patterns <- c(".git", "*.Rdata") 32 | expect_output(print(di), ".git\\n\\*.Rdata") 33 | }) 34 | 35 | # Test c.dockerignore() ---- 36 | test_that("c.dockerignore(): combines dockerignore objects correctly", { 37 | di1 <- dockerignore() 38 | di1 <- di_add(di1, c("pattern1", "pattern2")) 39 | 40 | di2 <- dockerignore() 41 | di2 <- di_add(di2, c("pattern3", "pattern4")) 42 | 43 | # Combine with c() 44 | combined <- c(di1, di2) 45 | expect_s3_class(combined, "dockerignore") 46 | 47 | # Check that all patterns are present 48 | expected_patterns <- c("pattern1", "pattern2", "pattern3", "pattern4") 49 | expect_true(all(expected_patterns %in% combined$patterns)) 50 | 51 | # Combine more than two objects 52 | di3 <- dockerignore() 53 | di3 <- di_add(di3, "pattern5") 54 | 55 | combined2 <- c(di1, di2, di3) 56 | expect_true(all(c(expected_patterns, "pattern5") %in% combined2$patterns)) 57 | 58 | # Combine with an empty dockerignore 59 | empty <- dockerignore() 60 | combined3 <- c(empty, di1) 61 | expect_equal(sort(combined3$patterns), sort(di1$patterns)) 62 | 63 | # Test error for non-dockerignore object 64 | expect_error(c(di1, "not-a-dockerignore"), "must be dockerignore objects") 65 | }) 66 | 67 | -------------------------------------------------------------------------------- /tests/testthat/test-dockerignore-instructions.R: -------------------------------------------------------------------------------- 1 | # Test di_add() ---- 2 | test_that("di_add(): adds patterns correctly", { 3 | di <- dockerignore() 4 | 5 | # Test single pattern 6 | di <- di_add(di, "node_modules") 7 | expect_equal(di$patterns, "node_modules") 8 | 9 | # Test adding multiple patterns at once 10 | di <- dockerignore() 11 | di <- di_add(di, c("node_modules", "*.log", "tmp/")) 12 | expect_equal(di$patterns, c("node_modules", "*.log", "tmp/")) 13 | expect_equal(length(di$patterns), 3) 14 | 15 | # Test handling of duplicates 16 | di <- di_add(di, c("node_modules", "build/")) 17 | expect_equal(di$patterns, c("node_modules", "*.log", "tmp/", "build/")) 18 | expect_equal(length(di$patterns), 4) 19 | 20 | # Adding the same pattern again shouldn't duplicate it 21 | di <- di_add(di, "node_modules") 22 | expect_equal(length(di$patterns), 4) 23 | expect_equal(sum(di$patterns == "node_modules"), 1) 24 | }) 25 | 26 | # Test di_remove() ---- 27 | test_that("di_remove(): removes patterns correctly", { 28 | di <- dockerignore() 29 | di <- di_add(di, c("node_modules", "*.log", "tmp/", "build/", ".env")) 30 | 31 | # Test single pattern 32 | di <- di_remove(di, "*.log") 33 | expect_false("*.log" %in% di$patterns) 34 | expect_equal(length(di$patterns), 4) 35 | 36 | # Test removing multiple patterns at once 37 | di <- di_remove(di, c("node_modules", "build/")) 38 | expect_false(any(c("node_modules", "build/") %in% di$patterns)) 39 | expect_equal(di$patterns, c("tmp/", ".env")) 40 | 41 | # Test removing non-existent pattern (should not error) 42 | di_before <- di 43 | di <- di_remove(di, "non-existent-pattern") 44 | expect_equal(di, di_before) 45 | 46 | # Test removing multiple with some non-existent 47 | di <- di_remove(di, c("tmp/", "another-non-existent")) 48 | expect_equal(di$patterns, ".env") 49 | }) 50 | 51 | # Test di_replace() ---- 52 | test_that("di_replace(): replaces patterns correctly", { 53 | di <- dockerignore() 54 | di <- di_add(di, c("logs/", "node_modules/", "tmp/", ".env", "*.cache")) 55 | 56 | # Test single pattern replacement 57 | di <- di_replace(di, "logs/", "log-files/") 58 | expect_true("log-files/" %in% di$patterns) 59 | expect_false("logs/" %in% di$patterns) 60 | 61 | # Test replacing multiple patterns with a single new pattern 62 | di <- di_replace(di, c("node_modules/", "tmp/"), "dependencies/") 63 | expect_false(any(c("node_modules/", "tmp/") %in% di$patterns)) 64 | expect_equal(sum(di$patterns == "dependencies/"), 2) 65 | 66 | # Test replacing with 1:1 mapping (equal length vectors) 67 | di <- dockerignore() 68 | di <- di_add(di, c("logs/", "node_modules/", "tmp/")) 69 | di <- di_replace(di, 70 | c("logs/", "node_modules/", "tmp/"), 71 | c("log-files/", "dependencies/", "temporary/")) 72 | expect_equal(di$patterns, c("log-files/", "dependencies/", "temporary/")) 73 | 74 | # Test error on unequal lengths (when new_pattern > 1) 75 | di <- dockerignore() 76 | di <- di_add(di, c("logs/", "node_modules/")) 77 | expect_error(di_replace(di, 78 | c("logs/", "node_modules/"), 79 | c("log-files/", "dependencies/", "extra/"))) 80 | 81 | # Test handling of non-existent pattern 82 | di <- dockerignore() 83 | di <- di_add(di, "logs/") 84 | di_before <- di 85 | di <- di_replace(di, "non-existent", "replacement") 86 | expect_equal(di, di_before) 87 | }) 88 | -------------------------------------------------------------------------------- /tests/testthat/test-dockerignore-io.R: -------------------------------------------------------------------------------- 1 | # Test read_dockerignore() ---- 2 | test_that("read_dockerignore(): reads .dockerignore correctly", { 3 | # Create a temporary .dockerignore for testing 4 | dockerignore_path <- tempfile(fileext = "") 5 | writeLines(c( 6 | "# Comments should be ignored", 7 | ".git", 8 | "*.log", 9 | "", 10 | "node_modules/" 11 | ), dockerignore_path) 12 | 13 | # Read the .dockerignore 14 | di <- read_dockerignore(dockerignore_path) 15 | expect_true(is_dockerignore(di)) 16 | expect_equal(length(di$patterns), 3) # 3 patterns after filtering 17 | expect_true(".git" %in% di$patterns) 18 | expect_true("*.log" %in% di$patterns) 19 | expect_true("node_modules/" %in% di$patterns) 20 | 21 | # Test error for missing file 22 | expect_error(read_dockerignore("nonexistent_dockerignore"), "File not found") 23 | 24 | # Clean up 25 | unlink(dockerignore_path) 26 | }) 27 | 28 | # Test write_dockerignore() ---- 29 | test_that("write_dockerignore(): writes .dockerignore correctly", { 30 | # Create a dockerignore object 31 | di <- dockerignore() |> 32 | di_add(".git") |> 33 | di_add("*.log") |> 34 | di_add("node_modules/") 35 | 36 | # Write to temporary file 37 | dockerignore_path <- tempfile(fileext = "") 38 | expect_message( 39 | write_dockerignore(di, dockerignore_path) 40 | ) 41 | 42 | # Check that file exists 43 | expect_true(file.exists(dockerignore_path)) 44 | 45 | # Read the file back 46 | lines <- readLines(dockerignore_path) 47 | expect_equal(length(lines), 3) 48 | expect_true(".git" %in% lines) 49 | expect_true("*.log" %in% lines) 50 | expect_true("node_modules/" %in% lines) 51 | 52 | # Clean up 53 | unlink(dockerignore_path) 54 | }) 55 | -------------------------------------------------------------------------------- /tests/testthat/test-dockitect-templates.R: -------------------------------------------------------------------------------- 1 | # Test dk_register_template() ---- 2 | test_that("dk_register_template(): registers and retrieves custom templates", { 3 | # Define a test template 4 | test_template <- function(name = "test") { 5 | dockerfile() |> 6 | dfi_from("ubuntu:24.10") |> 7 | dfi_run(paste("echo", name)) 8 | } 9 | 10 | # Register the template 11 | dk_register_template("test_template", test_template) 12 | 13 | # Use the template 14 | df <- dk_template_custom("test_template", name = "hello") 15 | expect_true(is_dockerfile(df)) 16 | expect_equal(df$lines[1], "FROM ubuntu:24.10") 17 | expect_equal(df$lines[2], "RUN echo hello") 18 | 19 | # Test error for non-existent template 20 | expect_error(dk_template_custom("nonexistent_template"), "Template .* not found") 21 | 22 | # Test error for non-function template 23 | expect_error(dk_register_template("bad_template", "not a function"), "must be a function") 24 | }) 25 | 26 | # Test dk_template_base() ---- 27 | test_that("dk_template_base(): creates a base R dockerfile", { 28 | 29 | df <- dk_template_base(r_version = "4.4.0") 30 | expect_true(is_dockerfile(df)) 31 | expect_true(has_instruction(df, "FROM")) 32 | expect_true(has_instruction(df, "LABEL")) 33 | expect_true(has_instruction(df, "WORKDIR")) 34 | expect_true(has_instruction(df, "RUN")) 35 | expect_true(has_instruction(df, "VOLUME")) 36 | expect_true(has_instruction(df, "CMD")) 37 | 38 | # Check if R version is correct 39 | expect_equal(df$metadata$base_image, "rocker/r-ver:4.4.0") 40 | 41 | # Test with additional packages 42 | df <- dk_template_base(r_version = "4.4.0", additional_pkgs = c("dplyr", "ggplot2")) 43 | expect_true(any(grepl("install.packages", df$lines))) 44 | expect_true(any(grepl("dplyr", df$lines))) 45 | expect_true(any(grepl("ggplot2", df$lines))) 46 | }) 47 | 48 | # Test dk_template_shiny() ---- 49 | test_that("dk_template_shiny(): creates a Shiny app dockerfile", { 50 | 51 | df <- dk_template_shiny(r_version = "4.4.0", port = 3838) 52 | expect_true(is_dockerfile(df)) 53 | expect_true(has_instruction(df, "FROM")) 54 | expect_true(has_instruction(df, "LABEL")) 55 | expect_true(has_instruction(df, "COPY")) 56 | expect_true(has_instruction(df, "WORKDIR")) 57 | expect_true(has_instruction(df, "EXPOSE")) 58 | expect_true(has_instruction(df, "CMD")) 59 | 60 | # Check if base image is correct 61 | expect_equal(df$metadata$base_image, "rocker/shiny:4.4.0") 62 | 63 | # Check if port is exposed 64 | expect_true(any(grepl("EXPOSE 3838", df$lines))) 65 | 66 | # Test with additional packages 67 | df <- dk_template_shiny(r_version = "4.4.0", additional_pkgs = c("dplyr", "ggplot2")) 68 | expect_true(any(grepl("install.packages", df$lines))) 69 | expect_true(any(grepl("dplyr", df$lines))) 70 | expect_true(any(grepl("ggplot2", df$lines))) 71 | }) 72 | 73 | # Test dk_template_plumber() ---- 74 | test_that("dk_template_plumber(): creates a Plumber API dockerfile", { 75 | 76 | df <- dk_template_plumber(r_version = "4.4.0", port = 8000, api_file = "plumber.R") 77 | expect_true(is_dockerfile(df)) 78 | expect_true(has_instruction(df, "FROM")) 79 | expect_true(has_instruction(df, "LABEL")) 80 | expect_true(has_instruction(df, "COPY")) 81 | expect_true(has_instruction(df, "WORKDIR")) 82 | expect_true(has_instruction(df, "EXPOSE")) 83 | expect_true(has_instruction(df, "CMD")) 84 | 85 | # Check if base image is correct 86 | expect_equal(df$metadata$base_image, "rocker/r-ver:4.4.0") 87 | 88 | # Check if port is exposed 89 | expect_true(any(grepl("EXPOSE 8000", df$lines))) 90 | 91 | # Check if plumber is installed 92 | expect_true(any(grepl("plumber", df$lines))) 93 | 94 | # Test with additional packages 95 | df <- dk_template_plumber(r_version = "4.4.0", additional_pkgs = c("dplyr", "jsonlite")) 96 | expect_true(any(grepl("install.packages", df$lines))) 97 | expect_true(any(grepl("dplyr", df$lines))) 98 | expect_true(any(grepl("jsonlite", df$lines))) 99 | }) 100 | -------------------------------------------------------------------------------- /tests/testthat/test-utils.R: -------------------------------------------------------------------------------- 1 | 2 | # Test determine_package_manager() ---- 3 | test_that("determine_package_manager(): detects package manager correctly", { 4 | expect_equal(determine_package_manager("ubuntu:24.10"), "apt") 5 | expect_equal(determine_package_manager("debian:12"), "apt") 6 | expect_equal(determine_package_manager("rocker/r-ver:4.2.0"), "apt") 7 | expect_equal(determine_package_manager("opensuse/leap:15.6"), "zypper") 8 | expect_equal(determine_package_manager("centos:7"), "yum") 9 | expect_equal(determine_package_manager("fedora:35"), "yum") 10 | expect_equal(determine_package_manager("alpine:3.21"), "apk") 11 | expect_equal(determine_package_manager("archlinux:latest"), "pacman") 12 | 13 | # Handle registry paths 14 | expect_equal(determine_package_manager("registry.example.com/ubuntu:20.04"), "apt") 15 | 16 | # Handle null input 17 | expect_null(determine_package_manager(NULL)) 18 | 19 | # Default for unknown 20 | expect_warning(pkg_mgr <- determine_package_manager("unknown:latest")) 21 | expect_equal(pkg_mgr, "apt") 22 | }) 23 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | --------------------------------------------------------------------------------