概要:
本篇文章将会通过以下几点简要的叙述docker 在前端开发中使用场景。
1. docker 前端应用情形
2. docker 基本概念(镜像 容器 端口映射 数据卷)介绍
3. 动手一步步搭建,前端开发环境 并生成可以团队共享的开发镜像以及团队拿到镜像后如何使用镜像快速搭建自己的开发环境。
4. 如何通过DockerFile来搭建开发环境。
docker 功能非常强大,可以保证线上线下环境一致性,可以快速部署启动项目,有极高的平台迁移性,其联合文件系统可以使得镜像非常方便的迭代升级。诸多优点,感兴趣的朋友可以自己搜索下相关的教程先熟悉下docker相关概念,如果实在看不懂也不必过多的纠结docker到底是什么东西,通俗的看他就是一个虚拟机,上面跑了很多应用,应用可以是个linux系统,也可以是实际的项目服务。其网络配置方式可以将几个不同的应用很方便的连在一起,保护你不想让用户通过外网直接访问的应用(如Mysql数据库)将其访问限制在docker 虚拟的内网环境,对外网只暴露服务层。其他的部署环境配置可以多爬爬帖子。
这里笔者推荐一本书,docker入门与实践 基础讲的很不错,笔者买了纸质版。纸质版内容和电子版的内容差不多,纸质版会多点内容。入门的话电子版的也够了。
本文只介绍其在前端使用情形,通过本篇文章你将了解
1.为什么我们要在前端开发中使用docker?
2.怎么用docker搭建我们自己开发环境,并共享给团队统一团队开发环境?
3.怎样用dockerfile 记录我们实际搭建的过程,并使用Dockerfile搭建开发环境?
这里简要的介绍下笔者的开发环境:
Macbook Air OS系统
dockertool docker工具包
一、Docker在前端开发应用情形
引用自梁杰文章用 Docker 快速配置前端开发环境
今天是你入职第一天。
你起了个大早,洗漱干净带着材料去入职。
签了合同,领了机器,坐到工位,泡一杯袋装红茶,按下开机键,输入密码,
然后,下载 Chrome、Postman、Sublime、盗版 PS、NodeJS、配置 NODE_PATH、安装 cnpm、安装 gulp、安装 webpack、安装 browserify、安装 LessSassStylus、安装 JadeCoffeePostCSS、安装 BabelExpressKoa、安装 gitpm2forever……
此处省略一万个插件。
如果顺利的话这个时候你应该已经准备下班了,当然,通常来说都不顺利。
在这个过程中,你可能会遇到网络问题环境问题兼容问题权限问题配置问题配置问题配置问题配置问题配置问题配置问题配置问题。
新人第一周周报:
本周工作:配置环境,熟悉项目
大公司的思路很简单:既然你自己搞这么麻烦,那我帮你搞好,给你个账号,直接登录上去开发。
确实没毛病,不过这个方案必须解决三个问题:
- 怎么在本机预览网页
- 怎么在本机编辑文件
- 怎么在外网访问开发机
解决方法有很多,这里只说一种:Nginx + Samba + VPN。
Nginx 可以解决第一个问题。每个工程师分配一个账号,每个账号对应一个域名,
Nginx 会把域名解析到对应用户的目录下,这样开发就可以在自己电脑上用域名预览网页
(需要配置好 host)。
举个例子,我的账号是 liangjie,项目的域名是 www.wisdomtmt.com,
那我访问 liangjie.wisdomtmt.com 就可以预览开发机中 liangjie 账号下的项目。
Samba 可以解决第二个问题。你可以把它理解成 Windows 中的“共享文件夹”。
在开发机上配置好 Samba,然后在自己机器上连接开发机,把共享文件夹拖到编辑器中就可以写代码了。
VPN 可以解决第三个问题。大公司除了专用的软件,还会配套使用硬件来提高安全系数。
VPN 硬件类似 U 盾,上面显示一串动态数字密码,定时刷新,每次外网登录 VPN 都需要附加动态密码。
这样就解决了问题,开发人员可以在自己机器上写代码,然后在浏览器中
直接预览,遇到意外情况也可以外网登录开发机修复。
粗略来看,这套方案没什么技术问题。但是对于中小型公司来说,搭建整
套开发机环境、规范开发流程、规范 VPN 使用流程、全公司切到开发机,
这一套走下来需要的时间和人力成本都不低。通常来说也只有大公司才玩得起。
那小公司呢?难道每个新员工都必须浪费时间来配置环境?
当然不是。
主角登场。
什么是 Docker?我不是 Docker 专家,所以这里不对 Docker 做专业介绍。如果你还不知道 Docker 是什么,把它看成虚拟机就可以了。
在引入 Docker 之前,我对它做了一些调研,主要想搞清楚以下几个问题:
Docker 能否跨平台?(毕竟你不能要求公司给所有人配 Mac)
* 如何预览 Docker 里的网页?
* 如何编辑 Docker 里的文件?
* Docker 能否实现一次配置多处使用?
由于 Docker 运行在每个人的机器上,因此不存在外网访问问题。
经过调研,上述问题理论上都可以解决,下面是初步确定的解决方案:
* 用端口映射预览 Docker 里的网页 (-p 8080:8080)
* 用挂载数据卷的方式映射本地文件 (-v 本地文件路径:容器路径)
* 配置一个通用的 Image(镜像)用 Kitematic 客户端实现跨平台运行 Docker
二、docker几个基本概念
Docker 中最重要的三个概念是 Container(容器)、Image(镜像)和 Volume(卷)。
Image 是静态内容,如果你要把某个 Image 跑起来,那就需要一个Container。
这里面有一点很重要:**Container 中所做的改动不会保存到Image**。
举个例子,你跑起来一个 Ubuntu Image,然后 touch newfile
创建一个新文件,这时候如果直接重启 Container,文件就没了。
那怎么保存改动?
很简单,执行docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
即可。
这里的 commit 和 git commit 类似,执行之后会把当前状态保存为一个新 Image。
有同学就要问了,如果每次做改动都要 commit,我写起代码来岂不是很不方便?万一写到一半不小心重启 Docker 怎么办?
这确实是个问题,Docker 也有对应的解决方法:使用 Volume
。
简单来说,Volume 就是专门存放数据的文件夹,启动 Image 时可以通过 `-v 本地目录:容器目录`
映射本地路径到容器,一个容器可以挂载一个或多个 Volume,Volume 中的数据独立于 Image,
**重启不会丢失**。
我们创建一个 Volume,挂载到系统的一个目录下,然后把代码都放进去就可以了。
最后说端口映射。前面说过,Docker 可以看做一个虚拟机,你的所有文件都在里面。如果你在 Container 中运行一个服务器,监听 127.0.0.1:8000,从你自己的机器上直接访问 http://127.0.0.1:8000是不行的,因为 Container 和你的机器是两个不同的环境。
那怎么办呢?我们先来看一个大家都熟悉的问题。
日常开发中我们经常需要让同事预览网页效果,常用的方法是监听 0.0.0.0:8000,然后让同事连接同一个局域网,访问 http://你的机器IP:8000即可。
Container 的问题非常相似,只不过我们自己变成了“同事”,需要访问
Docker 内部的网页。只需要在运行容器时,通过-p 如:`-p 8080:8080` 添加
端口映射然后在本机的浏览器上观察即可。
好了,枯燥的概念讲完了,理解不了也不用着急,跟着下一章走一遍流程就懂了。
三、动手搭建自己的开发环境
正式开工之前,先看看我们都要做什么。
目标:配置一个通用 Image,支持预览网页,项目文件可以在容器中开发又可以在本机上用版本管理软件管理(如:git),预装开发过程中可能用到的包。
过程:
1. 下载并安装 Docker Toolbox
2. 下载并运行 Ubuntu 镜像
3. 做常规的linux系统初始化工作(换源、安装常用的linux工具)
4. 安装前端开发工具
5. 导出镜像
1.下载并运行Ubuntu镜像
这里我推荐大家用Docker终端使用加速器后,再用终端下载。docker Hub 国内访问较慢,下载实在太慢。
镜像加速器
国内很多云服务商都提供了加速器服务,例如:
阿里云加速器
DaoCloud 加速器
灵雀云加速器
注册用户并且申请加速器,会获得如 https://jxus37ad.mirror.aliyuncs.com
这样的地址。我们需要将其配置给 Docker 引擎即可。
然后打开mac终端,输入以下命令拉取我们需要ubuntu镜像:
docker search ubuntu:14.04
docker pull ubuntu:14.04
docker images
我这里用的是ubuntu:14.04 版本的镜像而没有用官方的Ubuntu镜像了,官方的有很多工具都精简了用起来不方便。在终端输入命令后可以看到如下输出
这里笔者本地搭建了开发环境就没重新安装了,用
docker images
可以看到我们本地拥有的镜像文件。
正常的情况下你可以看到如下输出:
看到输出的sha256校验值后便表示已经下载完了。这里大家可以注意下方框阔住的区域,细心的朋友会发现我们下载ubuntu文件,是一段一段下载的,每段都有自己的ID.这就是Docker 的联合文件系统,多个镜像可以共用公共的部分,可以使得用户在拿到别人的镜像后,添加配置快速生成自己的开发镜像。
下载完后,打开kitematic 在myimages便可以看到我们刚刚下的ubuntu官方镜像文件
点击start后点击exec便可进入Ubuntu系统,或者直接在mac终端上输入
docker exec [container] /bin/bash
就可以打开终端,我们输入几行简单的shell命令看下:
可以看到熟悉的linux文件系统,太亲切了,让笔者回忆起刚毕业那会看鸟叔linux私房菜的辛酸史。
2.常规初始化工作
Ubuntu 装完系统第一件事是什么?没错,换源。
“源”其实就是网址,你在 Ubuntu 中用 apt-get install 安装软件的时候就是从“源”下载。Ubuntu 默认的源在国外,安装起来非常慢,所以要先换成国内的源。
国内有很多 Ubuntu 源,我用的是中科大源。
你可以直接看官方换源教程,也可以直接打开 Ubuntu 命令行,执行下面的命令:
sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
apt-get update
换源完毕,之后 apt-get 都会从中科大源下载软件。
前面说过,这个 Ubuntu Image 是超级精简版,很多不重要的工具都被删掉了,包括常用的vim、curl、ipconfig、ping。
除此之外,Linux 最常用的 TAB 补全路径也没有,所以下面先安装必要的编辑器和路径补全:
apt-get install vim bash-completion
这样就完成了基础配置,Ubuntu 可以正常用了。
3.安装前端工具
(1).首先安装 npm:
apt-get install npm
然后安装 cnpm,之后所有 npm 操作都改成 cnpm,从淘宝源下载,速度会快很多。
npm install -g cnpm --registry=https://registry.npm.taobao.org
(2).接着安装 n
TJ 大神的 NodeJS 版本管理工具,可以安装多个版本,一键切换。
n 需要用到 curl,所以先安装 curl:
apt-get install curl
然后安装 n:
cnpm install -g n
(3).最后使用 n 安装目前的稳定版 NodeJS:
n stable
这样就准备好了前端开发需要的基本工具。
我们的项目目前在使用 Vue,所以我还安装了 vue-cli、browserify、gulp、babel
以及相关的库,你可以根据你的项目需求安装对应的库。
(4).安装Vue-cli 等开发环境
# 全局安装 vue-cli
$ npm install --global vue-cli
4. 导出镜像
别忘了前面的提醒:如果不 commit,重启之后所有改动都会丢失!
所以先 commit。输入命令行执行:
docker ps
会看到下面这样的输出:
复制 Container name,我这里是 devtest3,然后执行:
docker commit -t registry:tag devtest3
tag 换成你想要的标签号, registry 换成你的镜像名称。我这里就是 docker commit -t dev:latest devtest3
注意:这里registry貌似不支持大写。有大写字母会报错
doker images
查看本地镜像
commit 之后就可以把当前 Container 导出 Image 了:
docker export > develop.tar
执行完后,在你的个人目录下(Mac 上是 /Users/你的用户名)可以找到 ubuntu 文件。
这就是我们的最终目标:一个完成所有配置的 Image。
稍微松口气,下面看看团队其他人如何使用这个 Image
新人使用流程:
1.准备好 Docker Toolbox 安装包和 Ubuntu Image
2.安装 Docker Toolbox
3.打开 Kitematic,注册一个 Docker Hub 账号并登陆
4.在 Kitematic 中点击左下角“DOCKER CLI”打开 Docker 命令行
5.输入命令docker import,从文件夹中直接把 ubuntu 文件拖拽到命令行中
(注意 ubuntu 文件路径中不能有中文,如果有,先把文件移动到另一个纯英文路径的文件夹中)
输入命令docker images,复制出镜像的 IMAGE ID(类似54184b993d46)
输入命令,
docker run -t -d -p 8080:8080/tcp --name dev -v /Users/yixinmac/Desktop/dockerRegistry/ssh_ubuntu/volums:/web IMAGEID
把其中的 IMAGEID 替换为上一步复制的内容.下面对上面的几个参数简要的介绍下
--name 自定义容器名称
-d 后台运行
-p 8080:8080 本地8080端口映射到容器8080端口
-v 挂载本地ssh_ubuntu/volums 文件夹到容器 /web 路径
回到 Kitematic,应该可以看到左侧多了一个容器,如果没有可以重启下Kitematic,此时环境已经搭建完毕,可以点击Kitematic 上的Ports Volumes 标签查看下容器的配置是否都正确,如果一部小心手快弄错了不碍事,大胆删,再docker run 配置正确的容器。只要镜像文件在,我们可以很方便的重新再建一个新的容器。 如果说新的容器配置了新的东西,不想删掉后重新配,没关系,commit 后再新建一个新的容器,原有的镜像可以通过docker rmi imgaeID
删除,不过推荐大家平时在启动容器的时候就养成 -t (防止容器没任务时自动退出) -v -p 的好习惯。
删除指令
1.docker rm container
即可删除
有时候容器正在运行时删除会报错,可以通过
dcoker stop container 后再删除
2.docker rm $(docker ps -a -q)
删除所有已停止的容器
查看下相关配置:
接下来我们将在容中新建一个vue 工程然后查看本地文件系统变化,最后在本地访问vue-cli 提供的nginx服务网页。
exec进入容器
输入如下命令:
su
ls
cd web/
vue init webpack myproject
cd myproject
npm install
npm run dev
本地访问localhost:8080 ,熟悉的vue欢迎页。
我们再进入本地文件系统看一下,
本地文件系统有了我们刚创建的工程文件,这部分文件我们交给git或svn管理即可。
这样前端环境就算搭建完成了,建好的镜像你可以直接通过镜像文件直接发给团队,也可以搭建docker私有仓库进行管理,推荐后者,docker私有仓库和git一样,可以很方便对现有的镜像迭代提交,具体步骤docker 入门与实践一书第十四章有,大家也可以百度下。
四、使用dockerfile 创建开发环境
这时候大家心里可能有个疑问:
既然我们可以通过上面的方式创建开发环境,为什么我们还需要使用dockerfile?
开发环境一旦搭建完后,后期我们基本上很少会懂了,久而久之可能自己都忘了对开发环境做了哪些事情。
团队分享的时候,怎么样让其他人知道你环境配置了什么而不会重复做已有的工作?
时间久了,有些服务要映射哪些端口不记得了怎么办?
这就是dockerfile的作用了。
dockerfile 和 上面的方式差不多,只是用一个文件用docker 指定的方式把我们的做的操作写在了一个文件里而已。
现在我们打开终端,进入我们指定的文件目录,新建Dockerfile 文件
新建完后我们把我们上面做过的指令,全部写下来前面 加个 RUN,不同的是apt-get install 后面多加了一个 -y
这个指令的意思是在之后需要交互的地方全部默认Yes.需要加上这样一个参数 否者在之后的建立镜像中,linux apt-get会因为得不到用户相应而自动退出。
最终得到的Dockerfile文件如下:
FROM ubuntu:14.04
MAINTAINER “niwanglongDevUbuntu”
#apt-get 换源
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update
#安装linux基本软件
RUN apt-get install -y vim bash-completion
#安装前端开发环境
RUN apt-get install -y npm
RUN npm install -g cnpm --registry=https://registry.npm.taobao.org
RUN apt-get install -y curl
RUN npm install -g -y n
RUN n stable
RUN npm install -y --global vue-cli
#开放Vue-Cli端口
EXPOSE 8080
使用Dockerfile 建立镜像。
注意箭头 所指的地方 "."表示dockerfile所在的目录。
五、坑汇总
1.CMD 总是提醒command not found 导致容器直接退出。
可以看到“”有明显的区别,换成vim 编辑后,问题解决。
2.windows下修改设置,丢失volume
2016.08.04 Windows 的 Kitematic 有 bug,如果在界面中修改设置会导致 volume 丢失,所以不要在 Kitematic 中修改任何设置,如果要改就从命令行执行
上一节提到过,Windows 的 Kitematic 有 bug,手动添加端口映射会丢失所有配置,所以我们直接用命令添加,只要不从 Kitematic 里修改配置就没问题。
有银弹
说了很多优点,下面来聊聊用 Docker 做开发环境的缺点。
首先,Docker 本身还不够成熟。
Docker 确实很强大,能支持三大操作系统,性能方面也远超传统虚拟机,但是仍然不够成熟。举一个小例子:Kitematic 在 Windows 上丢失配置的 bug 去年年底就有人报过,到现在都没解决。
其次,Docker 这套体系使用成本并不低。
试想一下,作为一个开发人员,在写代码之前必须运行 Kitematic、启动 Ubuntu 镜像、连接共享文件夹、进入镜像启动静态服务器。这个流程太重,理想的开发环境应该是透明的,打开电脑就能写代码。或许下一步可以考虑在这方面做一些自动化脚本来辅助开发。