创建镜像
除了使用开源的Docker镜像之外,我们可能会面临需要自己创建镜像的情况。基于Dockerfile文件是最常用的Docker镜像创建方式之一。例如:
sudo docker build -t image_01.qc:v0.1 /path/to/Dockerfile
注意:
1、需要sudo权限
2、给到的是Dockerfile的路径,而不是具体到文件名!否则会报错:
unable to prepare context: context must be a directory
3、 -t
后后镜像命名的字母必须为小写,可以带数字
4、如果 -t
与之前的镜像同名,默认会覆盖
5、默认会识别路径下的名为Dockerfile的文件,如果是其他命名,需要使用 -f
参数指定文件名,同样不要忘了设置其所在的路径!
sudo docker build -t image_01.qc:v0.1 -f Dockerfile_test .
如果报错:
ERRO[0000] failed to dial gRPC: cannot connect to the Docker daemon. Is 'docker daemon' running on this host? dial unix /var/run/docker.sock: connect: no such file or directory Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
可能就需要找 root 了,参考:
...Successfully built 0a88d6238136
Successfully tagged image_01.qc:v0.1
显示成功后,执行 sudo docker images
可查看刚创建好的镜像!
删除镜像
当然,你可能并不会刚创建好就想试试立马删除,毕竟后面我们还要用。
删除镜像需要使用 IMAGE ID(上图里有),例如删除掉刚才创建好IMAGE ID为0a88d6238136的 image_01.qc:v0.1
sudo docker rmi 0a88d6238136 # 注意是rmi
此时,再使用 sudo docker images
即可看到镜像被删除。
但是要注意:
1、不支持使用镜像名删除!
2、如果镜像中存在着正在执行的容器,会报错:
Error response from daemon: conflict: unable to delete a5063e101ee7(must be forced) - image is being used by stopped container a5063e101ee7
此时需要先根据 CONTAINER ID ,比如上示的 a5063e101ee7:
sudo docker stop a5063e101ee7 # 停止容器
sudo docker rm a5063e101ee7 # 删除容器
sudo docker rmi 0a88d6238136 # 最后删除镜像
另外,我们会发现很多是<none>的镜像,其中包括之前测试 sudo docker build
时,未成功创建的镜像,这些镜像一般无法行使特定的功能。同样是找到相应的 IMAGE ID 使用 rmi
删除即可:
sudo docker images| grep none |awk '{print $3 }'|xargs sudo docker rmi -f
注意,最后的 -f
参数表示即便是某些镜像仍被使用,但依然强制删除!
使用镜像
容器是镜像运行时的实体和载体。所以使用镜像,需要创建/运行容器(Container):
sudo docker run -itd --name=image_01.qc_con image_01.qc:v0.1 # :tag不能少
参数说明:
-i:以交互模式运行容器
-d:后台运行容器并返回容器ID
-t:为容器分配一个伪输入终端
--name:为创建的容器命名
执行 sudo docker run
时,Docker会启动一个进程,同时给这个进程分配其独占的文件系统,独占的网络资源和以此进程为根进程的进程组。
正确执行会返回一个容器ID:
eb10f25ec3a1064fa71d279dfe33b...
创建完成后容器即默认执行,可以使用 sudo docker ps
查看正在运行的容器。
显示的第一列CONTAINER ID(容器ID) 其实是之前返回的 容器ID 的开头部分,不过仍然具有唯一性,能且只能指向一个容器。
或手动启动/重启:
sudo docker start image_01.qc_con3 # 启动
# sudo docker restart container_name/container_id # 使用container_name或container_id重启
进入容器
毫无疑问,我们想看看容器里都有啥,Dockerfile设置的软件都有没有被安排上,测试一家伙。这里使用容器名或者容器ID都可以:
sudo docker exec -it image_01.qc_con /bin/bash # 此处 image_01.qc_con 可替换为 eb10f25ec3a1
此时:
1、我们相当于进入了一个虚拟的系统,与外部的系统相隔离。
2、自带root权限,可以进行任何操作,比如创建、删除文件,比如执行通过 Dockerfile 安装的软件!
3、直接输入 exit
命令就可以退出容器。
4、再次进入容器时,之前的操作(比如创建了一个文件夹)仍会保留。显然,如果删除掉容器又重新创建同名容器,之前的操作是不会被保存的。
挂载
使用 Dockerfile 一般只会安装流程中所要使用到的软件,而不会把脚本、数据库等打包进去,是因为一方面我们可能会经常修改内容,所以就需要重新打包或者更新操作,另外,纳入太多内容,镜像就会过于臃肿。所以,可以使用挂载的方式访问外部(宿主机)文件,即在 docker run
后添加 -v[host-dir]:[container-dir]:[rw|wo]
的文件对应关系。如果还想用之前的容器名进行测试,则首先需要退出并删除之前的容器:
exit # 先退出
sudo docker stop image_01.qc_con # 再停止(如果想要删除容器,必须先把容器关闭掉)
sudo docker rm image_01.qc_con # 删除
# 重新run
sudo docker run -itd --name=image_01.qc_con -v /data/Pipline/Genseq-PM/V3.0/lib:/Pipline/Genseq-PM/V3.0/lib image_01.qc:v0.1
容器名虽然没变,但ID变了!
sudo docker exec -it image_01.qc_con /bin/bash
注意:
1、目录必须是绝对路径
2、由于已经添加了挂载,所以进入容器后,在设置的路径下就能找到主机的映射文件,会自动创建路径
3、宿主机修改了文件,容器中的对应文件也会被同步