Docker for Devs:创建开发镜像

本文讲的是Docker for Devs:创建开发镜像【编者的话】本文介绍如何利用Docker本地化卷来搭建开发环境。

【3 天烧脑式容器存储网络训练营 | 深圳站】本次培训以容器存储和网络为主题,包括:Docker Plugin、Docker storage driver、Docker Volume Pulgin、Kubernetes Storage机制、容器网络实现原理和模型、Docker网络实现、网络插件、Calico、Contiv Netplugin、开源企业级镜像仓库Harbor原理及实现等。

在本系列的第一部分,我们创建了应用程序的基础Docker镜像,并运行了该镜像的实例(称为容器)。我们也鉴证了Grayskull(译者注:希曼的死对头,作者也是暴露年龄啊)的力量……我的意思是:Docker!我们完成了所有典型的应用程序的安装和运行。请注意这里我们不是从本地主机,而是从容器内运行的。继续这个Docker for Developers系列,我们将介绍如何设置可编辑的应用程序开发环境的镜像。

起航

我们在本教程的这一部分中的目标是生成一个代表我们应用程序开发版本的镜像,并设置容器的必要组件以使其运行,这样我们才可以对文件系统进行更改并将其反映在容器中。

步骤1:创建一个开发镜像

让我们在应用程序的根目录中创建一个新的Docker镜像文件,这将是我们派生镜像的说明:

FROM express-prod-i 

ENV NODE_ENV=development 

CMD ["./initialize.sh"]

我们做了什么?

我们创建了一个新的Docker镜像文件:

  • 将从我们的制作镜像“express-prod-i”中获得基本镜像……
  • ……并创建容器本地ENV变量NODE_ENV,值为“development”。
  • 最后,我们指定我们要从WORKDIR运行一个名为“initialized.sh”的bash shell脚本。

步骤2:创建我们的初始化Bash Shell脚本

我们将在容器中初始化应用程序,而不是让它在创建映像时初始化。因此,这些应用程序启动步骤(例如“npm install”)将在容器启动时进行:

1,在项目根中创建一个名为“initialize.sh”的文件
2,将以下内容粘贴到“initialize.sh”中

npm install 
node bin/www

3,从终端/提示符导航到项目根目录并运行以下命令使bash shell脚本可执行:

chmod +x initialize.sh

注意:请记住,这些容器正在基于Linux的环境中运行,因此运行chmod系统命令会将指定文件的权限设置为可执行文件,在这种情况下指的是initialize.sh文件。

我们做了什么?

如果回想起来,我们在基本的express-prod-i镜像中指定了运行“npm install”命令,它将安装的NPM软件包作为容器的一部分。但是我们在这里

  1. 创建一个文件,其中包含每次从该映像生成的容器启动时,我们想要运行的命令。
  2. 设置权限,以便可以从容器内执行文件,并在容器启动时运行诸如“npm install”之类的初始化步骤。

步骤3:创建应用开发镜像

现在,我们有一个新的Docker镜像文件,我们已经准备好创建一个镜像了。

步骤3a:构建开发镜像

就像我们在上一个教程中所做的那样,创建一个新的镜像:

1,从终端/提示符导航到我们项目目录的根目录。
2,从您的终端/提示符在项目目录的根目录下执行以下命令,不要忘记最后的[空格]和“.”

docker build -t express-dev-i -f dev.dockerfile .

我们做了什么?

  1. 我们使用Docker build命令创建了一个新的镜像。
  2. 需要注意的是,我们使用了一个代表文件的新标志(-f),以指定我们希望它使用的哪个Docker文件。记住默认文件名是Dockerfile。
  3. 如前所述,使用标签(-t)标记指定镜像名称,并给它一个名称“express-dev-i”。

步骤3b:列出镜像

我们可以看到以前和新的镜像:

docker images

步骤4:使用卷生成并运行容器

