How to Build and Deploy App to Kubernetes Using Bitbucket Pipelines

Automating the deployment process from Bitbucket Pipelines to Kubernetes involves setting up a continuous integration/continuous deployment (CI/CD) pipeline. Below is a general guide on how you can achieve this using Bitbucket Pipelines and Kubernetes.

Bitbucket Pipelines is the quickest and easiest way to setup continuous delivery right from your repo if you are using bitbucket for source control. Pipelines are configured with YAML files and can be very simple or extremely complex depending on your needs.

I always prefer to split my jobs into steps:

  • If a step fails, you can re-run individual steps.
  • Each step is isolated from the others. Only your base repo and any “artifacts” you declare will be passed to the next step.

Steps

  1. Configure your Bitbucket repository

    • Make sure you have your project hosted on Bitbucket.
  2. Kubernetes Cluster: Set up your Kubernetes cluster

  3. Add your credentials and configuration settings in Bitbucket as variables. See: how to configure Pipelines variables.

Configure Kubernetes Credentials in Bitbucket

Go to repo settings, repo variables and set these up

  • DOCKERHUB_PASSWORD - docker hub password used for pushing the image
  • DOCKERHUB_USERNAME - docker hub username used for pushing the image
  • KUBECONFIG - authentication to kubernetes

To get the KUBECONFIG

  • Switch to context
1
k ctx dev-ello-platform-k3s
  • Get raw kubeconfig
1
kubectl config view --minify --raw
  • Use the base64 encoded value
1
kubectl config view --minify --raw | openssl base64

Bitbucket pipeline Pipeline

Here is a 3-step bitbucket-pipelines.yml file that takes a nestjs app, run tests, packages it as a Docker image and deploys it to a Kubernetes cluster:

Then pipeline here in file bitbucket-pipelines.yml base of repo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
image: alpine:3.21
options:
  docker: true
definitions:
  services:
    docker:
      memory: 2048
pipelines:
  branches:
    main:
      - step:
          name: Build Docker Image
          script:
            - export IMAGE_NAME="ektowett/nestsimql:${BITBUCKET_BRANCH}-${BITBUCKET_COMMIT::7}"
            - docker build -t $IMAGE_NAME .
            - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD
            - docker push $IMAGE_NAME
          services:
            - docker
      - step:
          # trigger: manual
          name: Deploy to Kubernetes
          script:
            - apk add --update --no-cache yq bash curl openssl
            - curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
            - export IMAGE_TAG="${BITBUCKET_BRANCH}-${BITBUCKET_COMMIT::7}"
            - echo $KUBECONFIG | base64 -d > kubeconfig.yml
            - export KUBECONFIG=./kubeconfig.yml
            - helm repo add mycharts https://etowett.github.io/helm-charts
            - helm repo update
            - >-
              helm upgrade --install --debug nestsimql mycharts/app \
                --version 0.1.8 \
                --namespace=dev \
                --create-namespace \
                --timeout 300s \
                --wait \
                --set image.tag=${IMAGE_TAG} \
                -f deploy/helm/dev.yml

In the above:

  • I am using helm charts https://etowett.github.io/helm-charts

Content of dev.yml values fine

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
replicaCount: 1

image:
  repository: ektowett/nestsimql
  pullPolicy: IfNotPresent
  tag: latest

serviceAccount:
  create: true

service:
  type: ClusterIP
  name: nestsimql
  port: 4027

resources:
  limits:
    cpu: 2000m
    memory: 2048Mi
  requests:
    cpu: 100m
    memory: 64Mi

ingress:
  enabled: true
  className: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod-issuer
  hosts:
    - host: nestsimql.in.citizix.com
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls:
    - secretName: nestsimql-internal-tls
      hosts:
        - nestsimql.in.citizix.com

env:
  PORT: "4027"
  LOG_LEVEL: debug
  DB_URI: mongodb://root:SuperSecretPassword@mongodb-app.mongodb:27017
  DB_NAME: dev_nestsimql
  ENV: dev

Execute pipelines

Push changes to your repository, and Bitbucket Pipelines will automatically trigger the pipeline. Monitor the pipeline execution in the Bitbucket Pipelines dashboard.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy