理解 image 和 container 的区别
image 即镜像,只读不可写,可以理解为「橡皮泥」生产线生产「橡皮泥」的地方;
container 即容器,可读可写,可以理解为从「橡皮泥」生产线拿到一块「橡皮泥」,可以用这块橡皮泥做各种事情。
当然,我们可以制作镜像,可以抓取镜像。而一般我们说使用docker的时候,常常是使用容器。简单来说是,先抓取或者载入镜像,通过镜像创建一个容器,然后在容器内做各种各样的操作。
抓取镜像和使用docker
docker 环境部署完成后,本地是没有镜像的,自然也没有容器。如果我们要使用 docker,那么需要先创建一个镜像或者说可以直接抓取一个云端的基础镜像
# 这一步为可选项,逻辑上可以直接 run 镜像,会自动抓取
docker pull ubuntu
查看有什么镜像
docker images
![](https://img.haomeiwen.com/i10518391/ba8fef68a333d2da.png)
随后可以使用镜像,从云端抓取 ubuntu 镜像并以交互模式进入,-i
表示交互模式,-t
表示创建一个 tty
docker run -it ubuntu
![](https://img.haomeiwen.com/i10518391/fd0f1d85de0047f7.png)
可以在另外一个窗口查看有什么容器(新开一个 cmd 窗口)
docker ps -a
![](https://img.haomeiwen.com/i10518391/5c504a89b1c51f70.png)
进行一些操作
(此时在容器环境中,容器ID:6070f504a4fb)
简单安装 ncbi-blast+
apt-get update
apt-get install -y ncbi-blast+
当然还可以做很多其他环境部署工作,完成后可以退出或者不退出
导出容器为镜像
有两种方式可以实现
1. 使用 commit 和 save
比较简单,在docker环境外,容器ID即为上述ID(我们可以对即将创建的新镜像命名为 hello,版本是 1.0)
docker commit 6070f504a4fb helloworld:1.0
随后可以导出
docker save helloworld:1.0 > helloworld.tar
到新的电脑,使用 docker load 即可(注意 load 模式无法执行新的镜像名字,这在commit的时候已经指定)
docker load < helloworld.tar
2. 直接使用 export
对于任何一个容器,可以直接 export。此处无法指定镜像名字
docker export 6070f504a4fb > byebyeworld.tar
如此在新的设备上,使用docker import
(可以补充执行镜像名字为 goodbye,版本为 1.0)
docker import byebyeworld.tar goodbye:1.0
镜像文件可以压缩
直接在 wsl 中使用 xz 可以实现极限压缩
xz -9eT0 helloworld.tar
进一步理解容器
逻辑上,我们基于镜像创建了一个容器,对容器的所有操作和改造都被完整记录。退出容器,那么容器和他的修改仍然存在,比如前面我们安装的blast仍然可用。比如,在容器中
exit
可以在外部看到,容器仍然存留
![](https://img.haomeiwen.com/i10518391/0abd943c4751df3a.png)
容器属于
exited
状态。我们当然可以删了他
docker rm 6070f504a4fb
我们也可以重新启动并进入这个容器
docker start 6070f504a4fb
docker exec -it 6070f504a4fb bash
进一步理解基于镜像创建容器
每一次,我们使用 docker run image
都会新建一个容器
docker run -it ubuntu
如此容器就会不断积累。我们可以通过下述命令查看所有容器状态
docker ps -a
如果我们想删除某个容器,那么可以使用
docker rm 容器ID
但是,如果容器仍然在运行(也可以是在后台运行,比如做了一些网站容器,比如Rstudio网页版)。那么可以用
docker stop 容器ID
如此来删除该容器。
如果我们想删除某个镜像,那么需要使用
docker image rm imageID
注意到,如果基于这个镜像创建的容器还在本机存在(无论是否在运行),那么需要删掉这些相关容器,最后才能成功删除镜像。
自然有些时候,我们基于镜像创建容器并执行一些任务后,并不希望保留容器,那么当我们执行docker run
或者类似的docker exec
的时候,可以补充参数--rm
。如此会在退出容器时,自动删除容器。
docker run -it --rm ubuntu
映射本地目录为 docker 容器目录
很多时候,我们需要让docker读取和写入本地文件。下述命令可以映射当前工作目录为镜像中的/scauclass
目录,同时,进去镜像时,自动-w
切换到该目录
# cd C:\Users\ccj04\Documents\
# windows CMD
docker run -v %cd%:/scauclass -w /scauclass -it ubuntu
# macos/linux
docker run -v $(pwd):/scauclass -w /scauclass -it ubuntu
注意到,如此操作/scauclass
中写入写出或者其他任何操作都会同步影响到本地文件。
提交镜像到 Docker Hub
提交镜像到 Docker Hub,可以方便其他人使用,甚至可用于其他常用容器软件,如 Singularity 等
在命令行上,先docker login
docker login
注意,对于要提交的其镜像名字,比如带有符合「账户/镜像」这个格式。我的账户名字为「cjchen」,故对已有镜像进行一次重命名,补充 cjchen,如此才可正常提交
docker tag tbtoolszone:2.0 cjchen/tbtoolszone:2.0
docker push cjchen/tbtoolszone:2.0
![](https://img.haomeiwen.com/i10518391/397a2a35ca3cf779.png)
如此,就提交上去了。后续可以使用如
docker pull
或者singularity pull
等来直接使用![](https://img.haomeiwen.com/i10518391/e72611662b79a848.png)
抓取镜像之后测试(似乎会自动完成本地路径映射,无需继续 -v)
docker pull cjchen/tbtoolszone:2.0
docker run -it --rm cjchen/tbtoolszone:2.0
# 测试看看环境是否正常
seqkit
# 退出容器
exit
关于 Dockerfile
逻辑上,交互式构建 docker image 期间,记录所有执行的命令,整理一下,即可写成 Dockerfile,方便后续更快部署,同时也可以获得更为轻量的容器。
映射 ip
如搭建网站时(待补充)
串联多容器
如使用 mysql 等(待补充)
网友评论