Skip to content

docker publish Gitlab CI/CD jobs Template


This GitLab CI template is designed to publish Docker images to Docker Hub. It contains a job called "Publish Docker Image to Docker Hub" that handles the image publishing process.

Stage

  • publish

Variables

The following variables are used in the job:

  • DOCKER_IMAGE_BUILD_NAME: The name of the Docker image to build. By default, it uses the GitLab CI project name.

  • DOCKER_IMAGE_BUILD_REGISTRY: The registry for the Docker image build. By default, it uses the GitLab CI registry image.

  • DOCKER_IMAGE_BUILD_TAG: The tag for the Docker image build. By default, it uses the GitLab CI commit SHA.

  • DOCKER_IMAGE_BUILD_TARGET_PLATFORMS: A comma-separated list of available platforms for the Docker image build. Supported platforms include: 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.

  • CI_REGISTRY_USER: The username for logging in to the GitLab CI registry.

  • CI_REGISTRY_PASSWORD: The password for logging in to the GitLab CI registry.

  • NFC_DOCKERHUB_USERNAME: The username for logging in to Docker Hub.

  • NFC_DOCKERHUB_TOKEN: The access token or password for logging in to Docker Hub.

  • DOCKER_IMAGE_PUBLISH_REGISTRY: The registry for publishing the Docker image to Docker Hub.

  • DOCKER_IMAGE_PUBLISH_NAME: The name of the Docker image for publishing to Docker Hub.

  • DOCKER_IMAGE_PUBLISH_URL: The URL to access the published Docker image on Docker Hub.

Services

  • docker:23-dind: Runs Docker in Docker (DinD) service with version 23.

Script

The job executes the following steps in the script section:

  1. Logs in to the GitLab CI registry using the provided credentials (CI_REGISTRY_USER and CI_REGISTRY_PASSWORD).

  2. If the DOCKER_IMAGE_BUILD_TARGET_PLATFORMS variable is specified, it iterates over the platforms and inspects the Docker image using docker buildx imagetools inspect.

  3. If the DOCKER_IMAGE_BUILD_TARGET_PLATFORMS variable is not specified, it pulls the Docker image from the specified registry.

  4. Logs in to Docker Hub using the provided credentials (NFC_DOCKERHUB_USERNAME and NFC_DOCKERHUB_TOKEN).

  5. Lists the Docker images using docker image ls.

  6. Determines the appropriate tag for the Docker image based on the pipeline source and commit tag.

  7. If the DOCKER_IMAGE_BUILD_TARGET_PLATFORMS variable is specified, it creates multi-arch images using docker buildx imagetools create and tags them with the appropriate tag.

  8. If the DOCKER_IMAGE_BUILD_TARGET_PLATFORMS variable is not specified, it tags the Docker image with the appropriate tag based on the pipeline source and commit tag.

  9. Pushes the Docker image to Docker Hub.

  10. Logs out of Docker Hub.

Environment

The job sets the following environment variables:

  • Name: DockerHub

  • URL: The URL to access the published Docker image on Docker Hub.

Rules

The job is controlled by the following rules:

  • Runs when the pipeline is triggered by a Git tag and there is no associated branch.

  • Runs when the pipeline is triggered by a push to the master branch and there is a Dockerfile present.

  • Runs when the pipeline is triggered by a push to the development branch, there are changes in the Dockerfile or the includes/ directory compared to the master branch, and it allows failure.

  • Never runs explicitly.

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-06-10

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