0.了解docker
docker是目前最成熟高效的软件部署技术,docker简单来说就是用容器化技术,给应用程序封装独立的运行环境,每个运行环境就是一个容器,运行容器的计算机被称为宿主机,docker容器与虚拟机的最大区别是docker容器之间共用同一个系统内核,而每个虚拟机都包含一个操作系统的完整内核,所以docker容器比虚拟机更轻更小、启动速度更快。docker另外一个重要概念是镜像,镜像是容器的模板,我们可以把镜像类比成软件安装包,而容器是安装出来的软件,举一个现实世界的例子,镜像与容器的关系就像是用模具做糕点,docker镜像就像是模具,而容器就像是糕点,我们可以使用一个模具做出很多个糕点,当然,我们也可以把模具分享给其他人使用,docker仓库就是用来存放分享镜像的地方,每个人都可以把自己的镜像上传到仓库里面,然后其他人就可以下载镜像并且使用,docker的官方仓库就是Docker Hub,上面存储了许多人分享的Docker镜像,Docker利用了Linux内核的两大原生功能实现容器化Cgroups用来限制和隔离进程的资源使用,可以为每个容器设定CPU内存网络带宽等资源的使用上限,确保了一个容器的资源消耗不会影响到宿主机或者其他正在运行的容器,Namespaces用来隔离进程的资源视图,Namespaces使得容器只能看到自己内部的进程ID、网络资源和文件目录而看不到宿主机的,所以容器本质上还是一个特殊的进程,不过当我们进入到容器内部后容器内部看起来就像一个独立的操作系统

1.docker pull 从仓库中拉取的镜像
docker.io是docker仓库的注册表地址,表示这是Docker Hub的官方仓库,官方仓库可以省略不写仓库地址。library是命名空间,因为Docker Hub是公共仓库,每个人都可以上传自己的镜像,如果每个人上传的镜像都叫同一个名字,比如都叫nginx这样肯定会乱套,所以docker要求上传镜像的时候要在镜像前面加上作者的名字,也就是命名空间,library是docker官方仓库的命名空间,这个空间下面的所有镜像都是由官方管理的,如果一个镜像属于是官方的命名空间那这部分可以省略不写,最后冒号后面latest这部分是docker镜像的标签名也就是版本号,可以写指定的,也可以不写表示获取最新的,所以最后可以写成docker pull nginx

2.docker images 查看已拉取的镜像

3.docker rmi 删除镜像
rm这里代表remove也就是删除,i是Images的缩写,这样连起来就是删除镜像,接下来我们可以填写一个镜像的名字或者填写一个ID,这里我填写ID再回车这样就把服务器上的nginx的镜像删除了

3.1 docker rm 删除容器

4.docker run 使用镜像创建并运行容器
run后面可以接一个镜像的名字或者接一个镜像的ID,就像开头提到的用模具做糕点的例子,这一步就是使用镜像创建一个容器,正如我们使用模具制作一个糕点这样,这样我们就把容器启动起来了,在前面的docker pull中我们可以拉取镜像来运行,但其实我们可以简化这一步,直接使用docker run来运行,docker如果发现没有该镜像会自动去Docker Hub中拉取该镜像来运行

4.1 docker run -d 后台启动
我们启动后会占用窗口,所以我们可以在run的后面加上-d来后台启动

4.2 docker run -p 80:80 端口映射
-p的作用是端口映射,每个docker容器都运行在一个独立的虚拟环境里面,容器的网络与宿主机是隔离的,默认情况下并不能直接从宿主机访问到docker的内部网络,比如我在宿主机上直接安装一个nginx,在浏览器输入localhost80就能访问到这个nginx提供的网页,但是我使用docker来启动nginx在浏览器输入localhost80则无法访问到对应的网页,因为容器内的网络与宿主机的网络是隔离的。这时候我们需要添加一个启动参数把容器内的端口与宿主机的端口进行一个映射,我们可以添加这个-p参数,在冒号前后各填写一个端口,冒号前面是宿主机的端口,冒号后面是容器内的端口,顺序是先外后内,也就是把宿主机的80端口转发到容器内的80端口进行处理,这样我们在浏览器访问localhost的80也就是访问宿主机端口的时候,就等于访问到了容器内的端口,网页也就正确地显示出来了

4.3 docker -v 文件目录绑定
与-p绑定端口类似的参数是-v,-p是把宿主机与容器的端口进行绑定上,v则是把宿主机与容器的文件目录进行绑定,容器内对这个文件夹的修改会影响宿主机的文件夹,而在宿主机对文件夹的修改
同样会影响容器内的文件夹,宿主机与容器通过这个目录紧密的联系到了一起,这种目录也被称为是挂载卷,的最大作用是数据的持久化保存,因为当我们删除容器的时候容器内的所有数据会被同时删除掉,如果我们使用了挂载卷,容器内对应目录的数据就会保存在宿主机的对应目录里面,这样删除容器的时候保证了数据不会被删除,相当于把数据做了一个持久化的保存,如下图,我们将宿主机的/website/html和容器的/use/share/nginx/html目录绑定起来,这样我们就可以通过改变宿主机的目录文件使容器的文件也发生变化

5. docker ps 查看正在运行的容器
查看进程状况,这个是一个Linux上的经典命令,这个概念也被继承到Docker里面,表示查看正在运行的容器

5.1 docker ps -a 查看所有容器

