1. 简单的Demo
docker run ubuntu:15.10 /bin/echo "Hello World"
Docker以ubuntu15.10镜像创建一个新容器,然后再容器里执行/bin/echo "Hello world,然后输出结果,一共分为两种情况,如果此镜像已经存在,那么会直接运行该镜像然后输出;如果镜像不存在,就会从docker hub上拉取公共镜像进行输出
- docker: Docker的二进制执行文件
- run: 与docker组合来运行一个容器
- ubuntu:15.10: 指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker就会从镜像仓库Docker Hub下载公共镜像
- /bin/echo “Hello world”: 在启动的容器里执行的命令
2. Docker客户端
docker
直接使用docker命令即可查看Docker客户端的所有命令选项
docker <command> --help
使用此命令查看某个命令的详细信息
1 | wangyh@Ti-Sev:~$ docker |
2. 镜像命令
2.1 获取镜像
docker pull命令直接从DockerHub上拉取一个镜像,例如从nvidia/cuda这里拉取一个镜像,其中nvidia/cuda表示拉去的目标仓库,12.3.1-devel-ubi8表示拉取的版本
docker pull nvidia/cuda:12.3.1-devel-ubi8
2.2 查找镜像
docker search pytorch
查找合适的pytorch镜像
- NAME: 镜像仓库源的名称
- DESCRIPTION: 镜像的描述
- OFFICIAL: 是否docker官方发布
- stars: 类似GitHub里面的star, 表示点赞、喜欢的意思
- AUTOMATED: 自动构建
1 | wangyh@Ti-Sev:~$ docker search pytorch |
2.3 列出本地镜像列表
docker images
列出镜像列表
- REPOSITORY: 表示镜像的仓库源
- TAG: 镜像的标签
- IMAGE ID: 镜像ID
- CREATED: 镜像创建时间
- SIZE: 镜像大小
1 | wangyh@Ti-Sev:~$ docker images |
2.4 删除镜像
docker rmi <id>
有时候镜像删除不了,报如下错误Error response from daemon: conflict: unable to delete 0f4d93a5f95d (must be forced) - image is being used by stopped container 83835b8839d2,有两种方法解决(一般来说第二种方法更有效)
- 换为
docker rmi <name:tag>命令 docker rmi -f <id>命令强制删除
1 | wangyh@Ti-Sev:~$ docker rmi 304d4ce9d74a |
3. 容器命令
下面的演示均以pytorch/pytorch镜像为准
3.1 启动容器
docker run -i -t pytorch/pytorch /bin/bash
- -t: 在新容器内制定一个伪终端或终端
- -i: 允许你对容器内的标准输入(STDIN)进行交互
1 | wangyh@Ti-Sev:~$ docker run -i -t pytorch/pytorch /bin/bash |
其中第二行root@1315aa2d41a2:/workspace#表示我们已经进入到pytorch/pytorch的容器中,可以查看版本信息并进行一些相应的操作,最后用exit命令退出容器,返回主机。运行docker ps查看不到此容器,表示容器已经被停止
3.2 启动容器(后台模式)
docker run -d pytorch/pytorch /bin/sh -c "while true; do echo hello world; sleep 1; done"
此命令会输出一段长字符:c4bec97b9c398c470f2ccfae77e9d1fc35e1c22127b7d9209267a5bee79b18a8
这个长字符为容器ID,对每个容器来说唯一,只要容器在运行就可以查看,运行docker ps
- CONTAINER ID: 容器ID
- IMAGE: 使用的镜像
- COMMAND: 启动镜像时使用的命令
- STATUS: 容器的状态
- created:已创建
- restarting:重启中
- running or up:运行中
- removing:迁移中
- paused: 暂停
- exited: 停止
- dead: 死亡
- PORTS: 容器的端口信息和使用的连接类型(tcp/udp)
- NAMES: 自动分配的容器名称
1 | wangyh@Ti-Sev:~$ docker run -d pytorch/pytorch /bin/sh -c "while true; do echo hello world; sleep 1; done" |
3.3 停止容器
docker stop <id>/<name>
使用docker stop命令来停止容器,后面跟容器id或者容器name
1 | wangyh@Ti-Sev:~$ docker ps |
3.4 启动已经停止的容器
docker ps -a: 查看所有容器(包括已经停止的容器)
docker start <id>/<name>: 启动已经停止的容器
docker stop <id>/<name>: 停止容器
docker restart <id>/<name>: 重启容器
3.5 进入容器
docker attach <id>/<name>
进入到指定容器,如果从容器退出,会导致容器的终止
docker exec -it <id>/<name> /bin/bash
进入到指定容器,如果从容器退出,不会导致容器的终止
3.6 删除容器
docker rm -f <id>
删除正在运行的容器
docker container prune
清理掉所有处于终止状态的容器
3.7 导入和导出容器
docker export <id>/<name> > path/pytorch.tar
导出容器到指定文件
cat docker/ubuntu.tar | docker import - test/ubuntu:v1
导出容器
1 | wangyh@Ti-Sev:~$ docker export af2e2f698dfd > /data4/wangyh/pytorch.tar |
4. 制作docker镜像
当运行容器时,如果使用的镜像在本地不存在,docker就会自动从Docker Hub公共镜像源下载,当docker镜像仓库中的镜像不能满足需求时,可以有以下两种方式对镜像进行修改
- 从已经创建的容器中更新镜像,并提交修改后的镜像
- 使用Dockerfile指令来创建一个新的镜像
这里我们以创建一个深度学习的Docker镜像为例子,需要的版本是:cuda10.1-cudnn7-devel-ubuntu18.04,python3.8,pytorch1.8
4.1 使用现有镜像
此方法是利用现有的镜像建立一个容器,然后在容器内进行你想要的操作,比如建立了一个python环境,然后退出容器,将容器进行保存为镜像压缩文件,然后重新将压缩文件转化为镜像即可,下面直接给出命令行的建立过程
首先我们这里已经建立了一个容器,如下
1 | wangyh@Ti-Sev:~$ docker ps -a |
然后我们使用export命令将其保存到/data4/wangyh文件夹下,进入到文件夹,ls查看发现现在多了一个pytorch.tar文件
1 | wangyh@Ti-Sev:~$ docker export 506a5c87aaa3 > /data4/wangyh/pytorch.tar |
接下来我们用import命令将其转化为镜像,此时用docker images发现镜像已经存在啦
1 | wangyh@Ti-Sev:/data4/wangyh$ cat pytorch.tar | docker import - test/pytorch:vv2 |
4.2 Dockerfile
Dockerfile的制作很简单,首先建立一个文件命名为Dockerfile,然后将下面的内容复制进去,运行命令
docker build -t <image name> .
例如建立名称为nvidia/cuda:v2的镜像名称
docker build -t nvidia/cuda:v2 .
然后等待镜像建立完成即可,对下面的命令进行解释
1 | !/bin/bash |
- 首先刚创建的环境很多命令不能用,我们用apt-get update命令更新一下,然后就可以用apt-get install xxx安装了
- 随后我们安装miniconda3,wget安装包,bash安装,安装完后rm删除即可
- ENV用来给miniconda3添加环境变量,然后RUN命令修改conda源
- 将宿主机的requirements.txt文件上传到容器中的/home中,方便我们后续进行pip install -r requirements.txt
- 创建conda环境,然后SHELL进入到环境中
- 在PyTorch官网安装相应的包即可,至此镜像创建完成
4.3 Dockerfile命令
- (一)FROM命令
指定基础镜像。新的镜像在基础镜像上进行修改,例如我们要创建一个cuda环境,可以直接从Docker Hub上进行查找,本文中采用了nvidia/cuda:10.1的版本,所以写为FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04
- (二)MAINTAINER
指定作者。指定dockerfile的作者名称和邮箱,例如MAINTAINER wangyh 1061771439@qq.com
- (三)RUN
在镜像内部执行的命令,和在terminal中执行的一样,有两种执行格式
1 | shell格式:RUN mkdir abc |
如果要执行多个命令,需要在每个命令之后加入&&\
1 | RUN apt-get update && \ |
此外,有一些经常使用的文件操作命令
1. 向某个文件中写内容
1 | echo "aaa" > b.txt # 清空b.txt中的内容,并将"aaa"写到b.txt中 |
2. 修改替换某个文件中的内容
1 | sed 's/要被取代的字串/新的字串/g' # 语法格式,s和g |
- (四)ADD/COPY
这两个命令都是将宿主机的文件复制到镜像内,如果目标位置不存在,会自动创建。例如将home文件夹下的a.txt文件复制到容器中root目录下,执行ADD /home/a.txt /root/a.txt
- (五)SHELL
shell指令可以覆盖默认的命令shell,例如linux的默认shell是[“\bin\bash”, “-c”], windows是[“cmd”, “\S”, “\C”]
- (六)ENV
设置容器的环境变量
1 | ENV PATH=/root/miniconda3/bin:$PATH # 设置miniconda的环境变量 |