{"id":15578140,"url":"https://github.com/dmolitor/tugboat","last_synced_at":"2025-04-12T04:04:46.642Z","repository":{"id":204390908,"uuid":"701405193","full_name":"dmolitor/tugboat","owner":"dmolitor","description":"Quickly turn your analysis directory into a Docker image.","archived":false,"fork":false,"pushed_at":"2025-01-11T21:02:15.000Z","size":8301,"stargazers_count":22,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T04:04:35.790Z","etag":null,"topics":["docker","reproducible-research","rstats"],"latest_commit_sha":null,"homepage":"http://www.dmolitor.com/tugboat/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmolitor.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-10-06T15:03:30.000Z","updated_at":"2025-03-31T20:19:09.000Z","dependencies_parsed_at":"2024-12-11T20:22:12.915Z","dependency_job_id":"bf3ad331-a65e-4bab-8599-8f9fc4c24a63","html_url":"https://github.com/dmolitor/tugboat","commit_stats":{"total_commits":20,"total_committers":2,"mean_commits":10.0,"dds":0.25,"last_synced_commit":"ce0f10f01acb5279a3aae080595f3130dc511575"},"previous_names":["dmolitor/tugboat"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmolitor%2Ftugboat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmolitor%2Ftugboat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmolitor%2Ftugboat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmolitor%2Ftugboat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmolitor","download_url":"https://codeload.github.com/dmolitor/tugboat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514229,"owners_count":21116903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","reproducible-research","rstats"],"created_at":"2024-10-02T19:06:16.710Z","updated_at":"2025-04-12T04:04:46.626Z","avatar_url":"https://github.com/dmolitor.png","language":"R","funding_links":[],"categories":["R"],"sub_categories":[],"readme":"# tugboat \u003cimg src='man/figures/logo-no-bg.png' align=\"right\" height=\"140\"/\u003e\n\n\u003c!-- badges: start --\u003e\n[![R-CMD-check](https://github.com/dmolitor/tugboat/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/dmolitor/tugboat/actions/workflows/R-CMD-check.yaml)\n[![pkgdown](https://github.com/dmolitor/tugboat/actions/workflows/pkgdown.yaml/badge.svg)](https://github.com/dmolitor/tugboat/actions/workflows/pkgdown.yaml)\n[![CRAN status](https://www.r-pkg.org/badges/version/tugboat)](https://CRAN.R-project.org/package=tugboat)\n\u003c!-- badges: end --\u003e\n\nA simple R package to generate a Dockerfile and corresponding Docker image\nfrom an analysis directory. tugboat uses the [renv](https://github.com/rstudio/renv/) package to automatically\ndetect all the packages necessary to replicate your analysis and will generate\na Dockerfile that contains an exact copy of your entire directory with all\nthe packages installed.\n\ntugboat transforms an unstructured analysis folder into a renv.lock file\nand constructs a Docker image that includes all your essential R packages\nbased on this lockfile.\n\ntugboat may be of use, for example, when preparing a replication package for\nresearch. With tugboat, you can take a directory on your local computer\nand quickly generate a Dockerfile and Docker image that contains all the\ncode and the necessary software to reproduce your findings.\n\n## Installation\n\nInstall tugboat from CRAN:\n```r\ninstall.packages(\"tugboat\")\n```\n\nOr install the development version from GitHub:\n```r\n# install.packages(\"pak\")\npak::pkg_install(\"dmolitor/tugboat\")\n```\n\n## Usage\n\ntugboat only has two exported functions; one to create a Dockerfile from your\nanalysis directory, and one to build the corresponding Docker image.\n\n### Create the Dockerfile\n\nThe primary function from tugboat is `create()`. This function converts \nyour analysis directory into a Dockerfile that includes all your code \nand essential R packages.\n\nThis function scans all files in the current analysis directory,\nattempts to detect all R packages, and installs these packages in\nthe resulting Docker image. It also copies the entire contents of the\nanalysis directory into the Docker image. For example, if\nyour analysis directory is named `incredible_analysis`, the corresponding\nlocation of your code and data files in the generated Docker image will\nbe `/incredible_analysis`.\n\nFor the most common use-cases, there are a couple of arguments in this\nfunction that are particularly important:\n\n- `project`: This argument tells tugboat which directory is the one to generate\nthe Dockerfile from. You can set this value yourself, or you can just use\nthe default value. By default, tugboat uses the `here::here` function to\ndetermine what directory is the analysis directory. To get a detailed understanding\nof exactly how this works take a look at the [here package](https://github.com/r-lib/here/).\nIn general, this \"just works\"!\n- `as`: This argument tells tugboat where to save the Dockerfile. In\ngeneral you don't need to set this and tugboat will just save the\nDockerfile in the `project` directory from above.\n- `exclude`: A vector of files or sub-directories in your analysis directory\nthat should ***NOT*** be included in the Docker image. This is particularly\nimportant when you have, for example, a sub-directory with large data files\nthat would make the resulting Docker image extremely large if included. You\ncan tell tugboat to exclude this sub-directory and then simply mount it to\na Docker container as needed.\n\nBelow I'll outline a couple examples.\n```r\nlibrary(tugboat)\n\n# The simplest scenario where your analysis directory is your current\n# active project, you are fine with the default base \"r-base:latest\"\n# Docker image, and you want to include all files/directories:\ncreate()\n\n# Suppose your analysis directory is actually a sub-directory of your\n# main project directory:\ncreate(project = here::here(\"sub-directory\"))\n\n# Suppose that you specifically need a Docker base image that has RStudio\n# installed so that you can interact with your analysis within a Docker \n# container. To do this, we will explicitly specify a different Docker\n# base image using the `FROM` argument.\ncreate(FROM = \"rocker/rstudio\")\n\n# Finally, suppose that we want to include all files except a couple\n# particularly data-heavy sub-directories:\ncreate(exclude = c(\"data/big_directory_1\", \"data/big_directory_2\"))\n```\n\n### Build the Docker image\n\nOnce the Dockerfile has been created, we can build the Docker image\nwith the `build()` function. By default this will infer the Dockerfile\ndirectory using `here::here`. This function assumes a little knowledge\nabout Docker; if you aren't sure where to start,\n[this is a great starting point](https://colinfay.me/docker-r-reproducibility/).\n\nThe following example will do the simplest thing and will build the\nimage locally.\n```r\nbuild(image_name = \"awesome_analysis\")\n```\n\nSuppose that, like above, your analysis directory is a sub-directory of\nyour main project directory:\n```r\nbuild(\n  dockerfile = here::here(\"sub-directory\"),\n  image_name = \"awesome_analysis\"\n)\n```\n\n### Push to DockerHub\n\nIf, instead of just building the Docker image locally, you want to build\nthe image and then push to DockerHub, you can make a couple small additions\nto the code above:\n```r\nbuild(\n  image_name = \"awesome_analysis\",\n  push = TRUE,\n  dh_username = Sys.getenv(\"DH_USERNAME\"),\n  dh_password = Sys.getenv(\"DH_PASSWORD\")\n)\n```\n\nNote: If you choose to push, you also need to provide your DockerHub\nusername and password. Typically you don't want to pass these in\ndirectly and should instead use environment variables (or a similar\nmethod) instead.\n\n## Why tugboat? 🚢\n\nThere are a few available packages with similar goals, so why tugboat?\ntugboat is minimal and builds directly on top of\n[`renv`](https://rstudio.github.io/renv/articles/renv.html) and\n[`pak`](https://pak.r-lib.org/).\nEach of these packages is actively maintained and provides specific\nutilities that the tugboat utilizes for maximum convenience.\ntugboat aims to leverage packages that are likely to remain actively\nmaintained and handle dependency management as seamlessly as possible.\n\n- [containerit](https://o2r.info/containerit/) is a robust package that is\ndirectly comparable to tugboat. However, it implements its own method for\ndiscovering R package dependencies instead of using renv. It also relies on\n[sysreqsdb](https://github.com/r-hub/sysreqsdb) for system dependency\ndiscovery, which has been archived in favor of\n[r-system-requirements](https://github.com/rstudio/r-system-requirements),\nwhich pak is built on. It also isn't super actively maintained and isn't on\nCRAN.\n\n- [holepunch](https://github.com/karthik/holepunch) is related but focuses\non making GitHub repositories Binder-compatible. It currently relies on MRAN,\nwhich is now obsolete, and does not use pak for system dependency management.\nIt is also not actively maintained and is not on CRAN.\n\n- [automagic](https://github.com/cole-brokamp/automagic) focuses on\nautomatically detecting and installing R package dependencies but uses its own\nmethod rather than relying on renv. automagic also has no utilities for\ncreating/building Docker images.\n\n\n## Examples\n\nFor some worked examples of how to use tugboat in practice, see the\n`examples/` directory.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmolitor%2Ftugboat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmolitor%2Ftugboat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmolitor%2Ftugboat/lists"}