❝最近由于研究需要,复习下 Docker,找到了本教程,分两次推送,感兴趣的可以跟着学习。原英文网址:http://ropenscilabs.github.io/r-docker-tutorial ❞
这是专门为具有 R 和 RStudio 知识的朋友设计的 Docker 教程。该介绍旨在帮助需要 Docker 进行项目的人们。我们首先解释 Docker 是什么以及为什么有用。然后,我们将详细介绍如何将其用于可复制的分析项目。
在开始之前,请根据自己的操作系统安装下面的链接的介绍安装 Docker
想象一下,你正在 R 中进行分析,然后将代码发送给朋友。你的朋友在完全相同的数据集上运行此代码,但结果略有不同。这可能有多种原因,例如操作系统不同,R 软件包的版本不同等。Docker 可以解决这样的问题。
「可以将Docker容器视为你计算机内部的一台计算机」。这个虚拟计算机的妙处在于你可以将其发送给你的朋友。当他们启动计算机并运行你的代码时,他们将获得与你完全相同的结果。
简单来说,你因为下面的一些原因使用 Docker:
还有一些 Docker 可以发挥用处的地方:
下面会经常出现镜像和容器这两个词。映像的实例称为容器。映像是虚拟计算机的设置。如果运行此映像,将拥有它的一个实例,我们将其称为容器。可以有多个运行相同映像的容器。
首先参考 install Docker[4] 进行安装,没有必要完成链接中所有的教程,有需要再回看它们。
要启动 Docker,我们需要做的第一件事是打开一个 Unix Shell。如果你在 Mac 或 Windows 上,在最后一步,你安装了一个叫做Docker快速启动终端;现在打开它——它看起来应该像一个普通的 shell 提示符(~$
),但实际上它指向的是一个 Docker 默认运行的 linux 虚拟机,而在本教程的其余部分,除非另有说明,你应该在这里完成所有操作。如果您在 linux 机器上,那么您可以使用普通的旧终端提示符。
在 Mac上,你也可以选择终端并配置 Docker。特别是如果你得到错误不能连接到Docker守护进程。Docker 守护进程在此主机上运行吗?。在教程的某个时候,运行下面的命令可能会解决你的问题:
eval "$(docker-machine env default)"
接下来,我们将要求Docker运行一个已经存在的映像,我们将使用来自 Rocker[5] 的 verse Docker映像,它将允许我们在容器内运行RStudio,并且已经安装了许多有用的R包。
docker run --rm -p 8787:8787 -e PASSWORD=yourpassword rocker/verse
--rm
、-p
和 -e
是允许你自定义如何运行容器的标志。-p
告诉 Docker 你将使用一个端口在你的浏览器中看到 RStudio(在一个位置,我们随后指定为端口 8787:8787
)。—rm
确保当我们退出容器时,容器被删除。如果我们不这样做,每次我们运行一个容器,它的一个版本将被保存到我们的本地计算机。这最终会导致大量磁盘空间的浪费,直到我们手动删除这些容器。稍后,我们将向你展示如何保存容器(如果你想这样做的话)。最后,-e
将 PASSWORD
环境变量设置为 yourpassword
。在堆栈中运行带有RStudio的容器时,Rocker 需要你设置密码[6]。出于安全考虑,我们建议你将 yourpassword
更改为您自己独特的字符串。
如果你尝试运行一个没有在本地安装的 Docker 容器,那么Docker会自动在Docker Hub(一个在线的Docker 镜像存储库)上搜索该容器,如果它存在,就下载它。
上面的命令将导致 RStudio-Server 不可见地启动。要连接到它,打开一个浏览器,输入http://
,然后加上你的 ip 地址,再加上:8787
。如果您运行的是 Mac 或 Windows 机器,您将在启动 Docker Quickstart终端时出现在终端中的第一行文本中找到 ip 地址。例如,你应该会看到:
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com
你应该在浏览器中键入 URL http://192.168.99.100:8787
。
如果你在一台 Linux 机器上运行,你可以使用 localhost
作为 ip 地址,例如:http://localhost:8787
这将会将你导向 RStudio 登录界面,使用下面的信息登录:
username: rstudio
password: password
(上面你设置过这个东西)
现在你就可以在浏览器中使用 RStudio 工作了,就像你使用 Rstudio 桌面版一样。
下面是一个截图示例:
现在试试运行下面的代码吧:
# make x the numbers from 1 to 5, and y the numbers from 6-10
x <- 1:5
y <- 6:10
# plot x against y
plot(x, y)
因为我们刚才启动镜像时使用了 --rm
标记,所以在这个机器上创建的任何东西在关闭后都会消失。你可以试试将上面的代码保存为一个文件,然后关闭浏览器,在终端上用 Control+C 关掉容器,然后重新启动容器,看是否创建的文件是否依然存在。
既然数据文件会消失,那么我们退出容器后该如何保存我们的工作呢?一个解决的办法是将一个磁盘(例如你的本地硬盘)与一个容器连接起来,这样你就可以在本地磁盘上访问和保存数据了。
这一次当我们启动容器时使用 -v
标记指定我们项目的根目录,如下所示(你的目录可能有所不同),:
左边是你本地计算机的路径,右边是容器里的路径,一般以 /home/rstudio/
开始(这个镜像已经默认创建了用户名 RStudio 和进行了相关配置)。
docker run --rm -p 8787:8787 -v /Users/tiffanytimbers/Documents/DC/r-docker-tutorial:/home/rstudio/r-docker-tutorial rocker/verse
再一次地,在你的浏览器进行 RStudio。
这一次你在 Docker 容器中启动 RStudio 后,你可以查看到下面映射的文件目录。然后就可以载入数据进行分析工作了:
# load gapminder data from a csv on your computer
gap5yr <- read.csv(file = 'data/gapminder-FiveYearData.csv')
画一个分析图:
# load ggplot library
library(ggplot2)
# plot GDP against life expectancy
qplot(gap5yr$lifeExp, gap5yr$gdpPercap)
# save the plot
ggsave(filename = 'data/GDP_LifeExp.pdf')
让我们将脚本保存为 plot_GDP_LifeExp.R
,然后关闭容器,看在本地目录下是否能看到脚本和绘图文件。
这一课我们学习了如何通过容器在浏览器中运行 RStudio。学习了 --rm
标志的作用和如何连接磁盘文件。
这跟我们使用 RStudio 桌面版没什么区别,试试运行:
# install package
install.packages('gapminder')
# load library
library(gapminder)
# peek at data
head(gapminder)
太好了!现在我们已经安装好包并可以进行工作。但是等等,如果我们退出了容器会发生什么?安装的包会被删除,因为我们没有保存这个版本的 Docker 镜像。我们需要创建一个镜像,这样当利用它创建一个新的容器时,gapminder
包也已经安装好了,可以直接使用。
为了做到这一点,我们需要运行 docker commit
(类似 git commit
)保存修改。记住,这个操作需要在关闭容器前运行,一般我们另外打开一个终端进行这个操作。
我们可以使用下面的命令进行查看(类似 linux ps
命令):
docker ps
输出应该类似下面展示,哈希值记录了容器 ID:
4a6a528b35da rocker/verse "/init" 2 minutes ago Up 2 minutes 0.0.0.0:8787->8787/tcp silly_meninsky
现在我们在新的终端中运行下面命令,并记录修改信息:
docker commit -m "verse + gapminder" 4a6a528b35da verse_gapminder
-m
指定修改信息,哈希值指定了我们要保存的容器,verse_gapminder
为保存的镜像设定了一个名字。
现在我们的电脑上就有 2 个镜像了:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
verse_gapminder latest bb38976d03cf 57 seconds ago 1.955 GB
rocker/verse latest 0168d115f220 3 days ago 1.954 GB
现在你可以测试下新镜像的工作情况。
许多 R 包有外部依赖,如 GSL, GDAL, JAGS,为了安装它们,你需要进行如下的操作:
docker ps # find the ID of the running container you want to add a package to
docker exec -it <container-id> bash # a docker command to start a bash shell in your container
apt-get install libgsl0-dev # install the package, in this case GSL
如果安装报错,先试试 apt-get update
为了保存安装的依赖,依旧需要进行修改的提交:
docker commit -m "verse + gapminder + GSL" <container id> verse_gapminder_gsl
Docker Hub[7] 是一个存储 Docker 镜像的地方,当我们运行下面的命令时,软件首选检查镜像是否存在于你的计算机上。如果不存在,它会自动去 Docker Hub 搜索和下载。
docker run --rm -p 8787:8787 rocker/verse
如果你想要从 Docker Hub 上拉取镜像而不运行它,可以使用命令:
docker pull rocker/verse
想象一下如果你自己创建了一个镜像,然后想要与其他人分享,你可以在 https://hub.docker.com/ 创建一个账号。验证完邮箱之后,你就可以将你的镜像上传了:
docker login --username=yourhubusername --email=youremail@company.com
如果没问题应该会看到下面的信息
WARNING: login credentials saved in /home/username/.docker/config.json
Login Succeeded
docker images
然后你会看到类似下面的输出:
REPOSITORY TAG IMAGE ID CREATED SIZE
verse_gapminder_gsl latest 023ab91c6291 3 minutes ago 1.975 GB
verse_gapminder latest bb38976d03cf 13 minutes ago 1.955 GB
rocker/verse latest 0168d115f220 3 days ago 1.954 GB
docker tag bb38976d03cf yourhubusername/verse_gapminder:firsttry
这里镜像 ID 必须匹配,fisttry
是标签,一般选择一些容易识别的标签。docker push yourhubusername/verse_gapminder
现在所有人都可以使用你的镜像了!
将镜像推送到 Docker Hub 非常使用,但它有些缺点:
解决方案的在本地对你的镜像进行存档,这样你可以在需要的时候轻松载入。
为了这一目的,你可以使用 docker save
命令。让我们试试吧:
docker save verse_gapminder > verse_gapminder.tar
如果我们想要从存档中载入镜像,使用下面的命令:
docker load --input verse_gapminder.tar
[1]
mac: https://docs.docker.com/mac/step_one/
[2]
linux: https://docs.docker.com/linux/step_one/
[3]
windows: https://docs.docker.com/windows/step_one/
[4]
install Docker: https://docs.docker.com/engine/getstarted/step_one/
[5]
Rocker: https://github.com/rocker-org/rocker/wiki
[6]
需要你设置密码: https://github.com/rocker-org/rocker-versioned/blob/master/rstudio/README.md
[7]
Docker Hub: https://hub.docker.com/