我们现在有一个镜像代表我们的应用程序的开发版本,它使用我们的生产作为基础。我们现在想运行那个容器,但是有一些新的东西:卷。

一直以来,您可能一直在想,如果源代码驻留在容器中,我们将如何编辑源代码并将其反映在运行容器中,对吗?这是我们开始实现的主要目标之一,不是吗?

我之前提到,镜像是一组区分的只读分层文件系统。每层添加或替换其下面的层。我也提到容器是镜像的运行实例。但这不止于此。容器为镜像的底层只读文件系统提供读写层。

为了将这些读和写层结合在一起,Docker使用联合文件系统。来保证容器的状态变化不会反映在镜像中。任何文件更改都严格位于容器中。这带来了一个问题。当容器脱机时,在实例化容器的底层映像中不会保留任何更改。

因此,为了持久化容器的修改(以及其他好处),Docker开发了。简而言之,卷是存在于该联合文件系统之外的目录或文件,通常位于主机(读取:您的计算机)的文件系统上。

步骤4a:创建具有卷的开发容器

现在我们有一个表示应用程序开发版本的镜像,我们准备在主机上创建一个装载卷的容器,指向应用程序的源代码本地目录:

重要提示:如果您在本地容器外运行应用程序(例如,node bin / www),与我们在shell脚本initialization.sh中设置的命令一样,您的文件夹根目录中有一个本地的node_modules目录,请删除他们。

  1. 从终端/提示符导航到express应用程序根目录
  2. docker run -name express-dev-app -p 7000:3000 -v $(pwd):/var/app express-dev-i

注意:赋给卷-v标志的值被分解为主机目录和而后的容器WORKDIR工作目录,由(:)分隔。这仅与我们的设置相关,但指定的容器目录不一定是WORKDIR目录。

我们做了什么?

  • 使用Docker RUN命令,我们生成并启动了一个容器(镜像的实例)
  • 并使用-name标志给我们的容器使用“express-dev-app”的名字
  • 将主机7000上的本地端口映射到使用-p标志(与Dockerfile EXPOSE命令一起使用)的3000的内部容器端口
  • 使用卷-v标志,我们在主机上安装了一个卷,其中$(pwd)表示主机上的“当前工作目录”到容器“/var/app ”(被指定作为Docker文件中的WORKDIR)
  • 最后,指定镜像“express-dev-i”,并将其实例作为容器运行

提示:删除容器时,默认情况下不会删除卷。但是可以使用docker remove(rm)指定-v标志来删除关联的卷“docker rm -v [容器的名称或ID]”。

步骤4b:验证容器是否正在运行

如果一切都按计划进行,您应该在终端/提示中看到npm安装的结果与正在安装的节点模块的列表一起运行。我特意留下了脱离进程的-d标志,这样便于观察。

我们可以通过运行“列出运行中容器”命令来验证运行容器是否没有任何问题导致它停止运行:

docker ps

如果没有列出,您可以将ALL -a标志添加到上述命令中以显示所有容器,并查看“express-dev-app”容器是否列出了退出错误。

步骤4c:检查容器装载信息

在继续之前,我们可以使用以下INSPECT命令来查看有关此新容器的挂在的卷信息,这将显示一大堆容器信息:

docker inspect express-dev-app

我们做了什么?

  • 我们使用Docker INSPECT命令来查看有关我们的容器的JSON格式信息……
  • ……由“Mounts”部分组成,列出……
  • ……源,它指向我们在本地主机上指定的项目根目录,以及……
  • ……目的地,它指向容器中的WORKDIR目录。

步骤5:本地编辑源代码

这是你一直在等待的那一刻。我们将直接跳入,看看我们如何在本地进行源代码修改,并将它们反映在容器中。

重要信息 :请确保查看步骤6有关安装的本地源代码和容器的一些精彩提示,命令和说明。

步骤5a:验证运行Express应用程序

浏览器到http://localhost:7000

步骤5b:编辑源代码

1. 在根目录下,导航到/views目录并打开index.jade文件
2. 找到行

