Skip to content

Commit ba963a3

Browse files
committed
Add vignette on creating a running container
1 parent 8d746a5 commit ba963a3

File tree

2 files changed

+242
-0
lines changed

2 files changed

+242
-0
lines changed

_pkgdown.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ articles:
109109
Learn how to use dockitect to create and manage Docker files for R projects
110110
contents:
111111
- getting-started-with-dockitect
112+
- making-a-dockitect-dockerfile-into-a-running-container
112113

113114
home:
114115
sidebar:
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
---
2+
title: "Making a dockitect Dockerfile into a Running Container"
3+
output: rmarkdown::html_vignette
4+
vignette: >
5+
%\VignetteIndexEntry{Making a dockitect Dockerfile into a Running Container}
6+
%\VignetteEngine{knitr::rmarkdown}
7+
%\VignetteEncoding{UTF-8}
8+
---
9+
10+
```{r, include = FALSE}
11+
knitr::opts_chunk$set(
12+
collapse = TRUE,
13+
comment = "#>"
14+
)
15+
16+
Sys.setenv(R_USER_CACHE_DIR = tempfile())
17+
```
18+
19+
## Introduction
20+
21+
After creating a Dockerfile with `dockitect`, the next steps involve building a
22+
Docker image and running it as a container. This vignette walks through this
23+
process with practical examples, assuming you have Docker installed on your system.
24+
25+
If you haven't installed Docker yet, visit the [Docker installation page](https://docs.docker.com/get-docker/) for instructions specific to your
26+
operating system.
27+
28+
## Building Your Docker Image
29+
30+
Once you've generated a Dockerfile with `dockitect`, you'll need to build a
31+
Docker image from it. This is done by interacting with Docker on the
32+
command-line interface:
33+
34+
```bash
35+
# Basic build command
36+
docker build -t my-r-project .
37+
38+
# Build with a specific tag (e.g., for versioning)
39+
docker build -t my-r-project:1.0.0 .
40+
41+
# Build with build arguments (if your Dockerfile uses ARG)
42+
docker build --build-arg R_VERSION=4.4.0 -t my-r-project .
43+
```
44+
45+
The `-t` option tags your image with a name, making it easier to reference later.
46+
The `.` at the end tells Docker to look for a `Dockerfile` in the current directory.
47+
48+
During the build process, Docker will execute each instruction in your
49+
`Dockerfile` sequentially and create a series of intermediate layers. These
50+
layers are cached, which means subsequent builds can be much faster if parts
51+
of your `Dockerfile` haven't changed.
52+
53+
:::{.callout-tip}
54+
Effective use of layer caching can significantly speed up your Docker image builds.
55+
:::
56+
57+
## Running Containers Based on Your Image
58+
59+
After building the image, you can run it as a container using various configurations:
60+
61+
```bash
62+
# Basic run command
63+
docker run my-r-project
64+
65+
# Run interactively with a shell
66+
docker run -it my-r-project bash
67+
68+
# Run with environment variables
69+
docker run -e "DEBUG=TRUE" my-r-project
70+
71+
# Run with a volume for data persistence
72+
docker run -v $(pwd)/data:/app/data my-r-project
73+
74+
# Run a Shiny app with port mapping
75+
docker run -p 3838:3838 my-shiny-app
76+
```
77+
78+
Here's what these options do:
79+
80+
- `-it`: Provides an interactive terminal
81+
- `-p 3838:3838`: Maps port 3838 from the container to port 3838 on your host
82+
- `-e "DEBUG=TRUE"`: Sets an environment variable inside the container
83+
- `-v $(pwd)/data:/app/data`: Mounts your local directory to a location in the container
84+
85+
For Shiny apps and Plumber APIs, the `-p` flag is crucial as it maps a port
86+
from the container to your host machine, allowing you to access the web application.
87+
88+
## Container Management
89+
90+
Here are some useful commands for managing your Docker containers and images:
91+
92+
```bash
93+
# List running containers
94+
docker ps
95+
96+
# List all containers (including stopped ones)
97+
docker ps -a
98+
99+
# Stop a running container
100+
docker stop <container_id>
101+
102+
# Remove a container
103+
docker rm <container_id>
104+
105+
# List images
106+
docker images
107+
108+
# Remove an image
109+
docker rmi my-r-project
110+
```
111+
112+
You can refer to containers by either their ID (shown in `docker ps`) or by
113+
the name assigned when running them. If you don't specify a name with `--name`
114+
when starting a container, Docker assigns a random name.
115+
116+
## Example Workflows
117+
118+
### Complete Workflow for a Shiny App
119+
120+
Let's walk through a complete workflow for containerizing a Shiny application:
121+
122+
```{r}
123+
#| eval: false
124+
# 1. Generate the Dockerfile
125+
library(dockitect)
126+
dk_template_shiny(
127+
r_version = "4.4.0",
128+
port = 3838,
129+
app_dir = "shiny_app/"
130+
) |>
131+
write_dockerfile()
132+
```
133+
134+
Then, in your terminal:
135+
136+
```bash
137+
# 2. Build the Docker image
138+
## Note: For ARM-based systems, use --platform linux/amd64.
139+
docker build --platform linux/amd64 -t my-shiny-app .
140+
141+
# 3. Run the container
142+
docker run -p 3838:3838 my-shiny-app
143+
```
144+
145+
Now you can access your Shiny app by navigating to <http://localhost:3838/app> in your web browser.
146+
147+
### Running an R Script with Volume Mounting
148+
149+
For data analysis scripts, you often want to share data between your host and the container:
150+
151+
```{r}
152+
#| eval: false
153+
# 1. Generate the Dockerfile
154+
library(dockitect)
155+
dk_from_script("analysis.R") |>
156+
write_dockerfile()
157+
```
158+
159+
Then, in your terminal:
160+
161+
```bash
162+
# 2. Build the Docker image
163+
docker build -t my-analysis .
164+
165+
# 3. Run with volume mounting for input/output
166+
docker run -v $(pwd)/data:/app/data -v $(pwd)/results:/app/results my-analysis
167+
```
168+
169+
This mounts your local `data` and `results` directories to the container,
170+
allowing your R script to read input data and write results that persist after
171+
the container exits.
172+
173+
### Running an R Environment for Interactive Use
174+
175+
For interactive data analysis, you might want a container with specific packages and dependencies:
176+
177+
```{r}
178+
#| eval: false
179+
# 1. Generate a Dockerfile with your packages
180+
library(dockitect)
181+
dk_template_base(
182+
r_version = "4.4.3",
183+
additional_pkgs = c("visualize")
184+
) |>
185+
write_dockerfile()
186+
```
187+
188+
In your terminal:
189+
190+
```bash
191+
# 2. Build the image
192+
docker build -t r-interactive .
193+
194+
# 3. Run interactively with volume mount for your project files
195+
docker run -it -v $(pwd):/app r-interactive R
196+
```
197+
198+
This gives you an interactive R session with all your packages pre-installed, and your current directory mounted so you can access your files.
199+
200+
## Troubleshooting Common Issues
201+
202+
### Build Fails with Package Installation Errors
203+
204+
If your build fails during package installation, it might be due to missing
205+
system dependencies. The `dk_add_sysreqs()` function in `dockitect` can help
206+
with this:
207+
208+
```{r}
209+
#| eval: false
210+
# Add system requirements for specific packages
211+
df <- dockerfile() |>
212+
dfi_from("rocker/r-ver:4.4.3") |>
213+
dk_add_sysreqs(c("tidyverse", "rJava"))
214+
```
215+
216+
### Container Exits Immediately
217+
218+
If your container exits immediately after starting, it might be because the CMD
219+
instruction in your `Dockerfile` is not designed to keep the container running.
220+
For services, ensure the `CMD` runs a process that stays in the foreground.
221+
222+
### Cannot Access Shiny App or Plumber API
223+
224+
Make sure you've mapped the ports correctly with the `-p` flag and your
225+
application is configured to listen on all interfaces inside the container.
226+
For Shiny apps, this can be set with:
227+
228+
```r
229+
options(shiny.host = '0.0.0.0')
230+
```
231+
232+
## Conclusion
233+
234+
While `{dockitect}` simplifies `Dockerfile` creation, understanding how to build,
235+
run, and manage Docker containers is required for the complete workflow. This
236+
vignette covered the basics of working with Docker after generating your
237+
`Dockerfile` via `{dockitect}`.
238+
239+
For more information, consult the [Docker documentation](https://docs.docker.com/)
240+
or the [Rocker project](https://www.rocker-project.org/) which provides pre-built
241+
Docker images for R.

0 commit comments

Comments
 (0)