Skip to content

docker build Gitlab CI/CD jobs Template


This documentation provides an overview and explanation of the GitLab CI/CD YAML template. The template defines a job named .build_docker_container that builds a Docker container using the specified configuration.

Stage: build

This job builds a Docker container using the nofusscomputing/docker-buildx-qemu:dev image and the docker:23-dind service.

Variables

  • DOCKER_IMAGE_BUILD_NAME: The name of the Docker image to be built ($CI_PROJECT_NAME).

  • DOCKER_IMAGE_BUILD_REGISTRY: The registry where the Docker image will be pushed ($CI_REGISTRY_IMAGE).

  • DOCKER_IMAGE_BUILD_TAG: The tag to be applied to the Docker image ($CI_COMMIT_SHA).

Rules

  • Rule 1: The job runs if the pipeline is triggered by a git tag and a dockerfile or dockerfile.j2 file exists.

  • Rule 2: The job runs if the pipeline is triggered by a push to the development branch and a dockerfile or dockerfile.j2 file exists. It also checks for changes in the dockerfile, dockerfile.j2, or includes/ directory compared to the master branch.

  • Rule 3: The job runs if the pipeline is triggered by a push to a branch other than master or development and a dockerfile or dockerfile.j2 file exists. It also checks for changes in the dockerfile, dockerfile.j2, or includes/ directory compared to the development branch.

  • Rule 4: The job never runs.

Script

The script performs the following steps:

  1. Updates the binary formats and enables execution of other binary formats in the kernel.

  2. Creates a Docker buildx builder and sets it as the active builder.

  3. Builds a multi-arch Docker image if the DOCKER_IMAGE_BUILD_TARGET_PLATFORMS variable is specified. It applies labels to the image and pushes it to the specified registry. It also inspects the image and performs cleanup by removing additional unknown images from the container registry.

  4. Builds a Docker image if the DOCKER_IMAGE_BUILD_TARGET_PLATFORMS variable is not specified. It applies labels to the image and pushes it to the specified registry.

gitlab-ci.yml definition

.gitlab-ci.yml
---

variables:
  # Available platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
  # DOCKER_IMAGE_BUILD_TARGET_PLATFORMS: "linux/amd64,linux/arm64,linux/arm/v7"
  DOCKER_IMAGE_BUILD_NAME: $CI_PROJECT_NAME
  DOCKER_IMAGE_BUILD_REGISTRY: $CI_REGISTRY_IMAGE
  DOCKER_IMAGE_BUILD_TAG: $CI_COMMIT_SHA

  # DOCKER_IMAGE_PUBLISH_NAME: $CI_PROJECT_NAME
  # DOCKER_IMAGE_PUBLISH_REGISTRY: docker.io/nofusscomputing
  # DOCKER_IMAGE_PUBLISH_URL: https://hub.docker.com/r/nofusscomputing/$DOCKER_IMAGE_PUBLISH_NAME
  # JOB_STOP_CONVENTIONAL_COMMITS: 'any_value'
  # JOB_STOP_GIT_PUSH_MIRROR: 'any_value'
  # GIT_SYNC_URL: "https://$GITHUB_USERNAME_ROBOT:$GITHUB_TOKEN_ROBOT@github.com/NoFussComputing/config.git" # Must be defined for job to run
  # JOB_STOP_GITLAB_RELEASE: 'any value'


