如何在IDE中如何使用dockerfile

中国领先的IT技术网站
51CTO旗下网站
八种最常见Docker开发模式 别说你还不知道
Docker已迅速成为本人最喜欢的基础工具之一,以便构建可重复软件产品,从而带来尽可能静态的服务器环境。我在本文中将概述我在使用Docker的过程中开始反复出现的几种模式。我不指望它们会带来多少新奇或惊喜,但希望其中一些有用,我也很想听听各位在使用Docker过程中遇到的模式。
作者:布加迪编译来源:51CTO| 09:40
Docker已迅速成为本人最喜欢的基础工具之一,以便构建可重复软件产品,从而带来尽可能静态的服务器环境。
我在本文中将概述我在使用Docker的过程中开始反复出现的几种模式。我不指望它们会带来多少新奇或惊喜,但希望其中一些有用,我也很想听听各位在使用Docker过程中遇到的模式。
我试用Docker的基础是保持在卷中持续的状态,那样Docker容器本身可以随意重建,而不会丢失数据(除非我改动容器状态,而不更新Docker文件(Dockerfile)的状态,而经常重建容器有助于改掉这个坏习惯)。
下面的示例Docker文件都专注于此:构建容器DD在这种环境下,容器本身可以随时更换,没必要考虑它。
1. 共享基础容器
Docker鼓励&继承&,所以这应该并不奇怪DD继承是高效使用Docker的一个基本方面,尤其是由于它有助于减少构建新容器所需的时间,因为没必要那么频繁地重新执行步骤。Docker会试图将中间步骤放入到缓存,它在这方面做得很好DD有时太好了,不过要是没有明确注明,也很容易错过共享的机会。
将我的各种容器迁移到Docker上时明显出现的事情之一是,存在太多的冗余设置。
我为预计部署到任何地方的大多数项目运行单独的容器,至少它需要任何长时间运行的进程,或者需要&标准&程序包集之外的任何特定程序包时,是这样,因而我有好多容器,而程序包迅速变得越来越多。
等到我考虑迁移时,就试图在Docker中运行&一切&(包括我依赖的少数几个桌面应用程序),以便让我的mybase环境完全可以随意使用。
于是我很快开始将我的基本设置提取到基础容器,用于众多用途。下面是我当前的&devbase&Docker文件:
FROM&debian:wheezy&&RUN&apt-get&update&&RUN&apt-get&-y&install&ruby&ruby-dev&build-essential&git&&RUN&apt-get&install&-y&libopenssl-ruby&libxslt-dev&libxml2-dev&&#&用于调试&&RUN&apt-get&install&-y&gdb&strace&&#&设置我的用户&&RUN&useradd&vidarh&-u&1000&-s&/bin/bash&--no-create-home&&RUN&gem&install&-n&/usr/bin&bundler&&RUN&gem&install&-n&/usr/bin&rake&&WORKDIR&/home/vidarh/&&ENV&HOME&/home/vidarh&&VOLUME&[&/home&]&&USER&vidarh&&EXPOSE&8080&
这里没有什么需要特别说明的DD它安装了我往往喜欢随时可用的一些特定工具。这些工具对大多数人来说恐怕不一样。选择什么样的发行版很随意。值得考虑的是,如果/当你重建容器时,就要指定一个特定的标记以避免意外。
它在默认情况下暴露了端口8080,因为那是我通常暴露Web应用程序的端口,我通常将这些容器用于这些Web应用程序。
它为我添加了一个用户,将userid设置为服务器上的用户ID,并不创建/home目录。之所以不创建/home目录,是由于我从主机绑定挂载共享/ home,这就引出了下一种模式。
2. 共享卷开发容器
我的所有开发容器与主机至少共享一个卷:/ home,这么做是为了便于开发。就许多应用程序而言,它让我可以让与合适的基于文件-系统-变更的代码重载器一起运行的应用程序处于开发模式,那样容器就可以封装操作系统/发行版层面的依赖项,并且帮助证实捆绑的应用程序在原始环境中运行,我用不着针对每处代码变更,需要完全重启/重建虚拟机。与此同时,我可以相当频繁地重启虚拟机,确保没有什么错失。
至于其他,它让我可以只要重启(而不是重建)容器,即可接受代码变更。
对于测试/试运行容器和生产容器,我在大多数情况下会避免通过卷共享代码,而是使用&ADD&命令,将相应代码添加到Docker容器本身中。
比如说,下面是我&homepage&开发容器的Docker文件,它含有我自主开发的个人维基,可利用来自&devbase&容器的已经共享的/home卷,并展示了共享基础容器和我如何使用共享/home卷:
FROM&vidarh/devbase&&WORKDIR&/home/vidarh/src/repos/homepage&&ENTRYPOINT&bin/homepage&web&
(注意:我确实应该对我的devbase容器加上版本标记)
至于我博客的开发版本:
FROM&vidarh/devbase&&WORKDIR&/&&USER&root&&#&针对Graphivz整合&&RUN&apt-get&update&&RUN&apt-get&-y&install&graphviz&xsltproc&imagemagick&&USER&vidarh&&WORKDIR&/home/vidarh/src/repos/hokstad-com&&ENTRYPOINT&bundle&exec&rackup&-p&8080&
因为它们从共享软件库获取代码,而且基于共享的基础容器,当我添加/修改/删除依赖项时,这些容器通常可以极其迅速地重建,我觉得这很重要,以便确保我没有忍不住采用疏忽未记录依赖项的变通方法。
即便如此,肯定有些方面是我想改进的。尽管上述基础容器是轻量级,但它们肯定不止这样:这些容器中的大多数内容仍然未使用。由于Docker采用写时拷贝(copy-on-write)覆盖,这不会导致庞大开销,但确实仍意味着我并没有真正体现最基本需求,也没有尽可能减少攻击或出错风险(我倒不是很担心这些特定情况的攻击风险,因为我的博客并不在&实时&版本中含有任何重要状态。)。
3. 开发工具容器
这对像我们这些喜欢依靠通过ssh连接至屏幕会话来编写代码的人来说可能最有吸引力,而对IDE人群来说不太有吸引力;但对我来,上述方案的一个好处就是,它让我可以将编辑和测试执行部分代码与运行开发中的应用程序分离开来。
过去开发系统方面很烦人的问题之一是,开发及生产依赖项与开发工具依赖项很容易混在一起。你可以试着将它们分开来,但除非这些设置真正做到了分离开来,否则很容易建立未记录依赖项。
在过去,我花了几周对应用程序的依赖项进行&反向工程&后,总算搞清楚了这个问题。由于开发环境、测试和初始原型部署环境混在一起,这个应用程序积累了各种各样的未记录依赖项。
虽然有很多方法可以解决这个问题:只要确保你进行定期的测试部署,结合上述模式,但我还是有一种个人很喜欢的解决方案,因为它可以从根本上防止问题出现:
我有一个单独的容器含有Emacs安装环境,还有我喜欢随时可用的其他各种工具。我仍试图保持精简,但问题是,我的屏幕会话可以驻留在这个容器中,结合我那台笔记本电脑上设置的&autossh&,几乎总是有一条连接与容器相连,那样我就可以编辑与我的其他开发容器&实时&共享的代码。
在这个容器,我还允许偶尔出错:直接安装程序包,因为它只影响调试和开发。
目前,它看起来如下:
FROM&vidarh/devbase&&RUN&apt-get&update&&RUN&apt-get&-y&install&openssh-server&emacs23-nox&htop&screen&&#用于调试&&RUN&apt-get&-y&install&sudo&wget&curl&telnet&tcpdump&&#&针对32位试验&&RUN&apt-get&-y&install&gcc-multilib&&#&参考手册页和&most&viewer:&&RUN&apt-get&install&-y&man&most&&RUN&mkdir&/var/run/sshd&&ENTRYPOINT&/usr/sbin/sshd&-D&&VOLUME&[&/home&]&&EXPOSE&22&&EXPOSE&8080&&
结合共享&/ home&,这给了我一个足够实用的小地方可以通过ssh连入。我确信,用它用得越多,我会补充它,但眼下它证明完全能满足我的需要。
4. 不同环境下测试容器
我特别喜欢Docker的一个方面是,可以在不同环境下轻松测试代码。比如说,我升级Ruby编译项目以便处理Ruby 1.9(早就该有了)后,创建了这个小小的Docker文件,好让我在将主开发环境迁移到1.9之后,在Ruby 1.8环境中生成一个外壳。
FROM&vidarh/devbase&&RUN&apt-get&update&&RUN&apt-get&-y&install&ruby1.8&git&ruby1.8-dev&
当然,你可以用rbenv等获得类似的效果。但我总是觉得这些工具很烦人,因为我更喜欢尽量使用发行版程序包来部署,尤其是由于,如果我确保这顺利开展,它让其他人更容易使用我的代码。
拥有这样一个Docker容器:当我暂时需要不同的环境时,只要运行&docker run&,圆满地解决了这个问题,而且还有这个好处:它并不受制于像Ruby这种有预包装自定义工具来处理版本的编程语言。
我还可以使用标准虚拟机来达到目的,但是可以在短得多的时间内启动上述docker容器。
5. 构建容器
如今我编写的代码大多是用解释语言编写的,但即使那样,还是常常会有实用的&构建&(build)步骤需要花很大的开销,我宁可不是一直执行它们。
一个例子是为Ruby应用程序运行&捆绑工具&(bundler)。捆绑工具可为Rubygem更新缓存的依赖项(还可视情况更新全部的gem文件,甚至更新未打包的内容),针对较大的应用程序运行捆绑工具要花一段时间。
它还常常需要应用程序运行时并不需要的依赖项。比如说,安装依赖原生扩展的gem常常依赖众多的程序包DD常常没有记录到底是哪些程序包,通过获取所有的build-essential程序包及其依赖项,就更容易启动。与此同时,虽然你可以事先让捆绑工具做所有的工作,但我真的不想在主机环境中运行它,主机环境可能与容器兼容,也可能不兼容。
这方面的解决办法就是创建构建容器。如果依赖项不同的话,你可以创建单独的Docker文件,也可以重复使用主应用程序Docker文件,只要覆盖命令来运行你所需要的构建命令。比如说,Docker文件看起来如下:
FROM&myapp&&RUN&apt-get&update&&RUN&apt-get&install&-y&build-essential&[assorted&dev&packages&for&libraries]&&VOLUME&[&/build&]&&WORKDIR&/build&&CMD&[&bundler&,&&install&,&--path&,&vendor&,&--standalone&]&
然后,只要你更新了依赖项,将你的build/source目录挂载到容器的&build&目录下,就可以运行这段命令。只要更换合适的项就行。
关键在于,你可以将应用程序的构建或者其一部分与最后的包装分开来,同时仍封装Docker容器中的进程和依赖项,只要将进程细分到两个或多个容器中。
6.安装容器
这种方法虽非我原创,但确实值得一提。出色的nsenter和docker-enter工具随带一个安装选项,这与流行的,但又令人畏惧的&curl [你无法控制的某个URL] | bash&模式相比是个很大的进步。它通过提供实现上述&构建容器&模式的Docker容器来做到这一点,不过更进了一步。它值得关注。
这是Docker文件的最后部分,之后下载并构建了一个合适的nsenter版本(我要提醒的一点是,对下载文档没有进行完整性检查):
ADD&installer&/installer&&CMD&/installer&&&installer&看起来如下:&&#!/bin/sh&&if&mountpoint&-q&/&then&&echo&&Installing&nsenter&to&/target&&&cp&/nsenter&/target&&echo&&Installing&docker-enter&to&/target&&&cp&/docker-enter&/target&&else&&echo&&/target&is&not&a&mountpoint.&&&echo&&You&can&either:&&&echo&&-&re-run&this&container&with&-v&/usr/local/bin:/target&&&echo&&-&extract&the&nsenter&binary&(located&at&/nsenter)&&&fi&
虽然恶意攻击者仍有可能企图利用容器可能存在的特权提升问题大做手脚,但是攻击风险至少要小得多。
但这种模式最可能立即吸引我们大多数人的地方在于,避免了这一风险:本意良好的开发人员偶尔在安装脚本方面犯下很危险的错误。
我确实很喜欢这种方法。但愿它会有助于减少大家对&curl [something] | bash&的厌恶感(但即使没有起到这个作用,至少我们可以轻松控制容器里面的东西)。
7. 盒子中默认服务容器
如果我&认真对待&某个应用程序,会比较迅速地准备好合适的容器,为开发项目处理数据库等服务,但我觉得拥有一系列&基本&的基础设施容器非常重要,我可以进行合适的调整/改动,就能启动所选择的数据库,或者所选择的有合适默认设置的队列系统。
当然你也可以&基本上如愿以偿&,只要试一试&docker run [某个应用程序名称]&,祈祷Docker索引中有一个出色的替代者,而且这个替代者常常就在索引中。但我喜欢先审查,比如弄清楚它们如何处理数据,然后我更有可能将自己的修改后版本添加到自己的&库&中。
比如说,我有一个Beanstalkd的Docker文件:
FROM&debian:wheezy&&ENV&DEBIAN_FRONTEND&noninteractive&&RUN&apt-get&-q&update&&RUN&apt-get&-y&install&build-essential&&ADD&http:&&RUN&cd&/tmp&&&&tar&zxvf&v1.9.tar.gz&&RUN&cd&/tmp/beanstalkd-1.9/&&&&make&&RUN&cp&/tmp/beanstalkd-1.9/beanstalkd&/usr/local/bin/&&EXPOSE&11300&&CMD&[&/usr/local/bin/beanstalkd&,&-n&]&
我的目标是能够&OK,我将需要memcached、postgres和beanstalk&,运行三个快速&docker run&命令后,会启动并运行三个容器,它们都针对我的环境和默认环境个人偏好已经过了改动,随时可以使用。设置&标准&基础设施部件应该只需要1分钟,而不是占用开发本身的时间。
8. 基础设施/粘合剂容器
许多这种模式专注于开发环境(这意味着生产环境方面还有更多需要讨论的),但缺少了一大类别:粘合剂容器。
其目的是把你的环境组合成统一整体的容器。这是到目前为止有待我进一步研究的领域,不过我会提到一个特别的例子:
为了能够轻松访问我的容器,我有一个小小的haproxy容器。我有一个指向主服务器的通配符DNS项,一个iptable项允许访问我的haproxy容器。Docker文件没什么特别之处:
FROM&debian:wheezy&&ADD&wheezy-backports.list&/etc/apt/sources.list.d/&&RUN&apt-get&update&&RUN&apt-get&-y&install&haproxy&&ADD&haproxy.cfg&/etc/haproxy/haproxy.cfg&&CMD&[&haproxy&,&&-db&,&&-f&,&&/etc/haproxy/haproxy.cfg&]&&EXPOSE&80&&EXPOSE&443&
这里有趣的部分是haproxy.cfg,它由一段从&docker ps&的输出结果生成后端部分(就像这里)的脚本和前端定义中的一批acls和use_backend语句共同生成,前端定义将[hostname].mydomain发送到右边的backend.backend测试。
backend&test&&acl&authok&http_auth(adminusers)&&http-request&auth&realm&Hokstad&if&!authok&&server&s1&192.168.0.44:8084&
如果我想玩点花样,可以部署像AirBnB的Synapse这样的产品,但它拥有的选项数量之多超出了我对开发使用的要求。
就我的家用环境而言,这满足了我的大多数基础设施要求。我仍在不断推出了一系列基础设施容器,其目的是让实际应用程序部署起来轻而易举,就像我将一个完整的私有云系统向Docker迁移那样。
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条专题热点热点热点
24H热文一周话题本月最赞
讲师:273人学习过
讲师:1514人学习过
讲师:1478人学习过
精选博文论坛热帖下载排行
本书使用通俗易懂的语言,通过大量的实例,从实际应用的角度出发,全面系统地介绍了网络服务操作系统平台、电子邮件系统、Web站点和FTP站点...
订阅51CTO邮刊使用Docker进行Java开发 - 推酷
使用Docker进行Java开发
本文来自DockerOne,一篇入门级的学习教程,推荐Java开发者阅读,作者通过一个简单的例子演示了如何在Docker中进行Java开发。
这周,我和Anna、Stephan、Timo在慕尼黑的W-Jax开了一个关于企业技术(特别针对Java)的会议。没想到居然有这么多的人对Docker感兴趣,
但问题是怎么在Docker上进行Java开发呢? 我个人比较喜欢短小的示例,它可以通过包含几个小文件的框架帮助你了解某个技术
不幸的是,这在Java的世界很难实现,因为大多数的示例都需要某个 IDE以及适当的对Web框架有所了解。在这篇文章中,我将尝试使用短小的示例,以帮助你快速学习如何在Docker中进行Java开发。
现在有非常多的Java Web框架,但我这里并不打算使用它们。我只想要的是一个小的框架所以我选择了Spark,它是一个基于Java 8的极小的框架。Spark使用Maven作为构建工具。
源代码和配置文件
在这个例子中你要增加三个文件:
Maven的配置文件: pom.xml
一个Java类:Hello.java
一个Dockerfile
如果有读者等不及了,可以克隆这个repo:
/giantswarm/sparkexample
下面我们会详细解释这三个文件的结构,你可以此视频来快速了解。(读者可以查看原文中的视频,看完视频基本可以了解怎么做)
pom.xml 包含一些基本的Maven配置,比如配置Spark所依赖的Java 8。它会把所有的依赖封装成一个大的jar包。我不是 Maven专家,所以我没法把例子写得更简单、更流畅以便让他们更受欢迎。这是pom文件地址,你可以看看我的配 置:/luebke … m-xml
Hello.java
pom.xml文件定义mainClass为sparkexample.Hello,我们需要在src/main/java/sparkexample/目录下创建Hello.java文件。
Dockerfile
最 后我们来编写Dockerfile文件,这个Dockerfile使用到了Java镜像(java:oracle-java8),并从安装Maven开始 做起。下一步它会安装项目依赖。我们通过pom.xml来解析这些依赖,正如你所看到的,它允许Docker缓存这些依赖。下一步,我们要编译打包我们的 应用,并启动应用。如果我们重建应用时,pom.xml文件没有任何修改,之前的步骤都被缓存下来了,直接到最后一步启动应用。这可以加快应用的重新构建 速度。
创建和运行
一旦这三个文件已经完成,那创建Docker镜像就变得轻而易举了。
$ docker build -t giantswarm/sparkexample .
注意:首次启动时会花费一些时间,因为它要安装Maven并下载所有的依赖。之后再启动就需要几秒钟,因为所有的东西都已经缓存了。
镜像创建之后,用下面的命令创建容器:
docker run -d -p
giantswarm/sparkexample
用下面的命令访问:
curl localhost:4567 hello
现在可以去修改源码(返回你想返回的东西)并重新构建,这看起来是不是很棒?
=====================================================
对本微信的支持。Coding.net 是一个面向开发者的云端开发平台,目前提供代码托管、运行空间、质量控制、项目管理等功能。
阅读原文举报
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 docker mysql如何使用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信