首页 > 解决方案 > 如何在 devops 生命周期的开发阶段使用 docker?

问题描述

我有几个关于在开发阶段使用 Docker 的问题。

开发运维

我将提出三种我认为 Docker 可以在开发环境中使用的不同场景。假设我们正在用 Java 和 Spring Boot 创建一个 REST API。为此,我需要一个 MySQL 数据库。

  1. 第一个场景是使用 MySQL 容器进行开发的 docker-compose 以及使用 MySQL 和 Java 应用程序 (jar) 在另一个容器中的生产 docker-compose。为了开发,我启动了 docker-compose-dev.yml 来仅启动数据库。应用程序使用 IDE 启动和调试,例如 IntelliJ Idea。对代码所做的任何更改,IDE 将通过应用更改来识别并重新启动应用程序。

  2. 第二种情况是,对于开发和生产环境,都有一个包含数据库和应用程序容器的 docker-compose。这样,每次我对代码进行更改时,我都必须重新构建映像,以便将更改加载到映像中并再次启动容器。这种场景可能是最典型的,用于使用 Docker 进行开发,但由于每次发生更改都需要重新构建映像,因此看起来非常慢。

  3. 第三种情况是前两种情况的混合。两个码头工人组成。开发 docker-compose 包含两个容器,但具有允许实时重新加载应用程序、映射卷和使用例如 Spring Dev Tools 的机制。这样,容器就会启动,如果文件发生任何变化,应用程序容器将检测到有变化并重新启动。对于生产,只需使用两个容器创建 docker-compose,但没有实时重新加载的功能。在我看来,这将是理想的情况,但我认为这非常依赖于所使用的技术,因为并非所有技术都允许实时重新加载。

问题如下。

在我提出方案 2 的问题之后,我提出的疑问和方案就出现了。每次更改代码时,都必须重新构建映像并重新启动容器,这非常浪费时间。简而言之,一个问题是:如何避免这种情况?

在此先感谢您的时间。

注意这可能是一个有待商榷的问题,但很高兴知道开发人员通常如何处理这些问题。

标签: dockerdocker-composedevelopment-environmentlivereloadhotdeploy

解决方案


免责声明:这是我对火星先生提出的问题的个人看法。尽管我尽我所能用实际来源来支持我的答案,但这主要是基于我自己的经验和一些常识

使用 Docker 进行开发时,哪些场景最典型?

我在几个项目中看到了所有 3 个场景,每个场景都有其优点和缺点。但是,我认为 Docker Compose 允许动态代码重新加载的场景 3 在灵活性和一致性方面是最有利的:

  • Dev 和 Prod Docker Compose 非常匹配,这意味着 Dev 环境尽可能接近 Prod 环境
  • 开发时不必不断地重建镜像,但在需要的时候很容易做到
  • 很多技术都支持这样的场景,比如你提到的 Spring Dev Tools,还有 Python Flask 等。
  • 您可以轻松利用Docker Compose 扩展又名配置共享机制(也可以使用场景 2)

场景 1 是否被很好地提出?即只对外部服务进行 dockerize,例如数据库、队列等,并使用 IDE 执行应用程序的开发和调试,而不使用 Docker。

场景 1 很常见,但 IDE 环境可能与 Docker 容器中的环境不同(并且很难为每个库、依赖项等从 IDE 环境到 Docker 环境保持版本匹配)。它还可能需要在 Dev 和 Production 之间经过一个中间步骤,以实际测试 Dev 工作后构建的 Docker 映像,然后再进入生产。

以我自己的经验,当您在实际进行开发时不想过多地处理 Docker 和/或您使用的语言或技术不适用于场景 3 中描述的动态重新加载时,这样做非常好。但最终它只是在您的环境之间增加了偏差,并在 Dev 和 Prod 部署方法之间增加了复杂性。

必须重建映像并重新启动容器是非常浪费时间的。简而言之,一个问题是:如何避免这种情况?

除了您描述的场景之外,您还可以通过利用Docker 构建缓存和设计 Dockerfile来体面(甚至大幅)减少映像构建时间。例如,Python 应用程序通常会将代码复制为构建的最后(或几乎最后)步骤,以避免缓存无效,而对于 Java 应用程序,可以拆分代码以避免每次编译整个应用程序代码更改 - 这取决于您的实际设置。


我个人使用的工作流程大致匹配场景 3,例如:

  • docker-compose.yml对应于我的生产环境的文件
  • adocker-compose.dev.yml它将覆盖我的主要 Docker Compose 文件的某些方面,例如从我的机器上安装代码,向命令添加特定于开发的标志等 - 它将运行如下
    docker-compose -f docker-compose.yml -f docker-compose.dev.yml 
    
    但也可以docker-compose.override.yml使用Docker Compose 默认使用的覆盖
  • 在某些情况下,我必须对特定情况使用其他覆盖,例如docker-compose.ci.yml在我的 CI 上,但通常主要的 Docker Compose 文件足以描述我的 Prod 环境(如果不是这种情况,那就docker-compose.prod.yml行了)

推荐阅读