|
| 1 | +--- |
| 2 | +output: github_document |
| 3 | +--- |
| 4 | + |
| 5 | +<!-- README.md is generated from README.Rmd. Please edit that file --> |
| 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 <img src="man/figures/dockitect-animated-logo.svg" align="right" height="139" /> |
| 17 | + |
| 18 | +<!-- badges: start --> |
| 19 | +[](https://github.com/coatless-rpkg/dockitect/actions/workflows/R-CMD-check.yaml) |
| 20 | +<!-- badges: end --> |
| 21 | + |
| 22 | +> Create and Validate Dockerfiles from R |
| 23 | +
|
| 24 | +`dockitect` is an R package for programmatically creating, validating, and |
| 25 | +managing Dockerfiles using a pipe-friendly syntax. It bridges the gap between |
| 26 | +R development and containerization, enabling seamless Docker integration for |
| 27 | +data science workflows. |
| 28 | + |
| 29 | +> \[!IMPORTANT\] |
| 30 | +> |
| 31 | +> This package is currently in the prototype/experimental stage. It is |
| 32 | +> not yet available on CRAN and may have bugs or limitations. |
| 33 | +
|
| 34 | +## Installation |
| 35 | + |
| 36 | +You can install the development version of `dockitect` from |
| 37 | +[GitHub](https://github.com/coatless-rpkg/dockitect) with: |
| 38 | + |
| 39 | +```{r} |
| 40 | +#| label: setup |
| 41 | +#| eval: false |
| 42 | +# install.packages("remotes") |
| 43 | +remotes::install_github("coatless-rpkg/dockitect") |
| 44 | +``` |
| 45 | + |
| 46 | + |
| 47 | +## Design Philosophy |
| 48 | + |
| 49 | +To make the API intuitive and discoverable, `dockitect` employs a naming |
| 50 | +convention across all its functions. Understanding these prefixes will |
| 51 | +help you navigate the package and find the functions you need: |
| 52 | + |
| 53 | +- `dockerfile()` - Create a new Dockerfile object |
| 54 | + - `dfi_*()` - **D**ockerfile **i**nstruction functions (e.g., `dfi_from()`, `dfi_run()`) |
| 55 | + - `dfm_*()` - **D**ockerfile **m**odification functions (e.g., `dfm_add_line()`, `dfm_group_similar()`) |
| 56 | +- `dockerignore()` - Create a new Dockerignore object |
| 57 | + - `di_*()` - **D**ockerignore functions (e.g., `di_add()`, `di_remove()`) |
| 58 | +- `dk_*()` - **D**oc**k**er configuration/template functions (e.g., `dk_from_session()`, `dk_template_shiny()`) |
| 59 | + |
| 60 | +## Usage |
| 61 | + |
| 62 | +The following examples demonstrate how to use `dockitect` for various |
| 63 | +containerization scenarios. Each example showcases different aspects of the |
| 64 | +package's functionality, from basic Dockerfile creation to more advanced use cases. |
| 65 | + |
| 66 | +### Dockerfile Creation |
| 67 | + |
| 68 | +Let's start with the fundamentals. Creating a Dockerfile typically involves |
| 69 | +specifying a base image, installing dependencies, copying files, and defining |
| 70 | +commands. With `dockitect`, this process becomes a series of intuitive pipe-chained functions. |
| 71 | + |
| 72 | +For example, let's create a Dockerfile for an R script: |
| 73 | + |
| 74 | +```{r} |
| 75 | +#| label: basic-dockerfile |
| 76 | +#| eval: false |
| 77 | +library(dockitect) |
| 78 | +
|
| 79 | +# Create a basic Dockerfile for an R script |
| 80 | +dockerfile() |> |
| 81 | + dfi_from("rocker/r-ver:4.2.3") |> |
| 82 | + dfi_label(maintainer = "[email protected]") |> |
| 83 | + dfi_run("apt-get update && apt-get install -y libcurl4-openssl-dev") |> |
| 84 | + dfi_workdir("/app") |> |
| 85 | + dfi_copy("analysis.R", "/app/") |> |
| 86 | + dfi_cmd("Rscript analysis.R") |> |
| 87 | + write_dockerfile("Dockerfile") |
| 88 | +``` |
| 89 | + |
| 90 | +### Use Templates |
| 91 | + |
| 92 | +`dockitect` includes specialized templates for common R application types, |
| 93 | +saving you time and ensuring best practices are followed. These templates are |
| 94 | +fully customizable and provide a solid foundation for your projects. |
| 95 | + |
| 96 | +#### Shiny Application |
| 97 | + |
| 98 | +Creating a Docker container for a Shiny application requires specific |
| 99 | +configurations for ports, networking, and dependencies. The Shiny template |
| 100 | +handles these details automatically. For example, we can create a Dockerfile |
| 101 | +for a Shiny app with proper port configuration: |
| 102 | + |
| 103 | +```{r} |
| 104 | +#| label: shiny-template-demo |
| 105 | +#| eval: false |
| 106 | +# Create a Dockerfile for a Shiny app |
| 107 | +dk_template_shiny( |
| 108 | + r_version = "4.2.3", # Specify R version |
| 109 | + port = 3838, # Expose Shiny port |
| 110 | + app_dir = "app/" # Location of app files |
| 111 | +) |> |
| 112 | + dfi_env(SHINY_HOST = "0.0.0.0") |> # Configure Shiny to listen on all interfaces |
| 113 | + write_dockerfile() |
| 114 | +``` |
| 115 | + |
| 116 | +### Custom Templates |
| 117 | + |
| 118 | +While `dockitect` includes templates for common scenarios, your organization |
| 119 | +might have specific containerization patterns. The template system is |
| 120 | +extensible, allowing you to create, register, and reuse your own templates |
| 121 | +throughout your projects: |
| 122 | + |
| 123 | +```{r} |
| 124 | +#| label: custom-template-demo |
| 125 | +#| eval: false |
| 126 | +# Create a custom template function |
| 127 | +my_template <- function(my_param = "default") { |
| 128 | + dockerfile() |> |
| 129 | + dfi_from("rocker/r-ver:4.2.3") |> |
| 130 | + dfi_run(paste0("echo ", my_param)) |
| 131 | +} |
| 132 | +
|
| 133 | +# Register the template |
| 134 | +dk_register_template("my_template", my_template) |
| 135 | +
|
| 136 | +# Use the template |
| 137 | +dk_template_custom("my_template", my_param = "hello") |> |
| 138 | + write_dockerfile() |
| 139 | +``` |
| 140 | + |
| 141 | + |
| 142 | +### Modify Existing Dockerfiles |
| 143 | + |
| 144 | +Sometimes you need to modify existing Dockerfiles rather than creating them |
| 145 | +from scratch. `dockitect` provides specialized functions for reading, modifying, |
| 146 | +and writing Dockerfiles, allowing for precise changes without manual text editing: |
| 147 | + |
| 148 | +```{r} |
| 149 | +#| label: existing-dockerfile-modifications |
| 150 | +#| eval: false |
| 151 | +# Read an existing Dockerfile |
| 152 | +df <- read_dockerfile("path/to/Dockerfile") |
| 153 | +
|
| 154 | +# Modify it |
| 155 | +df |> |
| 156 | + dfm_add_line("RUN echo 'Hello World'", after = 3) |> # Add a line after line 3 |
| 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 | + di_add_common(include_git = TRUE, include_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 | +## Citation |
| 181 | + |
| 182 | +If you use `dockitect` in your research or project, please consider citing it: |
| 183 | + |
| 184 | +```r |
| 185 | +citation("dockitect") |
| 186 | +``` |
| 187 | + |
| 188 | +## License |
| 189 | + |
| 190 | +AGPL (>=3) |
0 commit comments