【问题标题】:Monolith docker application with webpack带有 webpack 的单体 docker 应用程序
【发布时间】:2019-09-11 06:23:22
【问题描述】:

我在 docker 容器和 GKE 上的 k8s 中运行我的单体应用程序。

该应用程序包含 python 和节点依赖项以及用于前端捆绑的 webpack。

我们已经实施了 CI/CD,大约需要 5-6 分钟来构建和部署新版本到 k8s 集群。

主要目标是尽可能减少构建时间。编写的 Dockerfile 是多阶段的。

Webpack 需要更多时间来生成捆绑包。要构建 docker 映像,我正在使用已经很高的 config worker。

为了减少时间,我尝试使用Kaniko builder

问题:

作为 python 代码的 docker 缓存层,它运行良好。但是当JSCSS 文件有任何变化时,我们必须生成bundle。

JS & CSS 文件发生任何变化时,如果生成新的捆绑包,则使用缓存层。

有没有办法通过将一些值传递给 docker 文件来分离构建新包或使用缓存。

这是我的 docker 文件:

FROM python:3.5 AS python-build
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt  &&\
    pip3 install Flask-JWT-Extended==3.20.0
ADD . /app

FROM node:10-alpine AS node-build
WORKDIR /app
COPY --from=python-build ./app/app/static/package.json app/static/
COPY --from=python-build ./app ./
WORKDIR /app/app/static
RUN npm cache verify && npm install && npm install -g --unsafe-perm node-sass && npm run sass  && npm run build


FROM python:3.5-slim
COPY --from=python-build /root/.cache /root/.cache
WORKDIR /app
COPY --from=node-build ./app ./
RUN apt-get update -yq \
    && apt-get install curl -yq \
    && pip install -r requirements.txt
EXPOSE 9595
CMD python3 run.py

【问题讨论】:

  • 您的 Dockerfile 中有三个构建版本。因此,使用前两个 buld 创建一个新图像并创建新的图像层并使用它来构建应用程序。
  • 我已经采用了这种方式。首先它是下载 python 依赖项,其次是生成前端包。第三,它混合了整个应用程序并运行。

标签: docker webpack kubernetes google-cloud-platform google-kubernetes-engine


【解决方案1】:

我建议为您的 docker 镜像创建单独的构建管道,您知道对 npm 和 pip 的要求并不那么频繁。 这将极大地提高速度,减少访问 npm 和 pip 注册表的时间。

使用私有 docker 注册表(official one 或类似 VMWare harborSonaType Nexus OSS)。

您将这些构建映像存储在注册表中,并在项目发生变化时使用它们。

类似这样的:

第一个 Docker 构建器 // python-builder:YOUR_TAG [gitrev、日期等)

docker build --no-cache -t python-builder:YOUR_TAG -f Dockerfile.python.build .

FROM python:3.5 
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt  &&\
    pip3 install Flask-JWT-Extended==3.20.0

第二个 Docker 构建器 // js-builder:YOUR_TAG [gitrev、日期等)

docker build --no-cache -t js-builder:YOUR_TAG -f Dockerfile.js.build .  

FROM node:10-alpine
WORKDIR /app
COPY app/static/package.json /app/app/static
WORKDIR /app/app/static
RUN npm cache verify && npm install && npm install -g --unsafe-perm node-sass 

您的应用程序多阶段构建

docker build --no-cache -t app_delivery:YOUR_TAG -f Dockerfile.app .  

FROM python-builder:YOUR_TAG as python-build
# Nothing, already "stoned" in another build process

FROM js-builder:YOUR_TAG AS node-build
ADD ##### YOUR JS/CSS files only here, required from npm! ###
RUN npm run sass && npm run build

FROM python:3.5-slim
COPY . /app # your original clean app
COPY --from=python-build #### only the files installed with the pip command
WORKDIR /app
COPY --from=node-build ##### Only the generated files from npm here! ###
RUN apt-get update -yq \
    && apt-get install curl -yq \
    && pip install -r requirements.txt
EXPOSE 9595
CMD python3 run.py

一个问题是:为什么在最终的docker镜像中安装curl并再次执行pip install -r requirements.txt命令? 每次apt-get update 时触发并安装而不清理 apt 缓存 /var/cache/apt 文件夹会产生更大的图像。

作为建议,使用带有选项 --no-cache 的 docker build 命令来避免缓存结果:

docker build --no-cache -t your_image:your_tag -f your_dockerfile .

备注

您将拥有 3 个单独的 Dockerfile,正如我在上面列出的。 在您更改 python-pipnode-npm 要求时构建 Docker 映像 1 和 2,否则为您的项目保留它们。 如果任何依赖要求发生变化,则更新所涉及的 docker 镜像,然后更新多阶段镜像以指向最新构建的镜像。

您应该始终只构建项目的源代码(CSS、JS、python)。这样,您还保证了可重现的构建。

要优化您的环境并跨多阶段构建器复制文件,请尝试使用virtualenv 进行python 构建。

【讨论】:

  • 您好,首先非常感谢您写下答案并很好地解释。非常感谢。
  • 当我从第 1 步到第 3 步复制 python 依赖项时,您的问题答案有时它不起作用,所以我这样做 pip install 以便再次缓存所有轮子并检查文件系统。跨度>
  • 尝试使用 virtualenv 并将整个 env 从构建器复制到最终图像。然后,您可以确保复制所有内容而不会再次触发对 pip 注册表的网络调用,从而再次花费时间
  • run pip 我正在做apt-get updte 而curl 只是为了ping 另一个用于调试备份和检查响应的服务。
  • 使用venvs 真是个好主意。当然,我也会按照您在回答中的建议尝试实施它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
  • 2021-01-21
  • 2016-09-24
  • 2018-01-11
  • 1970-01-01
相关资源
最近更新 更多