前端工程师,为什么要学习Docker ?

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_虚拟化传统的虚拟机,非常耗费性能

 

Docker可以看成一个高性能的虚拟机,并且不会浪费资源,主要用于Linux环境的虚拟化,类似VBox这种虚拟机,不同的是Docker专门为了服务器虚拟化,并支持镜像分享等功能。前端工程师也可以用于构建代码等等

 

 

目前看,Dokcer不仅带火了GO语言,还会持续火下去

 


首先,我们看看传统的虚拟机和Docker的区别

 

    传统的虚拟机:

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_虚拟化_02

 


Docker:

前端工程师学Docker ? 看这篇就够了   【原创精读】_虚拟化_03

 

可以看到,传统的虚拟机是每开一个虚拟机,相当于运行一个系统,这种是非常占用系统资源的,但是Docker就不会。但是也做到了隔离的效果

 


 

Docker容器虚拟化的优点:

 

 

1. 环境隔离

Docker实现了资源隔离,实现一台机器运行多个容器互不影响。

 

2. 更快速的交付部署

使用Docker,开发人员可以利用镜像快速构建一套标准的研发环境,开发完成后,测试和运维人员可以直接通过使用相同的环境来部署代码。

 

3. 更高效的资源利用

Docker容器的运行不需要额外的虚拟化管理程序的支持,它是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。

 

4. 更易迁移扩展

Docker容器几乎可以在任意的平台上运行,包括乌力吉、虚拟机、公有云、私有云、个人电脑、服务器等,这种兼容性让用户可以在不同平台之间轻松的迁移应用。

 

5. 更简单的更新管理

使用Dockerfile,只需要小小的配置修改,就可以替代以往的大量的更新工作。并且所有修改都是以增量的方式进行分发和更新,从而实现自动化和高效的容器管理。


 

正式开始

 

本文撰写于2019年10月13日

 

电脑系统:Mac OS

 

使用最新版官网下载的Docker

 

以下代码均手写,可运行

 


 

 


安装后直接打开

 

打开终端命令行,输入docker,会出现以下信息,那么说明安装成功

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_github_04

 


下载安装成功后,首先学习下Docker的两个核心知识点

 

container(容器)和image(镜像)

 

 Docker的整个生命周期三部分组成:镜像(image)+容器(container)+仓库(repository)

 

思维导图如下:

前端工程师学Docker ? 看这篇就够了   【原创精读】_html_05


 

该如何理解呢?

 

每台宿主机(电脑),他下载好了Docker后,可以生成多个镜像,每个镜像,可以创建多个容器。发布到仓库时,以镜像为单位。可以理解成:一个容器就是一个独立的虚拟操作系统,互不影响,而镜像就是这个操作系统的安装包。想要生成一个容器,就用安装包(镜像)生成一次

 

 


    

 

上面就是Docker的核心概念,下面开始正式操作

 

补充一点:如果想深入Docker , 还是要去认真学习下原理,今天我们主要讲应用层面的

 

 

首先,我们回到终端命令行操作

 

输入:

  •  
docker images

如果你的电脑上之前有创建过的镜像,会得到如下:

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_nginx_06

 

如果没有的话就是空~ 

 

我们首先创建一个自己的镜像

 

先编写一个Node.js服务

 

创建index.js

 

  •  
// index.jsconst Koa = require('koa');const app = new Koa();
app.use(async ctx => { ctx.body = 'Hello docker';});
app.listen(3000);

 

然后配置package.json文件

  •  
{    "name": "app",    "version": "1.0.0",    "private": true,    "scripts": {      "start": "node server.js"    },    "dependencies": {      "koa": "^2.5.0"    }   }

正常情况下 使用

  •  
npm start 或 node index.js 就可以启动服务

可是我们这里需要打包进Docker中,这里就需要写一个配置文件dockerfile

 

vsCode有天然插件支持

 

在目录下新建文件dockerfile,加入如下配置

  •  
FROM  node ADD . /app/EXPOSE 3000WORKDIR /appRUN npm installCMD ["node","./index.js"]

 

