docker - 如何在 devops 生命周期的开发阶段使用 docker?
问题描述
我有几个关于在开发阶段使用 Docker 的问题。
我将提出三种我认为 Docker 可以在开发环境中使用的不同场景。假设我们正在用 Java 和 Spring Boot 创建一个 REST API。为此,我需要一个 MySQL 数据库。
第一个场景是使用 MySQL 容器进行开发的 docker-compose 以及使用 MySQL 和 Java 应用程序 (jar) 在另一个容器中的生产 docker-compose。为了开发,我启动了 docker-compose-dev.yml 来仅启动数据库。应用程序使用 IDE 启动和调试,例如 IntelliJ Idea。对代码所做的任何更改,IDE 将通过应用更改来识别并重新启动应用程序。
第二种情况是,对于开发和生产环境,都有一个包含数据库和应用程序容器的 docker-compose。这样,每次我对代码进行更改时,我都必须重新构建映像,以便将更改加载到映像中并再次启动容器。这种场景可能是最典型的,用于使用 Docker 进行开发,但由于每次发生更改都需要重新构建映像,因此看起来非常慢。
第三种情况是前两种情况的混合。两个码头工人组成。开发 docker-compose 包含两个容器,但具有允许实时重新加载应用程序、映射卷和使用例如 Spring Dev Tools 的机制。这样,容器就会启动,如果文件发生任何变化,应用程序容器将检测到有变化并重新启动。对于生产,只需使用两个容器创建 docker-compose,但没有实时重新加载的功能。在我看来,这将是理想的情况,但我认为这非常依赖于所使用的技术,因为并非所有技术都允许实时重新加载。
问题如下。
在使用 Docker 进行阶段时,这些场景中哪一个是最典型的?
场景 1 是否被很好地提出?即只对外部服务进行 dockerize,例如数据库、队列等,并使用 IDE 执行应用程序的开发和调试,而不使用 Docker。
在我提出方案 2 的问题之后,我提出的疑问和方案就出现了。每次更改代码时,都必须重新构建映像并重新启动容器,这非常浪费时间。简而言之,一个问题是:如何避免这种情况?
在此先感谢您的时间。
注意:这可能是一个有待商榷的问题,但很高兴知道开发人员通常如何处理这些问题。
解决方案
免责声明:这是我对火星先生提出的问题的个人看法。尽管我尽我所能用实际来源来支持我的答案,但这主要是基于我自己的经验和一些常识
使用 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
对应于我的生产环境的文件- a
docker-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
行了)
推荐阅读
- r - ggplot在使用`facet_wrap`时添加正态分布
- javascript - Nodemon无法从打字稿构建中找到文件
- google-kubernetes-engine - 有没有办法通过代理将 Cloud Build 连接到 GKE 私有集群?
- reactjs - docker React、django(gunicorn)、带有 https 的 nginx 反向代理在访问后端 API 时给出错误请求 400
- python - 如何覆盖按钮相对于整个窗口的鼠标坐标?
- amazon-web-services - 从 govcloud ec2 实例访问商业 s3 存储桶
- php - 在 PHP 文件中更新 SVG 中的文本
- python - 在进行 PCA 分析时,sklearn 的 skpca.fit 会出现什么错误
- java - postgres的休眠序列问题
- date - Google 表格中的日期格式无法按照说明工作