当前位置: 首页 > 科技观察

前端工程师学Docker?看完这篇就够了

时间:2023-03-13 20:53:09 科技观察

传统虚拟机非常耗性能。Docker可以看作是一个高性能的虚拟机,不会浪费资源。主要用于Linux环境的虚拟化,比如VBox虚拟机。不同的是,Docker是为服务器虚拟化设计的,支持镜像共享等功能。前端工程师也可以用来构建代码等等。目前,Dokcer不仅让GO语言流行起来,而且还会继续流行下去。首先,让我们看一下传统虚拟机和Docker的区别。传统虚拟机:Docker:可以看到,传统虚拟机每打开一次,就相当于运行一个系统。这种系统会消耗大量的系统资源,而Docker不会。但是也达到了隔离的效果。Docker容器虚拟化的优势:环境隔离Docker实现了资源隔离,实现了一台机器上运行的多个容器互不影响。2.更快的交付和部署使用Docker,开发者可以使用镜像快速搭建标准的研发环境。开发完成后,测试和运维人员可以直接使用同一个环境部署代码。3.更高效的资源利用Docker容器的运行不需要额外的虚拟化hypervisor的支持。它是一种内核级虚拟化,可以实现更高的性能,同时需要很少的额外资源。4.更容易迁移和扩展Docker容器几乎可以运行在任何平台上,包括Ulrich、虚拟机、公有云、私有云、个人电脑、服务器等,这种兼容性让用户可以轻松地在不同平台之间迁移应用程序。5.更轻松的更新管理使用Dockerfile,只需要少量的配置修改就可以代替以往大量的更新工作。并且所有修改都以增量方式分发和更新,从而实现自动化和高效的容器管理。正式开始本文写于2019年10月13日电脑系统:MacOS使用官网下载的最新版Docker。以下代码均为手写。可以运行官网下载Docker安装包,然后直接安装https://www.docker.com/安装完成后,直接打开终端命令行,输入docker,会出现如下信息,说明安装成功。下载安装成功后,首先学习Docker容器(container)和镜像(mirror)这两个核心知识点。Docker的整个生命周期由三部分组成:镜像(image)+容器(container)+仓库(repository)思维导图如图:如何理解?每个主机(计算机),在他下载了Docker之后,可以生成多个镜像,每个镜像可以创建多个容器。发布到仓库时,以图片为单位。可以理解为:容器是一个独立的虚拟操作系统,互不影响,镜像是这个操作系统的安装包。如果要生成容器,使用安装包(镜像)生成一次即可。以上就是Docker的核心概念。下面开始正式运行,补充一点:如果想深入Docker,还是要认真研究原理。今天主要先说说应用层,我们回到终端命令行,输入:dockerimages如果你之前在电脑上创建过镜像,你会得到如下信息:如果没有,就是空的~我们先创建一个自己的镜像,写一个Node.js创建索引的服务。js//index.jsconstKoa=require('koa');constapp=newKoa();app.use(asyncctx=>{ctx.body='Hellodocker';});app.listen(3000);然后配置包。json文件{"name":"app","version":"1.0.0","private":true,"scripts":{"start":"nodeserver.js"},"dependencies":{"koa":"^2.5.0"}}一般情况下可以使用npmstart或者nodeindex.js启动服务,但是我们这里需要打包到Docker里面,所以需要写一个配置文件dockerfilevsCode有自然插件文件dockerfile目录下支持新建,添加如下配置FROMnodeADD./app/EXPOSE3000WORKDIR/appRUNnpminstallCMD["node","./index.js"]说明一下,上面配置FROM的作用是设置基本图片,我们这里需要NodeADD来转换当前文件夹下的图片要添加哪些文件,参数是我们这里使用的[src,target]。表示所有文件,当然像git一样可以配置忽略文件EXPOSE是对外暴露的端口号WORKDIR指的是工作目录,我们这里把文件添加到app目录下,所以配置app目录作为工作目录,这样就不需要在命令行RUN前加/app它是首先要执行的脚本命令。CMD是要执行的cmd命令。想一想,我们打包镜像,然后启动镜像后会发生什么?文件写好后,使用命令打包镜像,使用命令打包已经做好的文件目录dockerimagebuild./-tapp打包后出现提示:此时我们查看Docker镜像,使用命令:dockerimages我们可以清楚的看到app镜像已经打包成功,如下我们启动dockerrun-p8000:3000app使用上面的命令启动我们的镜像,然后我们在命令中输入curl127.0.0.1:8000获取返回内容hellodocker浏览器输入:127.0.0.1:8000即可访问从页面到上面的描述,我们的第一个Docker镜像就制作成功了。这里可能有人会觉得镜像和容器有点混淆。不是先有镜像再有容器吗?其实我们启动的镜像有一个脚本命令可以帮助我们启动服务,所以Docker自动创建了容器供我们查看Docker容器命令:dockerps-a列出所有容器,不用加-a只列出正在运行的,比如那些已经退出或者刚刚创建而没有上架的。dockercontainerls列出当前正在运行的容器。输入上面的dockercontainerls得到结果。原来Docker看到我们启动了脚本服务,自动为我们生成了容器?下面我们来创建一个生成镜像,重新生成容器,最后手动启动容器的例子。这次我们配置并添加Nginx反向代理服务器。首先,创建用户需要查看的html文件。这里我们给出一个普通hello-world内容的索引。然后.html文件可以创建一个dickerfile文件,配置如下,将index.html文件添加到对应位置FROMnginxCOPY./index.html/usr/share/nginx/html/index.htmlEXPOSE80端口号80为对外暴露这里特别提醒一下:配置文件怎么写,根据你的基础镜像,百度基本能找到,此时不用纠结文件结构:老规矩,开始打包dockerbuild./-thtml打印信息:终端输入命令:dockerimages得到结果:newimagehtml已经构建成功,但是此时查看容器时,没有运行中输入命令:dockercontainerls//查看所有运行中的容器dockercontainerls-a//查看所有容器结果是:可以确认我们在创建镜像的时候不会自动生成并启动容器。我们手动生成容器dockercontainercreate-p8000:80html。这时候命令行返回一个值。输入dockercontainerls不会显示任何已启动的容器。这时候我们开始手动输入dockercontainerstart***(上面的值)重复dockercontainerls命令得到结果。这时候访问localhost:8000就可以正常访问页面了~至此,我们可以确定,只要镜像没有启动,就不会生成容器,更谈不上可以运行容器,那么Doc??ker如何使用呢在前端的日常建设中?我们使用gitHub+travis+docker组成一个完整的自动化流水线只要我们把新代码push到gitHub上,它就会自动帮我们构建新代码,然后我们就可以拉取新镜像了(gitLab也有相应的代码更新)事件钩子,可以参考手动实现Jenkens的那篇文章)首先,我们先进入TravisCI官网配置,注册并绑定自己的gitHub账号,然后添加我们需要自动构建的仓库左侧gitpush后的镜像,然后在项目根目录下配置.travis.yml文件language:node_jsnode_js:-'12'services:-dockerbefore_install:-npminstall-npminstall-gparcel-bundlerscript:-parcelbuild./index。js-echo"$DOCKER_PASSWORD"|dockerlogin-u"$DOCKER_USERNAME"--password-stdin-dockerbuild-tjinjietan/mini-react:latest.-dockerpushjinjietan/mini-react:latest每次更新推送码都会下载,并且然后执行打包命令,使t您下载的图像具有最新代码大家再也不用下载打开镜像再去构建??了。为了降低复杂度,这里使用Parcel打包工具,零配置更改dockerfile的内容,将parcel打包后的内容COPY到容器FROMnginxCOPY./index.html/usr/share/nginx/html/COPY./dist/usr/share/nginx/html/distEXPOSE80添加完你的library后,选择这里的设置,添加两个环境变量:DOCKER_USERNAME和DOCKER_PASSWORD在这里,我将我写的mini-react框架的源码放到docker,然后用parcel打包工具打包,然后用nginx反向代理~特别提醒:这里的Docker容器如果要后台运行,必须要有前台进程。如果容器运行的命令不是那些已经挂起的命令(如tcp、ping),它们会自动退出。通过dockerps-a可以看到容器关闭的原因注意:jinejietan/mini-react需要替换成你的用户名/包名,然后推送代码这是一个思维导图:当配置成功后代码推送到gitHub,travis-ci会帮我们自动构建并发布新镜像。一定要学会使用:dockerps-a成功查看容器状态提示:至此,发布,自动构建镜像已经完成,正式开始拉取镜像。我们刚刚发布的镜像名称为:jinjietan/mini-react首先使用如下命令启动docker中的所有容器命令dockerstart$(dockerps-a|awk'{print$1}'|tail-n+2)closeallcontainersindocker命令dockerstop$(dockerps-a|awk'{print$1}'|tail-n+2)删除docker命令dockerrm$(dockerps-a|awk'{print$1}'|tail-n+)中的所有容器2)dockertodeleteallimagesdockerrmi$(dockerimages|awk'{print$3}'|tail-n+2)tail-n+2表示从第二行开始读取并清除当前主机上的所有镜像和容器,依次执行,然后使用:dockerimagepulljinjietan/mini-react:latest拉取镜像。这时候拉取完成后需要下载拉取,可以使用dockerimages查看当jinjietan/mini-react:latest镜像已经存在时,我们使用dockercontainercreate-p8000:80jinjietan/mini-react:latest为这个镜像创建一个容器,并绑定到端口号8000。最后输入如下命令启动mini-react框架的容器dockercontainerstart***(上面create的返回值)输入127.0.0.1:8000在浏览器中,发现访问成功,框架生效。Docker的使用大致就到这里了。我个人认为使用Docker比不使用它要好。这个技术和TypeScript差不多,已经到了学不会的地步了。不是说你一定要用,而是比如你对TypeScript不是很了解,你就没法把现在大部分优秀库的源码搞得那么清楚。越来越多的技术依赖于Docker。当然这个mini-react框架的源码也不错。有兴趣的可以学习以下,源码在:mini-react框架+镜像配置源码,记得切换到diff-async分支~