6. docker run -it 进入容器
-it可以让我的控制台进入容器进行交互,--rm指的是当容器停止的时候就把容器删除掉,看到这样直接进入到了容器内部,然后我们用exit退出以后这个容器同时被从宿主机上删除了,所以这套命令一般连在一起用,用于临时调试一个容器
7. docker --restart 意外重启
--restart用来配置容器在停止时的重启策略,常用的有--restart后面跟always,也就是只要容器停止了就会立即重启,包含容器因为内部错误崩溃或者宿主机断电等等的场景,还有一个类似的是把always换成unless stopped,这个跟always非常的相似,有一个关键区别是手动停止的容器就不会尝试重启了,这对于生产环境非常有用,Docker会自动重启因为意外原因停止的容器,而手动停止的容器就不会再重启了

8. docker stop 停止容器

9. docker start 重新启动容器

10. docker inspect 容器配置参数
如果我们忘记了容器启动时填的参数是什么,可以执行docker inspect这个命令,后面接容器的ID,docker这里打印了非常长一串,但是这种我们也不需要自己分析,直接把它贴给AI就行了
11. docker create 创建容器但不立即启动

12.docker logs 容器 -f 滚动查看日志

13. docker exec 容器 ps -ef 容器的内部执行Linux命令
docker exec可以在容器的内部执行Linux命令,我想进入这个容器查看一下里面正在运行的进程
我们可以执行这个命令docker exec,后面是容器的ID或者名字,最后是你想执行的Linux命令,这里查看进程一般是ps -ef,这样就看到了容器里面的进程情况,因为容器内进行了资源视图的隔离,所以这里看不到宿主机的进程

13.1 docker exec -it 容器 /bin/sh 进入容器并获得交互式的命令行环境
使用这个命令可以进入一个正在运行的docker容器内部获得一个交互式的命令行环境
容器内部表现出来的,就像一个独立的操作系统,我们可以进入容器内部执行Linux命令查看文件系统、管理容器内的进程,或者更加深入的进行调试

14 Dockerfile docker配置信息
在开头的例子里面,容器是用镜像这个模具生产出来的糕点,镜像是制作糕点的模具,而Dockerfile就是制作模具的图纸,Dockerfile是一个文件,里面详细的列出了镜像是如何制作的,Dockerfile相当于一个写死了的脚本文件,在run后面跟的命令都是容器的系统里的命令,底层是Linux就是Linux里的命令。from就是一个告诉依赖,entrypoint和cmd指定启动命令


15. docker网络
Docker网络默认是bridge,也就是桥接模式,所有的容器默认都连接到这个网络,每个容器都分配了一个内部IP地址一般是172.17开头的,在这个内部子网里面容器可以通过内部IP地址互相访问,但容器网络与宿主机的网络是隔离的,我们可以使用Docker network create创建出子网,默认情况下创建出来的子网也是属于桥接模式的一种,然后可以指定容器加入不同的子网,同一个子网的容器可以互相通信,而跨子网则不可以通信,创建子网还有一个好处是同一个子网的容器可以使用容器的名字互相访问,而不必使用内部IP地址

另外一种常见的网络是host的模式,docker容器直接共享宿主机的网络,容器直接使用宿主机的IP地址而且无需杠p参数进行端口映射,容器内的服务直接运行在宿主机的端口上,通过宿主机的IP和端口就能访问到容器,host的模式可以解决一些非常棘手的网络问题

我们还可以使用docker network list 来查看当前有什么网络连接方式,默认网络是不能删除的,我们可以使用命令Docker network remove命令删除自定义的子网

16.docker compose 管理容器
Docker compose使用yml文件管理多个容器,里面列出了容器之间是如何创建以及如何协同工作的,我们可以简单的把Docker compose文件理解成一个或者多个的Docker run命令,它们按照特定的格式列到了一个文件里面

以下面的例子来说,我们先创建一个子网然后创建MongoDB和MongoDB express两个容器,并且把它们加入子网右侧展示出的是对应的Docker compose文件的写法,左右两边有非常工整的对应关系,右侧最顶级的是services元素,每个服务也就是一个service都对应一个容器,左侧的--name
也就是容器名在右侧就变成了service名,左侧的镜像名在右侧写在了image后面也表示镜像名,接下来,左边的-e参数对应右边的environments都是环境变量的意思,左侧的-v对应右侧的volume,也就是挂载卷,左侧的杠p对应右边的POS也就是端口映射,左右两边唯一一点区别就是左边自定义了一个子网network,右边没有,因为Docker会为每一个compose文件都自动创建一个子网

我们可以使用docker compose up 来运行我们的docker compose,需要注意的是这个命令只会找当前目录下叫docker-compose.yaml的文件,我们看到这个命令做了两件事,首先他创建了一个子网,然后创建了两个容器,这个容器的名字跟我们在compose文件里面定义的service名字不太一样,他在前面加了一个前缀还加了一个编号

与它相反的就是compose down这个命令会停止并且删除容器
如果我们只想停止但是不想删除容器,我们可以执行Docker compose stop命令,这个命令只停止不删除,然后我们执行Docker compose start命令就可以把刚才stop命令停止的容器再启动起来,如果容器已经在运行了我们重复执行compose up命令并不会启动新的容器
如果我们想要识别非标准的文件名,我们可以在Docker compose后面接一个-f,-f指的是file也就是指定文件名,接下来,我们把非标准的文件名指定给他,这个文件名也可以在其他的目录下面,使用杠f命令就可以识别到对应的文件
