# Build and push a Docker image with CI/CD. # Docker-in-Docker documentation: https://docs.gitlab.com/ee/ci/docker/using_docker_build.html # # By default builds are tagged with their branch name and pushed to the # Gitlab Docker Registry. If DOCKER_TAG_LATEST is set to true, builds on # the $DOCKER_LATEST_BRANCH are also tagged and pushed as ":latest" # # Scheduled builds can be enabled on a Gitlab schedule by specifying # DOCKER_SCHEDULE = "true" in variables --- variables: # Docker registry where images will be pushed DOCKER_REGISTRY: "$CI_REGISTRY" DOCKER_USERNAME: "$CI_REGISTRY_USER" DOCKER_TOKEN: "$CI_REGISTRY_PASSWORD" # Whether or to push images after they're built DOCKER_PUSH: "true" # TODO: Conditionally include '--file' to docker build to reduce need # to always define FILEPATH when BUILDCONTEXT is set DOCKER_FILEPATH: "Dockerfile" DOCKER_BUILDCONTEXT: "." DOCKER_IMAGE: "$CI_REGISTRY_IMAGE" # If LATEST_TAG is set to true, builds on the $DOCKER_LATEST_BRANCH # will be tagged and pushed with ":latest" DOCKER_LATEST_TAG: "true" DOCKER_LATEST_BRANCH: "$CI_DEFAULT_BRANCH" .docker-build-and-push: &docker-build-and-push image: docker:latest stage: deploy interruptible: true services: - docker:dind before_script: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_TOKEN" $DOCKER_REGISTRY script: # Warm the cache by fetching the latest image. There's no guarantee # the image will already exist on the runner. - docker pull "$DOCKER_IMAGE:${CI_COMMIT_REF_SLUG}" || true - > docker build --pull --cache-from "$DOCKER_IMAGE:${CI_COMMIT_REF_SLUG}" --file "$DOCKER_FILEPATH" --tag "$DOCKER_IMAGE:${CI_COMMIT_REF_SLUG}" $DOCKER_BUILDCONTEXT - | if [[ "$CI_COMMIT_BRANCH" == "$DOCKER_LATEST_BRANCH" && "$DOCKER_LATEST_TAG" == "true" ]]; then docker tag "$DOCKER_IMAGE:${CI_COMMIT_REF_SLUG}" "$DOCKER_IMAGE" fi - | # Push docker images if DOCKER_PUSH is set if [[ "$DOCKER_PUSH" == "true" ]]; then docker push "$DOCKER_IMAGE:${CI_COMMIT_REF_SLUG}" # Push ':latest' if LATEST_TAG is true if [[ "$CI_COMMIT_BRANCH" == "$DOCKER_LATEST_BRANCH" && "$DOCKER_LATEST_TAG" == "true" ]]; then docker push "$DOCKER_IMAGE" fi fi rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' when: never # Gitlab does not have a way of specifying which jobs are scheduled, # so an extra variable is needed in order to signify docker build # should be picked up by the schedule run. - if: $CI_PIPELINE_SOURCE == "schedule" && $DOCKER_SCHEDULE != "true" when: never - if: '$CI_COMMIT_BRANCH == $DOCKER_LATEST_BRANCH' - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - if: $CI_COMMIT_TAG