如何在 DevOps 生命周期的开发阶段使用 docker?

Mr.*_*ars 9 development-environment hotdeploy livereload docker docker-compose

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

运维

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

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

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

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

问题如下。

  • 使用 Docker 进行阶段时,以下哪种场景最典型?

  • 场景1是否很好地提出?即仅dockerize 外部服务,如数据库、队列等,使用IDE 进行应用的开发和调试,不使用Docker。

我提出的疑问和场景是在我提出场景 2 的问题之后出现的。随着代码的每次更改,必须重新构建映像并再次启动容器是浪费大量时间。简而言之,一个问题是:如何避免这种情况?

在此先感谢您的时间。

注意这可能是一个受制于意见的问题,但很高兴知道开发人员通常如何处理这些问题。

Pie*_* B. 4

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

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

我在几个项目中见过这 3 个场景,每个场景都有各自的优点和缺点。不过,我认为使用 Docker Compose 允许动态代码重新加载的场景 3 在灵活性和一致性方面是最有利的:

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

场景 1 提出得好吗?即仅将外部服务(例如数据库、队列等)docker化,并使用IDE进行应用程序的开发和调试,而不使用Docker。

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

根据我自己的经验,当您在实际进行开发时不想与 Docker 打交道时,并且/或您使用的语言或技术不适合场景 3 中描述的动态重新加载时,这样做非常好。但最终它只是增加了环境之间的偏差以及开发和生产部署方法之间的更多复杂性。

必须重建镜像并再次启动容器是对时间的极大浪费。简而言之,一个问题是:如何避免这种情况?

除了您描述的场景之外,您还可以通过利用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 
    
    Run Code Online (Sandbox Code Playgroud) 但也可以docker-compose.override.ymlDocker Compose 默认使用的那样进行覆盖
  • 在某些情况下,我必须针对特定情况使用其他覆盖,例如docker-compose.ci.yml在我的 CI 上,但通常主 Docker Compose 文件足以描述我的 Prod 环境(如果不是这种情况,也docker-compose.prod.yml可以解决问题)