在mac上安装Docker Desktop,安装后可在终端上用docker version查看docker版本。
一、镜像相关命令
搜索镜像:
docker search nginx
查看镜像所有tag:
比如es,curl或者在浏览器访问https://registry.hub.docker.com/v1/repositories/elasticsearch/tags
拉取镜像:
docker pull nginx
查看本地镜像:
docker images
删除本地镜像:
docker rmi nginx:latest
或者docker rmi image_id
构建镜像:
docker build -t repository[:tag] -f path1/Dockerfile path2
-t 指定镜像名称,格式是repository[:tag]。如果不指定的话,生成的镜像的repository和tag均为none,所以强烈建议用-t。
-f 指定Dockerfile路径,可以省略,默认是上下文目录中的Dockerfile文件??确认一下
如docker build -t openresty:v1 .,表示上下文是当前目录,且以当前目录中的Dockerfile构建,repository是openresty,tag是v1。
我们想在拉下来的nginx镜像的基础上,构建一个预装常用命令的镜像,这样我们就可以在nginx服务器上调试下游接口通不通以及修改nginx的配置文件了。构建镜像需要Dockerfile文件,文件名就是Dockerfile,没有后缀。
Dockerfile文件内容至少要有这么几项:
1、用FROM指定基础镜像
如FROM nginx
2、用RUN指定要执行的命令,可以理解为要在基础镜像上干的事情
如RUN apt-get update && apt-get install -y vim net-tools procps lsof curl wget iputils-ping telnet lrzsz
3、WORKDIR指定容器内部的工作目录,相当于linux的mkdir -p xxx; cd xxx。启动容器后,用docker exec进去容器后一开始也是进入到这个目录中。
如WORKDIR /app
4、CMD用于指定启动容器时执行的命令,即执行docker run命令时,容器内部执行的命令。
如CMD java -jar aa.jar --server.port=9000
如果要执行多条命令,则多条命令需要用分号分开,如CMD yum -y install wget; touch a.txt; tail -f a.txt
更好的一个操作是把这些命令放到一个单独的shell脚本中,如start.sh,在CMD中执行这个脚本即可,如CMD ./start.sh,这样就不会因为修改CMD命令而必须重新build了。
5、启动容器后,进入,默认用户是root。如果不想用root用户,则可以用RUN命令创建用户,并用USER指定,如下:
RUN useradd ps
USER ps
这样,启动容器后,进入,用户是ps。
VOLUME不建议使用。VOLUME指定容器内的一个目录,并挂载到宿主机上,但是具体是宿主机的哪个目录,是不定的,是随机生成的,需要我们用docker inspect命令去查看,而且在mac上测试结果是,宿主机此目录不会自动创建,即使我们手动创建后,也和容器的目录关联不上,在容器的目录中创建一个文件,宿主机的这个目录中不会自动有这个文件。
查看本地某镜像的前世今生:
docker history image_id/repository[:tag]
如docker history redis:latest
保存镜像:
docker save -o XXX.tar repository:tag
如docker save -o openresty.tar openresty/openresty:latest
什么时候保存镜像呢?在A机器上build了一个镜像,是在nginx镜像上做的,自己装了一些常用的基础组件,如vim、procps、lsof、curl、net-tools、iputils-ping、telnet,这样在新镜像的容器中就可以用vi、ps、lsof、curl、ping、telnet等命令了。很多pull下来的镜像是不预装这些基础组件的,导致这些常用命令用不了,需要自己安装。想要在B机器上用这个我们预装好的镜像启动一个容器,则需要在A机器上保存此镜像,下载,然后上传到B机器上,在B机器上安装docker,然后载入此镜像,再启动容器即可。注意,如果保存时是用image_id指定的镜像,那么在载入时repository、tag会为none,所以最好用repository:tag指定要保存的镜像。
载入镜像:
docker load -i XXX.tar
之后,可以用docker images命令查看是否载入成功,载入成功的话,就可以正常使用了。
二、容器相关命令
启动容器:
docker run -p 10000:80 nginx
-p 10000:80 表示把宿主机的10000端口和容器的80端口映射起来。多个映射需要用多个-p 指定,如-p 10000:80 -p 11000:11000。
nginx是repository名,tag省略的话,就是latest,上面命令等同于docker run -p 10000:80 nginx:latest。注意,此时是前台启动,执行ctrl+c后,容器就挂掉了。
-d 表示后台启动,如docker run -d -p 11000:80 nginx
除了-p、-d外,还有几个参数比较常用:
--restart,指定容器退出时的重启策略,可选值有no、on-failure、always,默认值时no。如果容器已经启动了,这时候想设置重启策略,则可以执行docker update --restart=XXX container_id。
--name:指定容器的名字。强烈建议在启动容器时给容器指定一个名字。如docker run -d -p 11000:80 --name nginx_v1 nginx
--network:指定网络模式,可选值有bridge(默认值)、host、none、container:[container_name | container_id]。
-e 指定环境变量,多个环境变量需要用多个-e 指定,如-e port=10000 -e env=prd。容器启动后,就可以通过echo $port查看了。在我们的应用程序中,就可以用这个环境变量。在Dockerfile中的CMD命令中,也可以通过$port获取port值,进而使用,如启动应用时指定端口,或者设值到配置文件中。
-v:给宿主机某目录和容器某目录创建映射。后面跟宿主机某目录:容器某目录,改变任一目录的文件,对应目录也会改变。如docker run -d -p 11000:80 -v /Users/shengruikou/nginx/html:/usr/share/nginx/html nginx,用宿主机的/Users/shengruikou/nginx/html目录映射容器的/usr/share/nginx/html目录,在宿主机的这个目录中新建一个index.html文件,写点东西,会发现在容器对应的目录中同样会出现一个index.html文件,内容和宿主机的一样。反向操作,结果也是一样。
--volumes-from:使当前容器映射目录跟另外一个容器的映射目录一致,后面跟另一个容器的容器id或者name。如docker run -d -p 12000:80 --volumes-from 28b2722f40b9 nginx,这里假设上面宿主机11000端口对应的容器的id是28b2722f40b9,我们又启动了一个容器,映射目录跟刚刚的容器保持一致,那么宿主机目录、宿主机11000端口对应的容器的目录、宿主机12000端口对应的容器的目录,这三个目录是联动的,一个目录内容的改变会导致另外两个也会改。
--cpus:分配cpu核数
-m:分配内存大小
如果启动失败,可尝试用docker logs container_id查看错误日志,有些镜像的容器能看到错误日志,有些看不到。
docker run -d -v /root/shengruikou/app:/app -e BASICINFOPORT=8885 --network host openjdk8_env:latest
docker run还可以指定容器启动后执行的命令,如
docker run -d -v /root/shengruikou/app:/app -e BASICINFOPORT=8885 --network host openjdk8_env:latest bash touch.a.txt
如果要执行的命令太多的话,也可以都写到一个sh文件中,然后docker run指定这个文件,如
docker run -d -v /root/shengruikou/app:/app -e BASICINFOPORT=8885 --network host openjdk8_env:latest bash /path/cmd.sh
注意,bash后面的路径是容器中的路径,不是宿主机中的路径。
查看容器:
docker ps
查看正在运行中的容器,如果使用-a参数则可以查看所有的容器,包括已经挂掉的容器。
如果COMMAND显示不全的话可以再加个--no-trunc参数,即docker ps -a --no-trunc,此时container_id也会显示全。
暂停容器
docker stop container_id
停掉所有的容器:docker stop $(docker ps -aq)
启动暂停的容器
docker start contain_id
重启容器
docker restart container_id
删除容器
docker rm container_id
删掉某running状态的容器:docker rm -f container_id。这种方式删掉容器后,服务会不会停?
删掉所有的容器:docker rm $(docker ps -aq),如果有容器处于running状态,则这些不会删除。加-f参数,会强制删掉所有容器。
删掉所有停掉的容器:docker container prune
进入容器:
先docker ps 查看容器id,假如是775c7c9ee1e1,则继续执行 docker exec -it 775c7c9ee1e1 bash。如果报错,则尝试把bash换成sh,因为不同的linux系统命令是不一样的。
已知的linux系统有CentOS、Debian、Alpine,在CentOS上安装软件用yum,如yum install -y vim,在Debian上安装软件用apt-get,如apt-get update && apt-get install -y vim,在Alpine安装软件用apk,如apk add vim。
cat /etc/os-release可以显示出当前系统具体是哪个linux系统。
如docker pull nginx:1.18.0
用docker run -it nginx:1.18.0 bash命令启动后,执行cat /etc/os-release命令,可知是Debian系统。
如果进入容器后,报eth1: error fetching interface information: Device not found,怎么解决???
更新运行中的容器
docker update --help
如docker update --cpus 1 -m 1G --restart=always container_id