Last active
May 13, 2025 13:27
-
-
Save ahmetgeymen/f176f11ab0c81c2496cedac963e8e8ae to your computer and use it in GitHub Desktop.
Bitbucket Pipelines: Build Docker Image + GCR Image Push + GKE Deploy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
image: openjdk:11-jdk-slim | |
definitions: | |
caches: | |
gradlewrapper: ~/.gradle/wrapper | |
gke-kubectl-pipe: &pipe atlassian/google-gke-kubectl-run:1.3.1 | |
gke-kubectl-pipe-variables: &pipe-variables | |
KEY_FILE: $GKE_API_KEYFILE | |
PROJECT: $GCP_PROJECT_ID | |
COMPUTE_ZONE: $GKE_COMPUTE_ZONE | |
CLUSTER_NAME: $GKE_CLUSTER_NAME | |
KUBECTL_COMMAND: "set image deployment/$K8S_DEPLOYMENT_NAME $K8S_CONTAINER_NAME=$IMAGE_NAME --namespace=$K8S_NAMESPACE" | |
steps: | |
- step: &lint | |
name: Lint | |
caches: | |
- gradle | |
- gradlewrapper | |
script: | |
- ./gradlew lintKotlin | |
- step: &test | |
name: Test | |
caches: | |
- gradle | |
- gradlewrapper | |
script: | |
- ./gradlew test | |
- step: &assemble | |
name: Assemble | |
caches: | |
- gradle | |
- gradlewrapper | |
script: | |
- ./gradlew assemble | |
artifacts: | |
- build/libs/*.jar | |
- step: &build-image | |
name: Build Docker image | |
services: | |
- docker | |
caches: | |
- docker | |
script: | |
- export IMAGE_NAME=$GCP_IMAGE_NAME | |
- docker build -t $IMAGE_NAME --build-arg JAR_FILE=build/libs/app.jar . | |
- docker save --output docker.tar $IMAGE_NAME | |
artifacts: | |
- docker.tar | |
- step: &push-image-to-gcr | |
name: Push image | |
image: google/cloud-sdk:alpine | |
services: | |
- docker | |
caches: | |
- docker | |
script: | |
# backup docker image | |
- docker load --input docker.tar | |
# Authenticating with the service account key file | |
- echo $GCP_API_KEYFILE | base64 -d > ./gcloud-api-key.json | |
- gcloud info --run-diagnostics | |
- gcloud auth activate-service-account --key-file gcloud-api-key.json | |
- gcloud config set project $GCP_PROJECT_ID | |
# Login to google docker hub | |
- cat ./gcloud-api-key.json | docker login -u _json_key --password-stdin https://$GCP_REGISTRY_HOSTNAME | |
# Prepare image name and shorten commit id | |
- export IMAGE_NAME=$GCP_REGISTRY_HOSTNAME/$GCP_PROJECT_ID/$GCP_IMAGE_NAME | |
- export BITBUCKET_COMMIT_SHORT="${BITBUCKET_COMMIT::7}" | |
# If any image does not exist with commit id, then | |
- if [ "$(gcloud container images list-tags ${IMAGE_NAME} | grep ${BITBUCKET_COMMIT_SHORT})" == '' ]; then | |
# Tag docker image with commit id and push | |
- docker tag $GCP_IMAGE_NAME $IMAGE_NAME:$BITBUCKET_COMMIT_SHORT | |
- docker push $IMAGE_NAME:$BITBUCKET_COMMIT_SHORT | |
# Tag docker image with :latest tag and push | |
- docker tag $GCP_IMAGE_NAME ${IMAGE_NAME} | |
- docker push ${IMAGE_NAME} | |
# Tag docker image with commit tag and push (if pipeline triggered with tag) | |
- if [ "${BITBUCKET_TAG}" != '' ]; then | |
- docker tag $GCP_IMAGE_NAME $IMAGE_NAME:$BITBUCKET_TAG | |
- docker push $IMAGE_NAME:$BITBUCKET_TAG | |
- fi | |
# Else image exists with commit id | |
- else | |
# Add commit tag into existing image with commit id (if pipeline triggered with tag) | |
- if [ "${BITBUCKET_TAG}" != '' ]; then | |
- gcloud container images add-tag $IMAGE_NAME:$BITBUCKET_COMMIT_SHORT $IMAGE_NAME:$BITBUCKET_TAG --quiet | |
- fi | |
# End if | |
- fi | |
- step: &deploy-to-gke-staging | |
name: Deploy to Staging | |
deployment: staging | |
script: | |
- export BITBUCKET_COMMIT_SHORT="${BITBUCKET_COMMIT::7}" | |
- export IMAGE_NAME=$GCP_REGISTRY_HOSTNAME/$GCP_PROJECT_ID/$GCP_IMAGE_NAME:$BITBUCKET_COMMIT_SHORT | |
- pipe: *pipe | |
variables: *pipe-variables | |
- step: &deploy-to-gke-production | |
name: Deploy to Production | |
deployment: production | |
# Added for manual promotion | |
trigger: manual | |
script: | |
- export IMAGE_NAME=$GCP_REGISTRY_HOSTNAME/$GCP_PROJECT_ID/$GCP_IMAGE_NAME:$BITBUCKET_TAG | |
- pipe: *pipe | |
variables: *pipe-variables | |
pipelines: | |
pull-requests: | |
'**': | |
- parallel: | |
- step: *lint | |
- step: *test | |
tags: | |
'*': | |
- parallel: | |
- step: *lint | |
- step: *test | |
- step: *assemble | |
- step: *build-image | |
- step: *push-image-to-gcr | |
- step: *deploy-to-gke-staging | |
- step: *deploy-to-gke-production | |
branches: | |
master: | |
- parallel: | |
- step: *lint | |
- step: *test | |
- step: *assemble | |
- step: *build-image | |
- step: *push-image-to-gcr | |
- step: *deploy-to-gke-staging |
I think it would be better if you share yours as a gist and post its link as a comment. Thank you for sharing your experience. 👏
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you so much @ahmetgeymen for sharing this I'm able to create complete deployment pipeline below is my pipeline if someone maybe this could help other in the use-case I have
`image: atlassian/pipelines-awscli:latest
definitions:
###############################################
# Test Environment
###############################################
# App Test
gke-kubectl-pipe-app-test: &pipe-app-test atlassian/google-gke-kubectl-run:1.3.1
gke-kubectl-pipe-variables-app-test: &pipe-variables-app-test
KEY_FILE: $GCP_SERVICE_ACCOUNT_KEY
PROJECT: $PROJECT_NAME
COMPUTE_ZONE: $GCP_ZONE
CLUSTER_NAME: $GCP_CLUSTER_NAME
# If there is a change in k8s manifest enable below line and disable after that line
# KUBECTL_COMMAND: "apply -f k8s/test/deployment.yml --namespace=default"
KUBECTL_COMMAND: "rollout restart deployment/evstar-ev-api-test --namespace=default"
pipelines:
branches:
`