# 构建镜像: Rstudio + R4.1.0 + Seurat 4.0.5 > Create on 2021/10/25 by [Dawneve](https://github.com/dawneve) | [Biomooc](//www.biomooc.com) / [Docker](/linux/docker-tutorial.html) --- 镜像信息: - 构建的镜像是 R4.1.0 + Rstudio server + Seurat 4.0.5; 默认用户 rstudio,带sudo权限。 - 想直接使用镜像的,请看第3: `$ docker pull dawneve/seurat:4.0.5r1` --- 有3个方案: - 全新镜像,安装 R, Rstudio, Seurat; - Rstudio 基础镜像,安装 Seurat; - Seurat 基础镜像,安装Rstudio; 方案1太繁琐了,另外两个方案各有优劣。本文选择第三个,因为它只需要安装Rstudio即可使用。 --- 前提准备: ``` # 要先安装好最新版的 docker。 $ docker --version Docker version 20.10.9, build c2ea9bc # 本文示例宿主机是 CentOS 7.9。使用普通用户,在 docker 组。 ``` ## 1. 拉取基础镜像、安装文件 (1) 空镜像(可选) $ docker pull ubuntu:20.04 (2) Rstudio 基础镜像(可选) [Rstudio 专栏](https://environments.rstudio.com/docker) 提到 **Rocker Project**: The Rocker project is a community driven effort to create a series of self-contained images for R development. These images can often be used as “virtual machines”. The image labels define their contents, e.g. the rocker/tidyverse image includes R and the tidyverse packages. The tag specifies the specific version of R used in the image. These images are all based off of the Debian OS. [The Rocker Project](https://www.rocker-project.org/): Docker Containers for the R Environment. ``` https://hub.docker.com/r/rocker/rstudio 最新版是 4.1.1 $ docker pull rocker/rstudio:4.1.1 ``` (3) Seurat 基础镜像 Seurat 官网 install 目录下最后几行(2021/10/1): We provide docker images for Seurat via dockerhub. To use as a base image in a new Dockerfile: `FROM satijalab/seurat:latest` ``` https://hub.docker.com/r/satijalab/seurat 最新版是 4.0.5 $ docker pull satijalab/seurat:4.0.5 如果一直拉取失败,只能让 其他人/国外朋友 拉取后打包发过来,再导入。 打包为tar命令 $ docker save -o seurat_4.0.5.tar satijalab/seurat:4.0.5 由tar包导入的命令 $ docker load < seurat_4.0.5.tar ``` (4) 检查下载的镜像 ``` $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 20.04 ba6acccedd29 7 days ago 72.8MB rocker/rstudio 4.1.1 089c6b053857 3 days ago 1.89GB satijalab/seurat 4.0.5 3bf89a0bbbfb 3 days ago 3.67GB ``` 本文使用最后一个,其他2个作为学习/测试用。 查看构建镜像所用过的命令 ``` 我们发现,镜像 satijalab/seurat:4.0.5 也是基于 rocker 项目的。 $ docker history satijalab/seurat:4.0.5 输出到文件查看,比较直观 $ docker history --no-trunc satijalab/seurat:4.0.5 > ~/tmp.txt $ less -S ~/tmp.txt ``` ## 2. 开始构建镜像 以下操作都是在 ~/dockerBuild/4.1.0/ 下进行。 (1) ubuntu 版的 [Rstudio](https://www.rstudio.com/products/rstudio/download-server/debian-ubuntu/) 安装方法 ``` sudo apt-get install gdebi-core wget https://download2.rstudio.org/server/bionic/amd64/rstudio-server-2021.09.0-351-amd64.deb sudo gdebi rstudio-server-2021.09.0-351-amd64.deb ``` 先下载该deb文件: ``` $ wget https://download2.rstudio.org/server/bionic/amd64/rstudio-server-2021.09.0-351-amd64.deb ``` (2) 学习 镜像中安装 Rstudio 的脚本 ``` https://github.com/rocker-org/rocker-versioned2/blob/master/dockerfiles/rstudio_4.1.1.Dockerfile FROM rocker/r-ver:4.1.1 LABEL org.opencontainers.image.licenses="GPL-2.0-or-later" \ org.opencontainers.image.source="https://github.com/rocker-org/rocker-versioned2" \ org.opencontainers.image.vendor="Rocker Project" \ org.opencontainers.image.authors="Carl Boettiger" ENV S6_VERSION=v2.1.0.2 ENV RSTUDIO_VERSION=2021.09.0+351 ENV DEFAULT_USER=rstudio ENV PATH=/usr/lib/rstudio-server/bin:$PATH RUN /rocker_scripts/install_rstudio.sh RUN /rocker_scripts/install_pandoc.sh EXPOSE 8787 CMD ["/init"] ``` 继续看 [/scripts/install_rstudio.sh](https://github.com/rocker-org/rocker-versioned2/blob/master/scripts/install_rstudio.sh) 关键语句: ``` dpkg -i rstudio-server-*-amd64.deb rm rstudio-server-*-amd64.deb ``` (3) 写 Dockerfile $ cat Dockerfile ``` FROM satijalab/seurat:4.0.5 ENV DEFAULT_USER=rstudio ENV PASSWORD=123456 ENV UID=1001 ENV GID=1001 ADD rstudio-server-2021.09.0-351-amd64.deb /home/ COPY scripts/* /rocker_scripts/ RUN /rocker_scripts/install_Rstudio2.sh EXPOSE 8787 ENTRYPOINT ["/rocker_scripts/docker-entrypoint.sh"] CMD ["bash"] ``` 用到的脚本文件: $ cat scripts/install_Rstudio2.sh ``` #!/bin/bash set -e ## 安装Rstudio apt-get update && apt-get install -y gdebi-core \ psmisc sudo libclang-dev libpq5 Rstudio_version="2021.09.0-351" cd /home && gdebi -n rstudio-server-${Rstudio_version}-amd64.deb && rm rstudio-server-${Rstudio_version}-amd64.deb #cd /home && dpkg -i rstudio-server-${Rstudio_version}-amd64.deb && rm rstudio-server-${Rstudio_version}-amd64.deb ## 清理缓存 apt-get clean rm -rf /var/lib/apt/lists/* rm -rf /var/cache/* ``` $ cat scripts/docker-entrypoint.sh ``` #!/bin/bash set -e ## 新增用户 rstudio,密码随机生成。为了保证文件权限一致,传递一下uid和gid DEFAULT_USER=${DEFAULT_USER:-rstudio} groupadd -g $GID user useradd -s /bin/bash -d /home/${DEFAULT_USER} -m ${DEFAULT_USER} -u $UID -g $GID ## 设置密码 if [ "$PASSWORD" == "123456" ] then PASSWORD=`date|md5sum |head -c 10` fi echo "${DEFAULT_USER}:${PASSWORD}" | chpasswd ## 添加sudo权限 echo ${DEFAULT_USER}" ALL=(ALL:ALL) ALL" >> /etc/sudoers ## 输出用户名和初始密码 echo -e "user: ${DEFAULT_USER}\npassword: "${PASSWORD} "\n" \ "\033[31m WARNING! \033[m Please change your password as soon as possible! The default passwd is public!"; # 添加软链接 chown $uid:$gid /data/ ln -s /data/ /home/${DEFAULT_USER}/data ## 启动服务 service rstudio-server start exec "$@" ``` (4) 开始构建 ``` 当前目录下文件结构: $ tree . . |-- Dockerfile |-- rstudio-server-2021.09.0-351-amd64.deb `-- scripts |-- docker-entrypoint.sh `-- install_Rstudio2.sh 脚本要有可执行权限 $ chmod a+x scripts/docker-entrypoint.sh $ chmod a+x scripts/install_Rstudio2.sh ``` 构建 ``` $ docker build -t seurat:4.0.5r1 ./ 会有很多输出,除了出错信息,其他忽略。 时长取决于网速,2-5min。 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE seurat 4.0.5r1 8dc106e85b8e 12 seconds ago 4.58GB ``` 上传到 docker hub ``` 加上用户名前缀: $ docker tag 8dc1 dawneve/seurat:4.0.5r1 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE seurat 4.0.5r1 8dc106e85b8e 42 minutes ago 4.58GB dawneve/seurat 4.0.5r1 8dc106e85b8e 42 minutes ago 4.58GB 登录 $ docker login -u dawneve Password: WARNING! Your password will be stored unencrypted in /home/wangjl/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded 上传: 总是失败,不确定能否上传。 $ docker push dawneve/seurat:4.0.5r1 查看 https://hub.docker.com/u/dawneve 镜像打包压缩 $ docker save dawneve/seurat:4.0.5r1 | gzip -c > seurat_4.0.5r1.tar.gz -rw-r--r-- 1 wangjl docker 1.5G Oct 26 17:31 seurat_4.0.5r1.tar.gz 新机器导入gz包 $ gunzip -c seurat_4.0.5r1.tar.gz | docker load ``` ## 3. 使用镜像 优化启动方式: 文件映射,关联用户 uid,guid (1)在该用户的目录中新建文件夹,用于和 docker 容器共享文件,并持久化。 ``` $ mkdir -p /home/${user}/data/dockerHome ``` (2)设置信息 - 指定端口号,推荐[6千, 6万]之间的整数,一个主机上一个端口号只能被一个进程使用,被占用了就换一个。 - 获取用户信息:username, uid 和 gid ``` $ port=10002 && user=${USER} && uid=`id ${user} -u` && gid=`id ${user} -g` ``` (3)启动容器,并在容器内新建用户 rstudio ``` $ docker run --name=Rs4 --rm -it -d -p ${port}:8787 \ --mount type=bind,source=/home/${user}/data/dockerHome/,target=/data/ \ -e UID=$uid -e GID=$gid \ seurat:4.0.5r1 ``` - 可设定密码(-e PASSWORD=xxx),默认密码是随机生成10位字符串。 - 可设定用户名(-e DEFAULT_USER=xxx),默认 rstudio. * 默认用户有sudo权限,可以在Rstudio的shell标签下执行sudo命令。 查看容器是否启动成功 ``` $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0fa4f3d02cd2 seurat:4.0.5r1 "/rocker_scripts/doc…" 4 minutes ago Up 4 minutes 0.0.0.0:10002->8787/tcp, :::10002->8787/tcp Rs4 ``` (4) 网页登录 查看用户和密码 ``` $ docker logs Rs4 user: rstudio password: 21be20f8f9 WARNING! Please change your password as soon as possible! The default passwd is public! 查主机 ip: `$ ipconfig` 打开浏览器: http://IP:10002 ``` 安全警告: - 宿主机文件夹 /home/${user}/data/dockerHome/ 是和容器内 /home/rstudio/data/ 绑定的(内容完全一致)。 * 所以只要把数据放到主机的 ~/data/dockerHome/ 中,在Rstudio中的 ~/data/ 即可看到。 - 反复读这句:容器内仅 /home/rstudio/data/ 数据会保留,其他数据都会随着容器的停止(关机/停电/异常/被杀掉...)而被【销毁】。 * 销毁就是删除!重要输出只保存到Rstudio的 ~/data/ 下。 - 初始密码全服务器的人都可以看到,可能有些间谍软件也能看到,请及时修改! * 在 Rstudio 的 Terminal 修改密码 $ passwd ## 4. 经验教训 - 整个流程探索最费时间的就是固定步骤 apt update && apt install ...,可以使用多步构建。 - 反复重复构建的原因,是添加用户总是不对。这里花的时间太多,得不偿失。 * 完美是成功的敌人。能用即可,全局最节省时间是最优解。 * 下次构建其他镜像,只提供 `docker exec -it xx bash` 下的添加用户方法。