坎坷学习docker的一点复盘。下面的介绍主要包括以下七个部分。前面两个个比较基础,3-4部分不是必须的,是一些花里胡哨(但很有必要而且很方便的!!)的内容,5-6就是一般会涉及到的两种任务,他们的大概操作流程是
- 下载并运行一个镜像:①从docker hub上复制镜像名,拉取镜像;②在容器中运行镜像
- 创建/修改 并上传一个镜像:①在容器中运行镜像;②进入容器进行修改;③将容器commit成为镜像;④上传push镜像到docker hub
可能报错的问题都写在最后的第七部分。
0.预备备-基本概念
a. 镜像(image)
从docker hub上拉取(pull)的就是一个别人创建好的镜像,miccai挑战赛就是用docker的方式提交代码。另外比如ubuntu,NVIDIA等也有一些官方的镜像,前这就相当于一套ubuntu的root文件系统。可以自己创建、更新或下载别人创建好的镜像。运行时可以用run命令,直接创建一个对应的容器。
b. 容器(container)
每个容器可以看成是一个简单的主机环境,是镜像运行时的实体。
c. 仓库(Repository)
用于存放镜像文件,比如docker hub、docker pool等。用户可以创建私有或者共有的仓库,用于将镜像上传(push)。
1.安装docker
找对应系统的安装代码即可,这里Ubuntu的例子。也可以手动安装。
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
# 或者
curl -sSL https://get.daocloud.io/docker | sh
2.基础用法
这里浅浅先说一下一些基本的用法,在之后的操作当中可以用于查看新建、删除、拉取等操作是否成功,这里主要介绍查看镜像、查看容器、查看正在运行的进程、开始或停止一个container
# 这里的大写的IMAGE,CONTAINER是需要替换的,最方便的用对应IMAGE或者CONTAINER的ID,前几位就可以。
# 查看正在运行的进程
docker ps -a
# --------IMAGE-------
# 查看镜像
sudo docker images
# 拉取/上传一个镜像
sudo docker pull IMAGE
sudo docker push IMAGE
# -------CONTAINER------
# 查看容器
sudo docker containers ls -a
# 开始/停止一个container
sudo docker start CONTAINER
sudo docker restart CONTAINER
# 进入一个开始运行的container
sudo docker exec CONTAINER
#停止一个container
sudo docker stop XXCONTAINER
3.图形管理界面-portainer
用shell来管理还是有些不方便,可以找一些对应的图形化页面管理工具。常用的包括DockerUI,Portainer,Shipyard等。这里使用的是portainer来作为例子。
3.1 查询portainer镜像
可以查询有哪些portainer的镜像,选择一个拉取就可以,这里用第一个作为例子。用其他的话更换一下pull后面的镜像名就可以了
docker search portainer
3.2 下载上面列表中的第一个portainer镜像
docker pull docker.io/portainer/portainer
输入密码,运行成功后,利用sudo docker images查看现有镜像,看看有没有多出一个portainer。
3.3 运行镜像
有镜像了之后,下一步是运行镜像。这里用到的几个参数,简单说一下,后面展开的时候会具体介绍
docker run -dp 9000:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name portainer-test \
docker.io/portainer/portainer
- -p:设置9000端口(如果显示有冲突的话可以更换其他的端口,或者将现有占用端口的进程结束掉,具体见【常见问题2】部分)
- -d:后台运行
- –restart(设定重启的方式,后文会讲)
- -v(文件挂载)
- -name : 指定运行现在镜像的容器的名字,镜像会在一个容器里面运行,不设置名字的话就系统就会默认给你起一个奇奇怪怪可可爱爱的名字
这句话的功能就是把刚才拉取的portainer镜像运行到一个名为portainer-test的容器中。
然后就可以打开网页,用localhost:9000 (这里localhost可以换成自己的ip地址)登录portainer.io的界面。第一次登陆是一个创建用户的界面,输入密码,直接create一个账户。进入之后选择private(最左边的一个),点击确定,就可以了,会显示下面这个界面。
点击进入local,就可以看到不同的分类,在这个界面就可以完成查看images、containers以及对他们进行运行、暂停、修改、删除等操作,非常方便!
下一次想要进入portainer网页的时候直接用localhost:9000的地址在浏览器中打开即可。如果发现打不开了见【常见问题3】!!
4.vscode+docker
4.1 下载扩展:
左边的菜单栏就会多一只小鲸鱼,然后就可以在这里运行一个container了!
4.2 用!
然后就像ssh一样,点击左下角的><按钮,选择attach to running container (要先run哦)
然后它会自动新建窗口,open folders就和在本地的操作一样了,这里可以更方便的进行文件的删除、拖入,同时可以在这里配置想要的环境,超级无敌方便!!
5.下载并运行一个镜像
一般docker的使用就是下载并运行一个别人创建好的镜像
5.1 从docker hub上拉取(pull)一个镜像
在docker网站上复制想要拉取的镜像名,这里用2021miccai semi-supervised的举例子
拉取pull镜像
sudo docker pull IMAGENAME
# e.g. sudo docker pull gospelslave/semi-suplearn_subtask1
可以用sudo docker images检查一下是不是拉取成功了
5.2 用镜像创建一个container,运行
先查看一下目前images的信息,可以看到拉取成功的gospelslave/semi-suplearn_subtask1,以及它对应的IMAGE ID是45c开头的。
简单运行一个image的方法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用的写法和例子比如
sudo docker run --rm --gpus "device=0" -i -t -d IMAGE /bin/bash
# sudo docker run --gpus "device=0" -it 45c /bin/bash #只用一张卡跑
# sudo docker run --rm --gpus all -itd ae5d /bin/bash #有多张卡可以直接指定gpus为all
# 一些复杂花里胡哨的写法 运行一个images并自动创建一个container
sudo docker container run --rm --gpus "device=0" -i -t -d --name NEWCONTAINERSNAME -v path1/path2 IMAGENAMEORID /bin/bash
# sudo docker container run --gpus all --name semi-suplearn_subtask1 -v $PWD/TestImage/:/workspace/input/ gospelslave/semi-suplearn_subtask1:latest /bin/bash
- options(写几种常用的,剩余的见菜鸟教程):
- -t: 在新容器内指定一个伪终端或终端
- -i: 交互模式,可以用ctrl+C退出的那种,一般和-t一起用,可以省略写成-it
- -d:在后台运行,并返回容器ID。
- -p: 指定端口映射,格式为:主机(宿主)端口:容器端口, 刚才设置portainer图形界面的时候使用过
- **–**rm:容器退出时自动清理容器内部的文件系统
- **–**name XXX:为运行目前image的container起一个名字
- –env-file=[]: 从指定文件读入环境变量;
- –cpuset=“0-2” or --cpuset=“0,1,2”: 绑定容器到指定CPU运行;
- IMAGE : 改成镜像名或用imageid前几位
- -v path:path : 相当于把前面的path1里面的内容挂在到path2中,这样做的目的是在容器中的文件运行路径可以固定为path2,每次运行的时候只要利用这句命令将本地path1的数据挂在上来用就可以。这里$PWD是指当前路径
- /bin/bash :希望有个交互式 Shell,因此用的是 /bin/bash。一般这样写就可以
运行后就可以进入对应的环境里面,然后像正常本地的使用方法一样查看文件夹、文档等,也可以运行文件。exit退出。
6.创建/修改 并上传一个镜像
如果我们想自己配置一个环境,可以有两种方法:①从已经创建的容器中进行更新和修改,并重新提交镜像,②用dockerfile创建一个新的景象。这里简单用第一种方法来举例子
6.1 用镜像创建一个container
用之前提到的命令运行一个image
sudo docker run -it --name testing 45c /bin/bash
# 看一下目前的container, 是否多了一个name为testing的容器
sudo docker container ls -a
6.2 进入container,修改文件,配置环境
- OPTIONS: -i -t -d 同上
- CONTAINER: 可以用名字或者ID(前几位即可)
sudo docker exec [OPTIONS] CONTAINER /bin/bash
尝试用这个方法创建一个新的文件夹,退出之后再进来确认文件夹还在。完成修改!
# 运行这个container
sudo docker start 192
# 进入
sudo docker exec -it 192 /bin/bash
# 创建一个新的文件夹
mkdir testing
6.3 commit container ,生成一个镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- OPTIONS:
- -a : 作者
- -c:使用dockerfile指令来创建镜像
- -m:提交时的说明文字
- -p:commit时将容器暂停
这里提交刚才修改好的192容器,简单的写法和全一点的写法,以及对应的结果:
#这样生成的没有repository名字和tag,最好不要这样,要不后面还要改
sudo docker commit -m "testing" -a "me" 192
#复杂一点的,添加对应的仓库名和tag
sodu docker commit -m "testing" -a "me" 192 testing:v1
由于发布的时候需要有自己的账户名,因此最好创建的时候的名字就按照USERNAME/IMAGENAME:tag的格式来写,比如将上面的testing:v1前面加上自己docker hub的用户名和一个斜杠。如果commit的时候没有写,可以用下面的方式添加
docker tag testing:v1 USERNAME/testing:v1
6.3 最后一步!!push镜像到docker hub中
先记得登陆自己的docker hub,这里对应的命令是:
docker login
输入username和password即可,如果没有的话去https://hub.docker.com 创建一个。显示login succeeded就可以了。在其中创建同名仓库(这里的话就叫testing)。然后就可以push。如果报错denied: requested access to the resource is denied,见【常见问题5】!!
docker push [OPTIONS] NAME[:TAG]
这里将刚才commit过得username/testing:v1上传
docker push USERNAME/testing:v1
然后在docker hub里面点进仓库,就可以看到了!!
呜呜呜终于!
7.常见问题
7.1 error
在命令前面加一个sudo!权限get
7.2 端口9000被占用了
换一个吧
或者用lsof -i:9000命令看看目前占用该端口的进程在干嘛,不需要的话用kill PID(这里替换成要删除的进程的PID) 即可。
7.3 localhost:9000 打不开
可以先用sudo docker ps -a 查看一下目前正在运行的container有哪些
发现所有的状态都是暂停住的,那就是这个问题了!因为进入portainer界面需要启动docker(有正在运行的container),所以如果发现进入不了页面说明所有的container在运行完之后都默认关掉了。(这也是为什么portainer安装时,运行镜像的代码中有restart=always这一行!!)
临时解决方法:需要在终端中用sodu docker start XXX 来运行一个containers,这里XXX是一个containers的名字或编号,这里我用的是上面portainer的镜像对应的container id
再看一下,运行起来了。
这时候再刷新一下浏览器,可以的好起来了!
终生解决方法:为了避免这个复杂的操作,可以在运行镜像时加入restart=always的命令,或者更简单一点,在portainer网页中进入containers里面,点击刚才添加的portainer这个镜像的名字,然后再最上面的actions中点击最右边的duplicate/edit。拉到最下面,选择restart policy,默认为never,这里改成always,然后选择上面的deploy the container确定修改即可。
这样修改完后,这个容器在下次与进行完就不会自己关掉,就可以随时直接进入portainer界面了!
7.4 添加代理等,或者查看基本信息
sudo docker info
7.5 push报错
用sudo docker images查看当前的镜像,第一列就是各个镜像的仓库名,一定要和自己dockerhub上的一样!也就是要有username/XXX的形式,这样才不会报错!可以重新commit或者用tag命令来修改。
7.6 pull下来的代码运行好慢
使用环境的时候记得看一下torch等的版本合不合适,或者可能是电脑配置就不合适,那就换台电脑把😇
7.7 运行结果文件夹权限有问题
先进入到对应文件夹所在的地方。
sudo chown -R USERNAME FOLDERNAME
差不多够用了暂时。这一口气docker学没学懂还不知道,但人是真没了