解释一下,上面这些配置的作用

 

FROM 是设置基础镜像,我们这里需要Node

ADD是将当前文件夹下的哪些文件添加到镜像中 参数是 [src,target]

这里我们使用的 .  意思是所有文件,当然跟git一样,可以配置ignore文件

EXPOSE是向外暴露的端口号

WORKDIR是说工作目录,我们这里将文件添加到的是app目录,所以配置app目录为工作目录, 这样就不用在命令行前面加/app了

RUN是先要执行的脚本命令

CMD是执行的cmd命令

 


 

可以想一想,我们打包好镜像后,然后启动镜像会发生什么?

 

 

文件编写完,使用命令打包镜像

使用命令打包已经好的文件目录

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_github_07

 

  •  
 docker image build ./ -t app

 

打包后出现提示:

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_github_08

 

 

此时我们查看Docker镜像,使用命令:

  •  
docker images

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_docker_09

我们可以清楚看到,app镜像已经打包成功,下面我们启动它

 

  •  
docker run -p 8000:3000 app 

 

使用上面命令即可启动我们的镜像,这时我们在命令中输入 

  •  
curl 127.0.0.1:8000

得到返回内容

 

Hello docker 

 

 


 

 

以上说明,我们的第一个Docker镜像已经制作成功

 

有人可能会觉得到这里,镜像和容器有点混淆了,不是先有镜像再有容器吗?

 

其实是我们启动的镜像有脚本命令帮我们启动了服务,于是Docker帮我们自动创建了容器

 

查看Docker容器命令:

  •  
docker ps -a 列出所有容器不加 -a 仅列出正在运行的,像退出了的或者仅仅只是创建了的就不列出来docker container ls 列出当前运行的容器

输入上面 docker container ls

得到结果

前端工程师学Docker ? 看这篇就够了   【原创精读】_html_10

 

 

原来Docker看我们启动了脚本服务,帮我们自动生成了容器? 

 


 

 

下面我们来一个生成镜像,再生成容器,最后手动启动容器的例子

 

这次我们配置,加入Nginx反向代理服务器

 

首先,创建用户需要看到的html文件

 

这里我们给一个普通的 hello-world内容的index.html文件即可

 

然后创建dickerfile文件,配置如下,将index.html文件添加到对应的位置

 

  •  
FROM nginx
COPY ./index.html /usr/share/nginx/html/index.html
EXPOSE 80

 

对外暴露端口号80

 

这里特别提示:配置文件怎么写,根据你的基础镜像来,百度基本都能找到,不用纠结这个

 

此时的文件结构:

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_虚拟化_11

 


 

老规矩,开始打包

 

  •  
docker build ./ -t html

 

打印信息:

前端工程师学Docker ? 看这篇就够了   【原创精读】_nginx_12

 

输入终端命令:

  •  
docker images

得到结果:

前端工程师学Docker ? 看这篇就够了   【原创精读】_github_13

 

新的镜像html已经构建成功,但是此时查看容器,是没有正在运行的

 

输入命令:

  •  
docker container ls //查看正在运行的所有容器docker container ls -a  //查看所有容器

得到结果是:

前端工程师学Docker ? 看这篇就够了   【原创精读】_github_14

 

可以确认的是,我们创建镜像不会自动生成和启动容器

 

我们手动生成容器

  •  
docker container create -p 8000:80 html


此时命令行返回  一段值

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_docker_15

 

输入

  •  
docker container ls

没有显示有任何启动的容器,这时候我们手动启动

 

输入

  •  
docker container start ***(上面那段值)

 

再重复 docker container ls 命令

 

得到结果

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_虚拟化_16

 

此时访问localhost:8000即可正常访问页面~

 


 

至此,我们可以确定,创建镜像只要不启动,不会生成容器,更不会运行容器

 

 

那怎样将Docker用在前端的日常构建中呢?

 

 

我们使用gitHub+travis+docker来形成一套完整的自动化流水线

 

 