p Welcome to #{title} 

3. 编辑为

p Welcome to #{title} running in a container!

4. 回到浏览器中,刷新URL(或导航到)http://localhost:7000

我们做了什么?

我们没有必要重建或甚重新启动容器,去观察这个简单但却十分伟大的前端改变,这个改变反应了我们对容器内部的修改。

步骤6:Node_Modules本地驻留

如果您记得,我们删除了在创建最后一个容器之前可能存在于本地应用程序根目录中的任何node_modules文件夹。但是,如果再次查看,则会存在node_modules文件夹。这是为什么?

托管运行node.js应用程序所需的更改(例如安装所有依赖关系节点模块)将通过我们创建的已安装卷在本地进行映射。

步骤6a:与容器进行交互

我们可以通过连接到正在运行的容器来验证。我们可以在容器上打开一个bash shell,并检查有关工作目录的信息。

我们没有在分离模式下启动容器,所以您需要停止运行容器并使用Docker start命令重新启动,如上一个教程所示,或者您需要打开一个新的终端/提示符并连接:

1,

docker exec -it express-dev-app /bin/sh 

2,提示符下输入命令:ls -l

我们做了什么?

  • 我们使用EXEC命令将运行容器连接到……
  • ……使用-it标志提供交互式终端...
  • ……并指定我们想使用/bin/sh参数连接到bash shell。
  • 您应该注意到,当我们连接到容器时,我们将自动连接到工作的WORKDIR目录。
  • 我们使用列表命令ls -l来显示目录内容实际上显示了本地卷挂载主机目录的内容。

总结

我们在Docker for Developer教程中完成的似乎很简单,但功能非常强大。我们将应用程序设置模块化到容纳所有应用程序所需设置的容器,同时保持对在容器中运行应用程序的源代码的控制。

我们只是破解了应用程序开发以及Docker使用容器化的方式和方法。在下一个教程中,我们将使用并运行一个通用(同构)React.js应用程序,并将热模块重新加载到容器中,使培训更贴近实际应用场景。

原文链接:Docker for Devs: Creating a developer image(翻译:高洪涛)

===========================================
译者介绍

高洪涛,当当网架构师,开源数据库分库分表中间件Sharding-JDBC作者。目前从事Docker,Mesos相关工作

原文发布时间为:2017-07-04

本文作者:高洪涛

本文来自合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:Docker for Devs:创建开发镜像

时间: 2024-09-20 00:25:43

Docker for Devs:创建开发镜像的相关文章

用Docker创建开发环境

本文讲的是用Docker创建开发环境,[编者的话]鉴于还没有用Docker创建本地开发环境的先例,Jeff Nickoloff开创了一个先例,相信大家也可以. 译者解释用Docker创建开发环境:作者在此处使用了Frankenstein一词.Frankenstein,<弗兰肯斯坦>原是英国诗人雪莱的妻子玛丽·雪莱在1818年创作的小说,被认为是世界第一部真正意义上的科幻小说.弗兰肯斯坦来自于此小说,可以理解为怪人;毁灭创造者自己之物 知道一个事物和实现这个事物是完全不同的事情.从Docker诞

Docker 在 PHP 项目开发环境中的应用

环境部署是所有团队都必须面对的问题,随着系统越来越大,依赖的服务也越来越多,比如我们目前的一个项目就会用到: Web服务器:Nginx Web程序:PHP + Node 数据库:MySQL 搜索引擎:ElasticSearch 队列服务:Gearman 缓存服务:Redis + Memcache 前端构建工具:npm + bower + gulp PHP CLI工具:Composer + PHPUnit 因此团队的开发环境部署随之暴露出若干问题: 依赖服务很多,本地搭建一套环境成本越来越高,初级

用 Docker 快速配置前端开发环境

