Git 将代码库烘焙到生产图像中

Git 将代码库烘焙到生产图像中,git,docker,production-environment,Git,Docker,Production Environment,我目前正在使用git在不同的主机上部署我的应用程序。我的代码库正在装入正在运行的Docker图像中: docker compose.yml 服务: 应用程序: 图片:my.registry.net:5000/my/app 卷数: -.:/app # [...] 所以我的部署是这样的: $ git pull $ docker-compose build && docker-compose up -d $ docker-compose exec app some_dependenc

我目前正在使用git在不同的主机上部署我的应用程序。我的代码库正在装入正在运行的Docker图像中

docker compose.yml

服务:
应用程序:
图片:my.registry.net:5000/my/app
卷数:
-.:/app
# [...]
所以我的部署是这样的:

$ git pull
$ docker-compose build && docker-compose up -d
$ docker-compose exec app some_dependencies_installation_command
$ docker-compose exec app some_cache_clearing_command
对我来说,这似乎是错误的,原因很多,你可以想象得到。虽然如果出现问题,我仍然可以恢复到我以前的git发行标签

我希望通过将代码库烘焙到映像中来简化部署,因此我不再使用git进行部署,而是依赖于映像拉动。如果你不建议,请告诉我原因

我很想简单地将我的代码库添加到映像的末尾,并在主机中装载所需的内容:

Dockerfile

#[…]
加上/应用程序
docker compose.prod.yml

服务:
应用程序:
图片:my.registry.net:5000/my/app
卷数:
-./config.yml:/app/config.yml
-/日志:/app/日志
-/缓存:/app/cache
-/会话:/app/会话
# [...]
因此,一旦构建,我只需使用以下配置部署我的映像:

$ docker-compose pull && docker-compose up -d

这是个好办法吗?如何对图像进行版本设置,以便在出现问题时还原图像(因为
Dockerfile
实际上从未更改过)?另外,不是依赖docker文件的一层每次都会拉取整个代码库,而不仅仅是diff(比如git)?

docker compose是docker的一个编排工具,但还有其他工具,比如kubernetes或docker swarm。你应该自己检查一下,考虑一下在哪里可以使用这些工具

要对图像进行版本设置,可以标记它们(使用-t)。因此,您将能够推出特定的版本
my.registry.net:5000/my/app:1.1.0
,等等

构建可以在本地计算机上完成,也可以在CI/CD管道中自动完成

Docker不提取代码库,只提取包含文件的层。如果编译程序,只需添加二进制文件和一些资源。层被缓存,并且仅在需要时才被拉上


如果希望最小化注册表中的映像,可以在docker中使用多阶段构建。这将使用多个阶段来构建最后一个容器,它只为您的应用程序服务,因此需要更少的文件。例如,您可以在一个阶段使用javac编译二进制文件,在另一个阶段使用nodejs和webpack编译资产,并将生成的文件复制到最后一个容器中,该容器仅包含java运行时和静态生成的资产。官方文件如下:

你说得对,你的方法有很多问题,包括:

  • 应用程序的每个实例都必须等待构建完成后才能启动
  • 如果构建失败会发生什么?不包括手动测试,您只知道“部署时”的故障
  • 构建过程将在每次运行时生成相同的工件(前提是您没有更改源代码)。为什么要浪费时间重复这个过程
不必在容器中烘焙应用程序的源代码并在每次部署时重建应用程序,您可以只构建应用程序(如果您希望使构建环境也可移植,可以在另一个“构建”容器中构建,即仅用于构建的容器)并添加构建在另一个映像中生成的工件,该映像将部署在您的生产环境中(在测试和QA之后,因为您确实有多个环境,对吗?:)

Docker图像标记可以这样工作:在每个提交(可能在最新的图像标记下)和每个git标记(在相应的图像标记下)上构建一个图像。示例:对于主分支上的每个提交,您都“更新”
您的映像:最新版本
,当您标记1.0.0版本时,您会生成
您的映像:1.0.0

如果您有各种类型的CI服务,也可以自动执行此过程

请注意,在生产环境中使用最新标记可能会导致环境不稳定,因为您不知道要部署哪个版本。使用另一个更具体的标记


更新:正如其他人所指出的,将源代码放入容器中是一种可以应用于开发阶段的策略。但这不是你的情况,因为我假设你谈论的是(预)生产部门。

将源代码绑定到容器上,通常是为了在开发时有一个快速的反馈循环。这是通过避免在代码更改后重建图像来实现的。这项技术主要用于本地开发目的。对于生产环境,不应使用此技术

Docker图像设计为独立的。映像需要的所有依赖项都应打包在映像中。依赖绑定挂载来提供源代码或依赖项并不重要 推荐使用,因为生成的Docker映像不可移植。无论何时切换到新机器,都需要将源代码和依赖项转移到新机器

因此,建议将源代码添加到映像中。您还应该受益于标准的Docker工作流,在该工作流中,您构建图像并为其提供特定的标记(通常是版本),然后推送 将其保存到Docker存储库中。从那以后,你只需在你拥有的任何机器上拉取图像并启动它

至于版本控制:在构建映像时,使用源代码版本(或git标记或提交id)对其进行标记

docker构建-t:。
您还可以使用
docker pull:
提取特定版本。使用此技术,您始终可以恢复到图像的任何版本。

好的,我应该这样做
docker build -t <image-name>:<version> .