作为开发者,我们总是寻找一个捷径或更容易的方法来快速起步,对吧?如果你是团队领导,付出最少的代价让团队站在同一个起点是很重要的。 Docker可以提供帮助。
在软件开发领域,一直越来越强调模块化,从单一责任的一般原则到更具体的实现,例如将JavaScript功能模块化为无状态组件。在这里,我将告诉你我们如何使用Docker来模块化我们的开发环境,以获得许多类似的好处,包括帮助我们快速起步。
如你所知,为了加快项目进度,你有一个待办事项清单:
想象一下,如果在将应用程序的代码基线拉出存储库之后,您只需运行几个命令行(可能只有一个),可以使整个应用程序的环境准备就绪。听起来很酷,对吧?
这正是我们要完成的。不同于使用一个百科全书式的方法来使用Docker的所有功能和命令,我将介绍容器化开发人员的环境的主要的Docker功能。
这篇文章是关于利用Docker的容器化能力的一系列文章中的第一篇,它很容易构建一个可以在任何时间共享和运行的应用程序开发环境。
Docker Toolbox 对 Docker for X
Docker Toolbox是可用于处理多个Docker资源的原始工具集合,并且会根据您选择的操作系统而有所不同。但在那之后,他们发布了新的Windows和Mac原生应用程序。因此,除了Linux、OS X和Windows Docker Toolbox变体之外,您还将看到“Docker for Mac”和“Docker for Windows”。
要理解和决定应该使用哪种工具,我想概述使用新的原生应用程序的前提。原来的Docker Toolbox将会设置一些工具以及使用VirtualBox。它还将提供在Linux Hypervisor上运行的虚拟机,用于Windows或Mac。
VirtualBox、Hyper-V和Hyperkit,我的上帝啊!
原生应用程序,例如在Docker for Mac中,实际安装的是OS X原生应用程序。它也不再使用VirtualBox,而是使用OS X的hypervisor hyperkit。此外,共享接口和网络的管理更简单。还有一些用户体验更新以便于Docker更好的工作。在Docker for Windows原生应用程序中也会包含这些相同的更改,但是会使用Hyper-V作为hypervisor,以及其他类似的网络和工具更新的主机。
最后,原生应用的体验应该是一个更积极,更有效率的,而且更少的出错。但是,您会发现绝大多数与Toolbox相关的外部文档 - 因此了解Toolbox将是你的优势。
这个初始教程将简单地使用一个开箱即用的express.js应用程序。当我们开始编辑源代码并在容器之间进行通信时,我将介绍一个运行Webpack的开发服务器的进阶的通用React.js应用程序,其中包含热模块重新加载,MongoDB数据库等。
为了努力获得使用Docker并将开发人员环境与各种操作系统版本一起集中化的好处,我将让您选择需要下载的Docker版本(Toolbox或原生)和操作系统:
-
Toolbox:https://www.docker.com/products/docker-toolbox (OS X and Windows)
-
Docker for Windows:https://www.docker.com/products/docker#/windows
-
Docker for Mac:https://www.docker.com/products/docker#/mac
TOOLBOX用户
:Docker Toolbox配有“Docker快速入门终端”,并在运行时与Docker环境相关联。但是,通常在您选择的IDE中运行终端或独立运行终端。为了让Docker与另一个终端/提示进行交互,您需要通过运行“docker-machine env”来初始化Docker env。文本显示的末尾是一个命令,您需要从该同一终端中复制该命令以初始化Docker环境。
下一步是获取要容器化的开发应用程序的源代码。
现在,您可以从GitHub抓取这个项目(https://github.com/hyndsite/docker-4-devs.git),这个项目保存了本教程的一些步骤。
请记住,主要目标是在隔离和模块化的环境中运行我们的应用程序。为了让Docker创建这个环境,我们必须告诉它如何创建它。我们使用包含一组指令的Docker镜像文件(https://docs.docker.com/engine/reference/builder/)。
-
使用你的IDE,增加一个文件到工程根目录并命名为“Dockerfile”
-
拷贝下面的文件内容到这个文件
重要信息
:该Docker镜像文件将允许我们创建一个镜像,该镜像将代表我们一直在讨论的容器化环境,并最终创建称为容器的该镜像的运行实例。但是,我们向前跳了一步,这些内容应该在第5步中。
Dockerfile
FROM mhart/alpine-node:6.9.2
WORKDIR /var/app
COPY . /var/app
RUN npm install --production
EXPOSE 3000
ENV NODE_ENV=production
CMD ["node", "bin/www”]
Dockerfile是Docker在镜像文件中寻找的默认名称,但它可以是任何名称,我们将在稍后的步骤中看到。这些指令告诉Docker我们要创建一个镜像:
-
从一个基础的mhart/alpine-node镜像的6.9.2标签开始创建
-
设置应用程序初始运行的工作目录WORKDIR
-
拷贝当前本地目录“."中的内容到工作目录
-
然后从工作目录运行RUN命令npm install —production”
-
我们将对外暴露 EXPOSE3000端口从容器中,当它从镜像中被创建的时候
-
另外我们想要对容器设置本地环境变量ENV NODE_ENV的值为“production”
-
最后,我们启动express.js服务,它驻留在bin目录中的“www”文件中,执行命令“node bin/www”
提示
:Docker总是需要一个基本的镜像,镜像保持尽可能小空间占用是关键。alpine-node镜像是非常小的(49.65mb),包括Node.js和NPM。
现在我们有一个Docker镜像文件,它指定了有关如何创建镜像的详细信息,让我们停下来谈谈镜像是什么:
镜像是只读分层文件系统。它构成了我们不断追求的环境的基本文件系统。我们在上一步中创建的镜像文件将指示Docker如何去创建镜像的每层。
但如果它是一个只读的文件系统,我们如何去写它,(例如,执行代码的变化对我们的应用程序的代码在开发过程中)?好问题,我会在即将到来的步骤中回答。
步骤 4a:构建生产镜像
-
-
docker build -t express-prod-i .
提示
:对于Docker Toolbox,从Docker Quickstart Terminal开始运行Docker命令会导致错误(根据操作系统而异)。为了从任何随机终端/提示符运行命令,您需要将终端/提示链接到docker环境。运行docker-machine env,并运行它提示的命令,例如“@FOR / f”tokens = *“%i IN('docker-machine env')DO @%i”
我们做了什么?
-
我们运行build命令从我们在步骤3中创建的Docker镜像文件创建一个文件
-
使用标签开关-t,我们给镜像一个名称,我们可以使用它来引用它,而不必引用Docker生成的ID(例如50e8dde7e180)
-
我们指定了使用“.”指定的当前本地目录的镜像路径
步骤 4b:验证镜像
如果所有都按计划进行,我们应该看到(如.gif中的)一个“successful build ...”消息。我们现在可以运行一个命令来记住你的镜像:
在这种情况下,我们的组合镜像大小为61.26 MB,这是基本的alpine-node镜像和我们的express应用层的组合。
步骤 4c:观察镜像文件层
如果我们想要看到为我们的镜像创建的文件层,我们可以运行命令:
docker history express-prod-i