Gitlab CI 拆分 Docker 构建成多个阶段

Gitlab CI Split Docker Build Into Multiple Stages

我有一个 react/django 应用 docker。 GitLab CI 过程有 2 个阶段。 Build_Node 和 Build_Image。构建节点只是构建 React 应用程序并将其存储为工件。构建映像运行 docker build 以构建实际的 docker 映像,并依赖于节点步骤,因为它将构建的文件复制到映像中。

但是,如果软件包依赖项发生变化(apt 或 pip),映像的构建过程会花费很长时间,因为它必须重新安装所有内容。

有没有办法将 docker 构建作业分成多个部分,这样我就可以说在 docker 文件中安装 apt 和 pip 包,而 build_node 仍然存在运行,然后在该阶段完成后完成 docker 构建?

gitlab-ci.yml:

stages:
  - Build Node Frontend
  - Build Docker Image

services:
  - docker:18.03-dind

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_HOST: tcp://localhost:2375
  DOCKER_TLS_CERTDIR: ""

build_node:
  stage: Build Node Frontend
  only:
    - staging
    - production
  image: node:14.8.0
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
  artifacts:
    paths:
      - http
  cache:
    key: "node_modules"
    paths:
      - frontend/node_modules
  script:
    - cd frontend
    - yarn install --network-timeout 100000
    - CI=false yarn build
    - mv build ../http



build_image:
  stage: Build Docker Image
  only:
    - staging
    - production
  image: docker

  script:
    #- sleep 10000
    - tar -cvf app.tar api/ discordbot/ helpers/ http/
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    #- docker pull $CI_REGISTRY_IMAGE:latest
    #- docker build --network=host --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA --tag $CI_REGISTRY_IMAGE:latest .
    - docker build --network=host --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA --tag $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - docker push $CI_REGISTRY_IMAGE:latest

Docker 文件:

FROM python:3.7-slim

# Add user
ARG APP_USER=abc
RUN groupadd -r ${APP_USER} && useradd --no-log-init -r -g ${APP_USER} ${APP_USER}

WORKDIR /app
ENV PYTHONUNBUFFERED=1
EXPOSE 80
EXPOSE 8080

ADD requirements.txt /app/

RUN set -ex \
    && BUILD_DEPS=" \
        gcc \
    " \
    && RUN_DEPS=" \
        ffmpeg \
        postgresql-client \
        nginx \
        dumb-init \
    " \
    && apt-get update && apt-get install -y $BUILD_DEPS \
    && pip install --no-cache-dir --default-timeout=100000 -r /app/requirements.txt \
    && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false  $BUILD_DEPS \
    && apt-get update && apt-get install -y --no-install-recommends $RUN_DEPS \
    && rm -rf /var/lib/apt/lists/*

# Set uWSGI settings
ENV UWSGI_WSGI_FILE=/app/api/api/wsgi.py UWSGI_HTTP=:8000 UWSGI_MASTER=1 UWSGI_HTTP_AUTO_CHUNKED=1 UWSGI_HTTP_KEEPALIVE=1 UWSGI_LAZY_APPS=1 UWSGI_WSGI_ENV_BEHAVIOR=holy PYTHONUNBUFFERED=1 UWSGI_WORKERS=2 UWSGI_THREADS=4
ENV UWSGI_STATIC_EXPIRES_URI="/static/.*\.[a-f0-9]{12,}\.(css|js|png|jpg|jpeg|gif|ico|woff|ttf|otf|svg|scss|map|txt) 315360000"
ENV PYTHONPATH=$PYTHONPATH:/app/api:/app
ENV DB_PORT=5432 DB_NAME=shittywizard DB_USER=shittywizard DB_HOST=localhost

ADD nginx.conf /etc/nginx/nginx.conf

# Set entrypoint
ADD entrypoint.sh /
RUN chmod 755 /entrypoint.sh
ENTRYPOINT ["dumb-init", "--", "/entrypoint.sh"]

ADD app.tar /app/

RUN python /app/api/manage.py collectstatic --noinput

好的!查看 stages and on building docker images with gitlab-ci.

上的 gitlab 文档

如果您在一个阶段中定义了多个管道步骤,它们将运行并行。例如,以下管道将并行构建节点和图像工件,然后使用这两个工件构建最终图像。

stages:
- build
- bundle

build-node:
  stage: build
  script:
  - # steps to build node and push to artifact registry

build-base-image:
  stage: build
  script:
  - # steps to build image and push to artifact registry

bundle-node-in-image:
  stage: bundle
  script:
  - # pull image artifact
  - # download node artifact
  - # build image on top of base image with node artifacts embedded

请注意,根据相对于构建时间的图像大小,所有推拉以及启动和停止操作可能不会节省您的时间,但这会满足您的要求。