.build_docker_container:
  stage: build
  image: 
    name: nofusscomputing/docker-buildx-qemu:dev
    pull_policy: always
  services:
    - name: docker:23-dind
      entrypoint: ["env", "-u", "DOCKER_HOST"]
      command: ["dockerd-entrypoint.sh"]
  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    DOCKER_DOCKERFILE: dockerfile
    # See https://github.com/docker-library/docker/pull/166
    DOCKER_TLS_CERTDIR: ""
  before_script:
    - git submodule foreach git submodule update --init
    - if [ "0$JOB_ROOT_DIR" == "0" ]; then ROOT_DIR=gitlab-ci; else ROOT_DIR=$JOB_ROOT_DIR ; fi
    - echo "[DEBUG] ROOT_DIR[$ROOT_DIR]"
    - docker info
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    #- pip3 install -r gitlab-ci/gitlab_release/requirements.txt
    - pip3 install setuptools wheel
    - pip install -r $ROOT_DIR/conventional_commits/requirements.txt
    - pip3 install gitlab-ci/gitlab_release/python-module/cz_nfc/.
      # see: https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/1861 
      # on why this `docker run` is required. without it multiarch support doesnt work.
    - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
    - update-binfmts --display
    - update-binfmts --enable # Important: Ensures execution of other binary formats is enabled in the kernel
    - docker buildx create --driver=docker-container --driver-opt image=moby/buildkit:v0.11.6 --use
    - docker buildx inspect --bootstrap


  #       --label org.opencontainers.image.url="$CI_PROJECT_URL/-/releases/$(cz -n cz_nfc version --project)" \
  #       --label org.opencontainers.image.version="$(cz -n cz_nfc version --project)" \
  script: 
    - update-binfmts --display
    - |

      if [ "0$DOCKER_IMAGE_BUILD_TARGET_PLATFORMS" != "0" ]; then

        echo "[DEBUG] building multiarch/specified arch image";

        docker buildx build --platform=$DOCKER_IMAGE_BUILD_TARGET_PLATFORMS . \
          --label org.opencontainers.image.created="$(date '+%Y-%m-%d %H:%M:%S%:z')" \
          --label org.opencontainers.image.documentation="$CI_PROJECT_URL" \
          --label org.opencontainers.image.source="$CI_PROJECT_URL" \
          --label org.opencontainers.image.revision="$CI_COMMIT_SHA" \
        --push \
        --build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN --build-arg CI_PROJECT_ID=$CI_PROJECT_ID --build-arg CI_API_V4_URL=$CI_API_V4_URL \
        --file $DOCKER_DOCKERFILE \
        --tag $DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG;

        docker buildx imagetools inspect $DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG;

        # during docker multi platform build there are >=3 additional unknown images added to gitlab container registry. cleanup

        DOCKER_MULTI_ARCH_IMAGES=$(docker buildx imagetools inspect "$DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG" --format "{{ range .Manifest.Manifests }}{{ if ne (print .Platform) \"&{unknown unknown  [] }\" }}$DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG@{{ println .Digest }}{{end}} {{end}}");

        docker buildx imagetools create $DOCKER_MULTI_ARCH_IMAGES --tag $DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG;

        docker buildx imagetools inspect $DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG;

      else

        echo "[DEBUG] building image";

        docker build . \
          --label org.opencontainers.image.created="$(date '+%Y-%m-%d %H:%M:%S%:z')" \
          --label org.opencontainers.image.documentation="$CI_PROJECT_URL" \
          --label org.opencontainers.image.source="$CI_PROJECT_URL" \
          --label org.opencontainers.image.url="$CI_PROJECT_URL/-/releases/$(cz -n cz_nfc version --project)" \
          --label org.opencontainers.image.version="$(cz -n cz_nfc version --project)" \
          --label org.opencontainers.image.revision="$CI_COMMIT_SHA" \
        --build-arg CI_JOB_TOKEN=$CI_JOB_TOKEN --build-arg CI_PROJECT_ID=$CI_PROJECT_ID --build-arg CI_API_V4_URL=$CI_API_V4_URL \
        --file $DOCKER_DOCKERFILE \
        --tag $DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG;

      docker push $DOCKER_IMAGE_BUILD_REGISTRY/$DOCKER_IMAGE_BUILD_NAME:$DOCKER_IMAGE_BUILD_TAG;

      fi
  rules:

    - if: # condition_git_tag
        $CI_COMMIT_TAG != null &&
        $CI_COMMIT_BRANCH == null
      exists:
        - '{dockerfile,dockerfile.j2}'
      when: on_success

    - if: # condition_dev_branch_push
        $CI_COMMIT_BRANCH == "development" && 
        $CI_PIPELINE_SOURCE == "push"
      exists:
        - '{dockerfile,dockerfile.j2}'
      changes:
        paths:
          - '{dockerfile,dockerfile.j2,includes/**/*}'
        compare_to: 'master'
      when: always

    - if: # condition_not_master_or_dev_push
        $CI_COMMIT_BRANCH != "master" && 
        $CI_COMMIT_BRANCH != "development" && 
        $CI_PIPELINE_SOURCE == "push"
      exists:
        - '{dockerfile,dockerfile.j2}'
      changes:
        paths:
          - '{dockerfile,dockerfile.j2,includes/**/*}'
        compare_to: 'development'
      when: always

    - when: never

About:

This page forms part of our Project Gitlab-CI.

Page Metadata
Version: ToDo: place files short git commit here
Date Created: 2023-06-10
Date Edited: 2023-09-02

Contribution:

Would You like to contribute to our Gitlab-CI project? You can assist in the following ways:

 

ToDo: Add the page list of contributors