本文讲的是用 Docker 快速配置前端开发环境[编者的话]最近在公司实践了一下 Docker,记录成了一篇文章,发出来和大家交流下.我基本上是个 Docker 新手,如果有什么地方说得不对请大家指出~目前的方案还比较粗糙,大家有什么改进建议也请告诉我,我多和大家学习 今天是你入职第一天. 你起了个大早,洗漱干净带着材料去入职. 签了合同,领了机器,坐到工位,泡一杯袋装红茶,按下开机键,输入密码, 然后,下载 Chrome.Postman.Sublime.盗版 PS.NodeJS.配置 NODE

用Git子模块和Docker Compose实现高效开发工作流

本文讲的是用Git子模块和Docker Compose实现高效开发工作流,[编者的话]搭建开发环境一直让程序员们头疼,本文使用Git子模块和Docker Compose实现高效率的开发工作流,让程序员能够轻松搭建出开发环境,把精力投入到需要开发的应用本身. 问题 自我们从Continuous Software雇佣了第一位远程开发的程序员以来,我们就意识到精简开发工作流的重要性.当新入职的程序员接手由很多应用组成的复杂项目时,我们想尽量避免以下这几个问题: 缺少stack模块:Node.js.PH

Docker 1.8:可信镜像、Toolbox、Registry 以及编排工具大更新

本文讲的是Docker 1.8:可信镜像.Toolbox.Registry 以及编排工具大更新,[编者的话]1.7 发布不到一个月 1.8 就重磅来袭.生产.生产还是生产,Docker 为了让自己能更适应生产环境进行了加速奔跑,我们也需要紧随技术的步伐不断前进. 我们很高兴的宣布 Docker 1.8 的发布,最新的版本包含了对镜像签名的支持,新的安装器以及 Engine.Compose.Swarm.Machine 以及 Registry 的多项改进. 你们过去总是和我们说想要一个扩展性更好的

docker 搭建私有仓库及镜像存储目录结构

仓库 (Repository)是集中存放镜像的地方, docker 仓库分为公有仓库和私有仓库,然而公有仓库在某些情况下并不适用于公司内部传输,所以在这边我来搭建私有环境的 registry .那私有仓库较公有仓库有以下优点: 省带宽 传输速度快 方便存储 下面我们来创建私有仓库,实现 docker client 通过 docker registry 上传和下载 docker images,最后说下docker registry 的存储方式. 本实验要达到的效果是: 1.docker regis

用Dokcer创建开发环境

作者在此处使用了Frankenstein一词.Frankenstein,<弗兰肯斯坦>原是英国诗人雪莱的妻子玛丽·雪莱在1818年创作的小说,被认为是世界第一部真正意义上的科幻小说.弗兰肯斯坦来自于此小说,可以理解为怪人;毁灭创造者自己之物 知道一个事物和实现这个事物是完全不同的事情.从Docker诞生那天开始,我们就梦想着诸如"15秒部署一个项目","版本可控开发环境",以及时髦的运维用语,如"滚动开发","软件定义架构&

Docker基础之十: 存储镜像到Docker Hub

存储镜像到Docker Hub (对Docker感兴趣的朋友可以加我的微信ghostcloud2016,然后我把你加到我们的一个Docker爱好者群组里面.) 到目前为止,我们已经学习了docker的基本用法,包括拉取镜像,运行容器,编译镜像文件等等.接下来,我们将学习如何通过docker hub来简化你的操作,并提高你的工作效率. Docker Hub是Docker的主仓库,由Docker公司进行维护.这个仓库里面包含了系统的官方镜像,同时提供简单的用户认证信息,以及其他的附属功能.默认情况下

Docker 实现浏览器里开发Android应用的功能_docker

在浏览器里开发Android应用          这里需要用到Docker的知识, Che 发布后对Android应用开发多了一个工具,这里就对如何实现该功能就行详细介绍:                                                                    Eclipse Che 最近Che发布了正式版,那我就介绍下在Che上开发Android吧-- 使用Che需要懂得一些Docker的知识,只需要一点点即可,因为Che是基于Docker的,所