只要我们push新的代码到gitHub上,自动帮我们构建出新的代码,然后我们拉取新的镜像即可(gitLab也有对应的代码更新事件钩子,可以参考那位手动实现Jenkens的文章)

 

 

首先我们先进入  Travis CI 官网配置,注册绑定自己的gitHub账号

 

然后在左侧将自己需要git push后自动构建镜像的仓库加入

 

 

接着在项目根目录配置 .travis.yml 文件

 

  •  
language: node_jsnode_js:  - '12'services:  - docker
before_install: - npm install - npm install -g parcel-bundler
script: - parcel build ./index.js - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - docker build -t mini-react:latest .  - docker push mini-react:latest

 

每次更新push代码,都会下载,然后执行打包命令,这样你下载的镜像就是有最新的代码。不再需要每个人下载打开镜像再去build


 

为了降低复杂度,这里使用了Parcel打包工具,零配置

 

 

更改dockerfile内容,将parcel打包后的内容COPY进容器

  •  
FROM nginxCOPY ./index.html /usr/share/nginx/html/COPY ./dist /usr/share/nginx/html/distEXPOSE 80

 

添加好了你的库之后,选择这里的设置

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_github_17

 

 

然后添加两个环境变量:


DOCKER_USERNAMEDOCKER_PASSWORD

前端工程师学Docker ? 看这篇就够了   【原创精读】_docker_18

 

这里,我将我编写的mini-react框架源码,放入docker中,然后使用parcel打包工具打包,再用nginx反向代理~

 

特别提示:这里的Docker容器,想要后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如tcp,ping),就是会自动退出的

 

通过 docker ps -a 可以看到容器关闭的原因

 

注意 :jinejietan/mini-react应该换成你的用户名/包名,再push代码

 


 

这是思维导图:

 

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_docker_19

当配置成功,代码被推送到gitHub上后,travis-ci帮我们自动构建发布新镜像

 

一定要学会使用: docker ps -a  查看容器的状态

 

成功的提示:

前端工程师学Docker ? 看这篇就够了   【原创精读】_github_20

前端工程师学Docker ? 看这篇就够了   【原创精读】_虚拟化_21

 

至此,发布,自动构建镜像已经完成


 

正式开始拉取镜像,启动容器

我们刚才发布的镜像名称是:jinjietan/mini-react
 先使用下面几条命令 

docker中 启动所有的容器命令

docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)

docker中 关闭所有的容器命令

docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)

docker中 删除所有的容器命令

docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2)

docker中 删除所有的镜像

docker rmi $(docker images | awk '{print $3}' |tail -n +2)

tail -n +2 表示从第二行开始读取

 

清除当前宿主机上面所有的镜像,容器,依次执行

 

 

然后使用:

  •  
docker image pull jinjietan/mini-react:latest

拉取镜像,这时候需要下载

 

拉取完成后,使用

  •  
docker images

可以看到jinjietan/mini-react:latest镜像已经存在了

 

我们使用docker container create -p 8000:80 jinjietan/mini-react:latest创建这个镜像的容器,并且绑定在端口号8000上

 

最后输入下面的命令,即可启动mini-react框架的容器

  •  
docker container start  ***(上面create的返回值)

 


 

 

浏览器输入 127.0.0.1:8000 发现,访问成功,框架生效。

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_html_22


Docker的使用,我们大致就到这里,个人认为,用Docker比不用好,这个技术已经快跟TypeScript一样,到不学不行的阶段了。

 

并不是说你非要用它,而是比如说,你如果不怎么懂TypeScript,你就没办法把如今那些优秀库的大部门的源码搞得那么清楚。

 

越来越多的技术在依赖Docker

 


 

当然,其实这个mini-react框架源码也是不错的,如果有兴趣可以了解以下,源码都在:

mini-react框架+镜像配置源码,记得切换到diff-async分支哦~

https://github.com/JinJieTan/mini-react

 

 

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_虚拟化_23

 

前端工程师学Docker ? 看这篇就够了   【原创精读】_nginx_24