如果现在有个厨王争霸赛,比赛的菜式是做一道🐔相关的菜式,选手们需要做不同的鸡,有需要公鸡和母鸡的,有需要鸡仔的,为了让选手们完美的进行比赛,主办方为每个选手准备了独立厨房,厨房里的厨具和材料应有尽有,但问题是如果选手只做白斩鸡,你却给了他炸鸡的面粉和其他不用的材料就太浪费了,这其实就和虚拟机差不多,如果有些应用需要node8.0,有些应用需要安装node16,虚拟机虽然可以创建独立的环境,使得每个都环境都有对应的版本,但是每个环节都有自己的客户机操作系统,占用非常大的资源和空间,要解决这个问题就可以用到Docker了。
先回到厨王争霸赛选手们依然有独立的厨房,但现在的厨房并不会具有全套的厨具和材料,除了最基本的水电是公用的,其他东西都是按照实际需求进行提供,大大减少主办方费用,我们的Docker也是如此,Docker并不需要创建完整的虚拟操作系统,但还是会创建独立的环境,也就是容器 container,容器里面也是有操作系统的,这样可以跑着各自的应用程序,互不干扰,容器之间共用的是主机的内核,但是容器不会直接访问内核,而是通过Docker引擎来访问,容器里面需要什么应用再根据需求添加,不多也不少。每个选手的菜都是独一无二的,给选手的菜进行拍照,照片就相当于Docker里的镜像,假设其中一个应用或者多个应用的版本不一样,就是另一个镜像里,镜像是一个相对静态的东西,要让镜像动起来,我们可以让不同的镜像运行在不同的容器里面,做到相互隔离,厨师根据特定步骤材料做菜,也就是根据不同的菜谱,比如第一步烧开水,第二步给鸡泡汤,第三步去毛等等,这个菜谱就相当于制作镜像的Dockerfile。
如果你在特定的操作系统,使用特定版本的应用,以及各种依赖,那我们就可以把这些写入Dockerfile,要真正形成一个镜像,我们需要使用docker build命令来构建,运行的时候Docker引擎就会构建镜像,这个镜像实际上还是没有运行的,docker run这个命令可以让Docker引擎为我们分配一个新的容器,一个镜像分别在多个容器进行,镜像除了可以在自己的主机运行,还可以分享给别人,把制作好的镜像推送到Docker Hub,使用的就是docker push,docker pull拉到本地就可以使用镜像里。
实践
使用node的experss来构建
1.npm install express
创建一个app实例,随便一个端口
2.创建一个Dockerfile的文件
随便引用一个node镜像,这里使用hub上的node镜像
pakcage.json引到镜像里
RUN npm install 安装依赖,这样我们的镜像在运行时就可以自行安装express,并且生成node_modules文件里的内容了,然后把剩余的文件全部复制到镜像里。
我们在容器里的端口号和本机的端口号不同,各自不处于同个操作系统,不同的环境,所以暴露端口,然后用CMD命令运行,CMD接的内容需要用数组形势,这样我们的镜像就构建完了。
接着启动docker,在Dockerfile的当前目录输入docker build .命令
这些步骤提示就对应着我们镜像的内容
查看镜像只需要进行docker images,会显示所有的镜像
然后登录docker,push到hub在仓库里就可以看到了
构建的时候,docker build -t cxx .就可以添加名字 .表示相对地址,docker使用缓存构建,非常快。
镜像创建完成了,接下来我们需要在容器里运行一下我们的镜像了,也就是使用docker run命令 添加
docker run -d cxx -d让在后台运行,不会占用当前命令窗口
docker ps命令确认镜像是否在运行
进行端口映射docker run -d -p 3000:3000 意思就是访问主机3000端口的时候,就会访问容器端口3000
修改文件后,我们需要生成新的镜像,我们查看容易里的app.js的时候,容器正在运行,需要使用docker exec来查看,可以看到app.js内容修改后查看 镜像内的app.js是不改动的,如果每次本地文件修改都要重新构建镜像,然后新建容器运行,显然是很麻烦的,这时候我们需要+ -v选项,可以把本地指定文件夹和容器文件绑定,本地路径也可以用环境变量的方式来写,只不过不同 操作系统写法有所不同。这时候按道理热更新还是没有实现的,因为虽然我们已经绑定了文件,但是我们根据镜像启动服务的时候,也就是node执行app.js的时候,是根据执行时的服务器文件来启动的,如果文件有修改,我们需要重新用node执行app.js,我们可以用nodemon来自动重启。
每次启动容器的时候,都要写一长串命令,如果要启动多个容器来处理不同版本应用,这样肯定费劲,这个时候可以用到docker-compose,首先创建一个docker-compose.yml文件,使用yml编写
这样就可以使用docker-compose来管理容器
通过这个简单的实操可以让我们对docker有个清晰的认知了,Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
最后在使用docker的时候,docker远程连接注意别随便开启,用完记得关哦!