【编者按】Vidar Hokstad 在Docker使用方面非常有经验,尤其在没有数据丢失前提下,使用Docker创建可重复build上经验丰富,在本博客中,他总结了开发Docker容器的8种模式。 以下为译文: Docker现在成了我最喜欢的工具,在本文中,我将概述一些在我使用Docker过程中反复出现的模式。我不期待它们能给你带来多少惊喜,但我希望这些能对你有用,我非常愿意与你交流在使用Docker过程中碰到的模式。 我所有Docker实验的基础是保持volume状态不变,以便Docker容器在没有数据丢失的前提下任意重构。 下面所有的Dockerfiles例子都集中在:创建容器在其本身可以随时更换的地方,而无需考虑其它。 1. The Shared Base Container(s) Docker鼓励“继承”,这应用也很自然——这是高效使用Docker的一个基本方式,不仅由于它有助于减少建立新容器的时间,Docker优点多多,它会cache中间步骤,但也容易在不明确的情况下,失去分享机会。 很显然,在将我的各种容器迁移到Docker上时,首先要面对的是多个步骤。 对于多数想要随处部署的项目来说所,要创建多个容器,尤其是在这个项目需要长进程,或者需要特定包的情况,所以我要运行的容器也变得越来越多。 重要的是为了让mybase环境完全自由支配,我正考虑试图在Docker上运行“所有一切”(包括我依赖几个桌面app)。 所以我很快开始提取我的基本设置到base容器。这是我当前的“devbase”Dockerfile: 这里没有什么需要特别说明的地方——它安装一些需要随时可用的特定工具。这些可能会对大多数人来说是不同的。值得注意的是如果/当你重建一个容器的时候,你需要指定一个特定的标签来避免意外。 使用默认端口8080,因为这是我发布web app的端口,这也是我用这些容器的目的。 它为我添加了一个用户,并且不会创建一个/ home目录。我从宿主机绑定挂载了一个共享文件夹/ home,这就引出了下一个模式。 2. The Shared Volume Dev Container 我所有的dev容器与宿主机分享至少一个volume: / home,这是为了便于开发。对于许多app,在开发模式中,使用基于file-system-change的code-reloader运行,这样一来容器内封装了OS / distro-level的依赖,并在初始环境中帮助验证app-as-bundled工作,而不需要让我每次在代码改变时重启/重建VM。 至于其他,我只需要重启(而不是重建)容器来应对代码的更改。 对于test/staging和production容器,大多数情况下不通过volume共享代码,转而使用“ADD”来增添代码到Docker容器中。 这是我的“homepage”的dev容器的Dockerfile,例如,包含我的个人wiki,存在于“devbase”容器中的 /home下,以下展示了如何使用共享的base容器和/home卷: 以下是dev-version的博客: 因为他们从一个共享的库中取代码,并且基于一个共享的base容器,这些容器通常当我添加/修改/删除依赖项时会极其迅速重建。 即便如此也有一些地方是我非常愿意改善,尽管上面的base是轻量级的,他们大多数在这些容器仍未使用。由于Docker使用copy-on-write覆盖,这不会导致一个巨大的开销,但它仍然意味着我没有做到最小的资源消耗,或者说最小化attack或error的几率。 3. The Dev Tools Container 这可能对我们这些喜欢依靠ssh写代码的人很有吸引力,但是对IDE人群则小一点。对我来说,关于以上设置更大的 一个好处,是它让我在开发应用程序中,能够将编辑和测试执行代码的工作分离开来。 过去dev-systems对我来说一件烦人的事,是dev和production依赖项以及开发工具依赖项容易混淆,很容易产生非法的依赖项。 虽然有很多方法解决这个,比如通过定期的测试部署,但我更偏爱下面的解决方案,因为可以在第一时间防止问题的发生: 我有一个单独的容器包含Emacs的installation以及其他各种我喜欢的工具,我仍然试图保持sparse,但关键是我的screen session可以运行在这个容器中,再加上我笔记本电脑上的“autossh”,这个连接几乎一直保持,在那里我可以编辑代码,并且和我的其他dev容器实时共享。如下: 结合共享“/ home“,已经足够让ssh的接入了,并且被证明能满足我的需要。 |