如何在GitLab CI作业中使用docker构建缓存?



我的repo中有以下.gitlab-ci.yml文件:

# This file is a template, and might need editing before it works on your project.
docker-build-main:
# Official docker image, develop tag
image: docker:latest
stage: build
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker pull "$CI_REGISTRY_IMAGE:develop-depsonly" || true
- docker build --cache-from "$CI_REGISTRY_IMAGE:develop-depsonly" --target build -t "$CI_REGISTRY_IMAGE:develop-depsonly" .
- docker push "$CI_REGISTRY_IMAGE:develop-depsonly"
- docker build -t "$CI_REGISTRY_IMAGE:develop" .
- docker push "$CI_REGISTRY_IMAGE:develop"
rules:
- if: $CI_COMMIT_BRANCH != "main"
when: never
- if: $CI_COMMIT_TAG == null
when: on_success
docker-build-tag:
# Official docker image, tagged release (also updates latest)
image: docker:latest
stage: build
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker pull "$CI_REGISTRY_IMAGE:develop-depsonly" || true
- docker build --cache-from "$CI_REGISTRY_IMAGE:develop-depsonly" -t "$CI_REGISTRY_IMAGE:develop-depsonly"
- docker push "$CI_REGISTRY_IMAGE:develop-depsonly"
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" -t "$CI_REGISTRY_IMAGE" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
- docker push  "$CI_REGISTRY_IMAGE:latest"
rules:
- if: $CI_COMMIT_BRANCH != "main"
when: never
- if: $CI_COMMIT_TAG
when: on_success

它的工作方式应该是,它应该使用旧图像作为缓存来构建新图像。但我有两个问题:

  1. 缓存不起作用,即即使build目标中没有任何变化,它仍然从头开始重建。
  2. docker-build-tag配方从未运行。它应该在创建新标签时运行,但它根本没有运行。

DockerFile如下:

FROM rust:1 as build
RUN cargo install cargo-build-deps
RUN cargo new --bin simply-shorten
WORKDIR /pkg
COPY ./actix/Cargo.toml .
COPY ./actix/Cargo.lock .
RUN cargo build-deps --release
COPY ./actix/src ./src
COPY ./actix/resources ./resources
RUN cargo build --release
FROM frolvlad/alpine-glibc:latest
EXPOSE 2000
RUN apk add sqlite-libs
WORKDIR /opt
COPY --from=build /pkg/target/release/pkg /opt/pkg
COPY --from=build /pkg/resources /opt/resources
CMD ["./pkg"]

docker:dind和其他所有服务都是隔离运行的。这就是缓存效率不高的原因。对于你来说,构建目标中没有任何变化,对于在docker:dind服务中运行的Docker来说,它是一个干净的状态,它从来没有看到过构建上下文,所以一切都是新的,闪亮的和新鲜的,所以将是构建。

如果你总是在同一个实例上构建,并且使用shell执行器而不是提供docker命令,你可以在所有作业中共享docker构建缓存。这将防止所有限制您使用的隔离,并且您也可以预先验证注册表并准备好使用。

如果这不是一个选项,您可以尝试如果将服务移动到顶层(而不是将它放在每个作业上)已经有所不同。但只有当你能回答自己第二个关于第二份工作的不表现条件的问题时,这一点才会显现出来。我建议先删除它进行测试,然后逐步重建它,以找出它在哪里不符合您的期望。

最新更新