gpt4 book ai didi

docker - 拉取源代码并在 docker 镜像中使用它的最佳实践

转载 作者:行者123 更新时间:2023-12-02 18:25:35 25 4
gpt4 key购买 nike

这里完全是 Docker 新手。

我有一个使用两个存储库的 Web 应用程序。其中一个存储库基本上是一个“客户端”应用程序,而第二个是服务器。服务器提供来自客户端应用程序的静态文件。

我想把整个东西 docker 化。为此,现在我想知道最佳做法是什么:

  • 拉取客户端并将其构建在图像中
  • 做剩下的事

或者

  • 在外部 bash 脚本中拉取客户端代码
  • 以某种方式将构建文件复制到图像
  • 做剩下的事

或者

  • 在外部 bash 脚本中拉取客户端代码
  • 永远不要将客户端代码放在图像中,以某种方式在外部使用它
  • 做剩下的事

第一种方法确实有效,但它看起来很浪费,因为图像现在非常大并且包含处理文件。

第二种方法感觉“更好”,但是当我从 bash 脚本运行 docker-compose up 时,我无法复制文件,因为脚本已经在运行:

#!/bin/bash

git clone ... ~/tmp/client
(cd ~/tmp/client && yarn && yarn build && mv build ~/tmp/build)
docker-compose up
rm -rf ~/tmp/client

至于第三种方法,我什至不知道该怎么做。

任何建议或引用都会非常有帮助。

最佳答案

好问题!尽管有多种方法可以解决这个问题,但其中一些方法存在很多差异和缺点。 过去模式基本上是在外部(在主机上)构建内容,然后如果您想避免在生产镜像中包含所有 SDK 和源代码,则将相关内容复制到镜像中。

幸运的是,今天有更好的方法来解决这个问题:multistage docker builds .

多阶段 Dockerfile 类似于常规 Dockerfile,但它包含多个阶段(也称为多个 FROM 语句)。每个阶段都是镜像构建的全新开始。并非所有图像最终都会出现在您的容器注册表中,因为其中一些图像仅用于触发中间构建步骤。

伪代码

FROM node:version AS frontend-build
WORKDIR /src
COPY src/frontend . # or better package.json/package-lock.json first, then install, then the rest
RUN npm ci # or yarn build

FROM jdk-plus-buildtool:version AS backend-build
WORKDIR /app
COPY src/backend .
RUN mvn package # or similar

FROM trimmed-down-runtime:version
WORKDIR /app
COPY --from=backend-build target/myapp/ .
COPY --from=frontend-build dist/ ./static-files-folder
CMD your-run-command # or entrypoint

使用这种方法有几个优点:

  • 您的最终图像将仅包含运行您的应用程序所需的最少依赖项(例如 JRE、java 应用程序、静态 javascript 文件)
  • 没有任何东西是在限制环境对构建的影响的容器之外构建的。所需的每个工具都必须在构建容器中可用,这使得构建非常可靠且可重现
  • 构建可以很容易地在开发人员机器上运行,产生相同的结果,即使开发人员可能在他们的机器上本地有不同版本的 npm/java
  • 没有构建工具、sdk、源文件或中间工件最终出现在您的最终图像中
  • 甚至后端部分本身也可以变得更小,因为在将 SDK 移至生产容器时您不再运送 SDK(例如,用于 Java 应用程序的 JDK)
  • 您可以更多地利用 docker 构建缓存,因为如果没有任何更改,可以跳过整个部分(例如,如果仅更改 javascript 文件,则重用 java 构建)
  • 您可以更精细地控制每个构建步骤中使用的依赖项,并且构建本身具有较少的相互依赖性,因为不同技术的步骤在不同的容器中运行。

如果您正在谈论一个静态 javascript 应用程序和一个 HTTP API 后端服务器,您还可以使用两个单独的图像(前端和后端),然后相应地设置网络和代理,以便您只向外界公开前端容器并且所有请求都通过前端路由到后端应用程序。

还有一条评论:您正在谈论客户端和服务器的不同存储库。通常 CI 环境关心在真正的构建开始之前检查代码的所需版本。如果这个服务器基本上只从这个客户端使用,我会使用捆绑方法并将客户端源移动到主服务器存储库的子文件夹中。这使得使用单个错误修复分支为整个系统修复错误变得更加容易。如果您真的不能在存储库之间移动源代码,我会采用一些 git 子模块/子树方法来避免在构建期间自行处理提交引用。

关于docker - 拉取源代码并在 docker 镜像中使用它的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64113854/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com