docker已经是开发领域的大明星,如果你现在对它不了解,那么是时候学习它了。
本文情景:需要一个可以跑特定angular版本的docker容器,用于统一项目的开发环境以及跑单元测试
技术要求:安装了docker并且会一些常用的docker命令。
背景
当前我们需要一个可以运行angular以及可以自动跑单元测试的容器,但遗憾的是docker hub中并不存在现成的容器
找镜像
虽然没有angular的镜相,但我们可以找到node的镜像,由于我们在本机开发使用的node版本是14.16.0,所以在确认node镜像时也使用相同的版本。
打开官网地址,最终发现有几个版本可供我们选择,在版本方面存在alpine
,buster
,stretch
等。简单来说就是一个原则:新手使用stretch/buster/jessie
,老手自己随便选。
本地构建
镜相确认后,便可以开始进行本地构建了。
第一步,我们先在本地建立一个文件,命名为:Dockerfile
,需要注意的该文件没有任何扩展名
第二步:编辑这个文件,并输入以下内容
FROM node:14.16.0-stretch
第三步:开始构建
来到Dockerfile
的存在文件夹,执行$ docker build . -t <imagename:version>
,即开始进行镜相构造,该速度在一定程度上依赖于网速。其中imagename:version
自己起喜欢的,比如我们在此起名为node-angular:14.16.0
最后,我们使用docker image ls
命令来查看image是否创建成功
自定义image
接下来,我们使用当前image来构建可以执行angular单元测试的node环境。
在继续工作前,我们需要认识到:一个image可以创建多个container,它们的关系就像是class与object。而任何container又都可以成为一个新的image。
我们当前要做的工作其实是:
- 根据上一步build得到的image来创建一个新的container
- 在这个container(官方名字叫容器,可以理解为一个小的独立的虚拟机)上进行环境设置,使其满足Angular的单元测试要求。
- 将已经满足Angular的单元测试要求的container要做为image来保留下来。
日后再需要进行Angular相关测试时,便可以直接使用这个image来创建新的container了。
配置container
启动容器并进入
$ docker run -it node-angular:14.16.0 /bin/bash
此时,上述命令行实际上已经在运行起来的container上了,后面我们运行的命令都将在这个container上运行并最终被保存下来。
安装chrome
接收我们参考官方的教程,来安装chrome.
依次执行以下命令:
$ apt-get update
$ wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
$ apt install -y ./google-chrome*.deb;
$ export CHROME_BIN=/usr/bin/google-chrome
更新安装源:
下载chrome:
安装chrome:
设置环境变量:
安装Angular-cli
继续安装angular-cli
$ npm install -g @angular/cli
安装vim
本文还需要对一些文件进行一些简单的编辑,所以把vim
也一并安装上。
$ apt-get install -y vim
测试
我们创建一个angular应用,并尝试进行测试.
$ ng new app
$ cd app
此时,我们需要编辑一下karma的配置文件:
$ vi karma.conf.js
将以配置:
browsers: ['Chrome'],
变更为:
browsers: ['Chrome', 'ChromeHeadless', 'ChromeHeadlessCI'],
customLaunchers: {
ChromeHeadlessCI: {
base: 'ChromeHeadless',
flags: ['--no-sandbox']
}
},
最后退出编辑器,并执行以下命令进行单元测试:
$ ng test "--no-watch" "--no-progress" "--browsers=ChromeHeadlessCI"
新建image
容器确认可用后,便可以停止该容器了。下面我们以这个container为基础,创建一个新的image.
首先使用docker ps -a
命令来查看所有的container,并找到我们想要的那个container id
$ docker commit <containerid> <repositroy:tag>
比如我们在此创建一个14.16.0-0版本:
$ docker commit 6dab5bce9bab node-angular:14.16.0-0
接下来,我们便可以使用这个新的image来创建新的container了.
$ docker image ps
$ docker run -it node-angular:14.16.0-0 /bin/bash
测试一下ng还在,说明的确是我们想要的那个环境。
以后,当我们再想在本机上启动一个angula的测试环境时,便可以依赖我们当前这个node-angular:14.16.0-0
了.
docker仓库
如果你有docker仓库的话,还可以将当前的image直接推送到docker仓库中,这样以来,其它同样拥有该仓库权限的小伙伴便可以快速的使用该image了。但大多数情况下,我们是通过自动构建来达到推送仓库这一目的,比如阿里云便提供了构建docker image的免费仓库服务。
而在这些仓库中构建的最好的办法是通过配置Dockerfile
,也就是说:我们可以把本文中执行的一些环境安装的命令也放到Dockerfile
中。
接下来,我们便可以找找本文中的历史命令,在把这些命令复制到Dockerfile
中,再然后上传到代码仓库,并结合阿里云的构建来完成自建构建了。
本文后面给出一些截图和代码,具体的作用由于超出了本文的主题范畴,不再过多描述:
Dockerfile
FROM node:14.16.0-stretch
RUN apt-get update
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN apt install -y ./google-chrome*.deb;
RUN export CHROME_BIN=/usr/bin/google-chrome
RUN apt install -y vim
RUN npm install -g @angular/cli
RUN apt-get clean
上传到github仓库
文件完成后,指定好一个文件夹,然后上传到github仓库
自动构建
然后来到阿里云的容器镜像服务,创建一个新镜像
认证后添加个构建规则:
点击立即构建:
查看构建日志:
结果小插曲出现了:
由于众所周知(wo xiang ma jie)的原因阿里云的海外机器,竟然无法连接阿里云的国内机器。。。好吧,要么我们重试两次,要么我们把构建规则中的海外机器构建(一些包的安装,国内机器可能会构建不成功)取消掉看看。
然后果然在执行 apt-get update
更新包信息的时候卡住了,不过还好是自动构建,只要是有速度,那么我就信奉:忍一时风平浪静。选择忍。
经过了漫长的等待以后,终于:
构建完成后,我们便可以像使用其它的官方image一样,在任何机器上都可以快速的获取到一份安装有chrome并且node版本是14.16.0的运行容器了。
创建container
接下来便可以根据 公网地址的信息在任意安装有docker而网络通畅的机器上来运行我们刚刚创建的image了.
由于在构建时指定的版本号并不是latest,所以在启动container时,需要指定好特定的版本号:14.16.0
$ docker run -it registry.cn-beijing.aliyuncs.com/mengyunzhi/node-chrome:14.16.0 /bin/bash
此时由于image的地址是阿里云的,所以在进行image拉取的时候还是非常快的。
至此,一个可以用于进行angular单元测试的image便成功地被构建出并可以共享给团队中其它的小伙伴来使用了。
总结
本文介绍了如何通过官方的镜像(非官方镜像也可以)打造了一个自定义功能的镜像。镜像完成了,推送到了国内的阿里云仓库,向阿里云仓库推送的好处是其它成员在使用的时候会有一个比较好的网络环境,坏处是它并没有共享到docker官方的hub中,这并不是一个好的共享方式。
其实docker就是一个小的虚拟机机制,docker中的image就相当于备份的操作系统,而根据image来创建的container就是运行的虚拟机。所以:一个image可以创建多个container,就像可以根据一个操作系统盘来在多个电脑上安装同样的操作系统一样。如果你使用过一些操作系统的clone软件的话,相信对上述概念并不陌生。