Automating build and deployment from Bitbucket to Kubernetes lets you push code and have a new image built and deployed without manual steps. Bitbucket Pipelines is a built-in CI/CD service that runs pipelines defined in YAML in your repository.
In this guide you will:
- Configure repository variables in Bitbucket for Docker Hub and Kubernetes access
- Use a two-step pipeline: build a Docker image and push it, then deploy to Kubernetes with Helm
- Optionally run the deploy step manually so you control when releases go out
Pipelines can be simple or complex; splitting work into steps helps because each step can be re-run on its own, and only the repo and any declared artifacts are passed between steps.
Prerequisites
Before you start:
- Bitbucket repository – Your application code is in a Bitbucket repo (not necessarily Bitbucket Server; Pipelines runs on Bitbucket Cloud).
- Kubernetes cluster – A cluster you can deploy to (e.g. kubeadm, K3s, or a managed cluster).
kubectlshould be configured locally so you can export a kubeconfig. - Docker Hub (or another registry) – An account to push images. The pipeline below uses Docker Hub; you can switch to another registry by changing the login and image name.
- Helm – The deploy step installs Helm in the pipeline; your chart can live in the repo or in a Helm chart repository.
For more on Pipelines configuration, see Bitbucket: Configure Pipelines variables.
Configure Repository Variables in Bitbucket
Store credentials and the Kubernetes kubeconfig as repository variables so the pipeline can push images and deploy without hardcoding secrets.
- In your Bitbucket repo, go to Repository settings → Pipelines → Repository variables.
- Add the following variables. For secrets, enable Secured so they are masked in logs.
| Variable | Secured | Description |
|---|---|---|
DOCKERHUB_USERNAME | No | Docker Hub username for pushing images. |
DOCKERHUB_PASSWORD | Yes | Docker Hub token or password; prefer access token. |
KUBECONFIG | Yes | Base64-encoded kubeconfig so the pipeline can authenticate to the cluster. |
Getting the KUBECONFIG value
Use a kubeconfig that has access only to the cluster (and namespace) you need. From your workstation:
Switch to the right context (if you use multiple clusters):
1 2kubectl config use-context dev-ello-platform-k3s # or: k ctx dev-ello-platform-k3s # if you use kubectxExport the current context, minified and raw:
1kubectl config view --minify --rawBase64-encode it (Bitbucket expects the variable to be the encoded string):
1 2kubectl config view --minify --raw | base64 # or on Alpine: openssl base64Copy the output and paste it as the value of the KUBECONFIG repository variable (Secured).
The pipeline will decode this and write it to a file, then set KUBECONFIG so kubectl and Helm use it.
Pipeline Overview
The example pipeline has two steps:
- Build Docker image – Build the image, log in to Docker Hub, push the image with a tag derived from branch and commit (e.g.
main-abc1234). - Deploy to Kubernetes – Install Helm, decode
KUBECONFIG, add your Helm repo, and runhelm upgrade --installwith the new image tag and a values file (e.g.deploy/helm/dev.yml).
The pipeline runs on every push to main; you can change the branch or add a manual trigger for the deploy step (see below).
Example: bitbucket-pipelines.yml
Place this file at the root of your repository as bitbucket-pipelines.yml:
| |
Notes:
- IMAGE_NAME / IMAGE_TAG – Uses
BITBUCKET_BRANCHand the first 7 characters ofBITBUCKET_COMMITso each build has a unique tag (e.g.main-abc1234). - Docker – The build step runs with the Docker service so
docker buildanddocker pushwork. - Helm – The deploy step installs Helm and uses a chart from
https://etowett.github.io/helm-charts; replace with your own repo and chart name. - Manual deploy – To require a manual approval before deploy, add
trigger: manualunder the deploy step (see Bitbucket Pipelines triggers).
Example: Helm Values File (dev.yml)
The pipeline passes a values file, e.g. deploy/helm/dev.yml. The chart is expected to support at least image.repository, image.tag, and your app’s settings (replicas, service, ingress, env). Example:
deploy/helm/dev.yml:
| |
The pipeline overrides image.tag with --set image.tag=${IMAGE_TAG}, so the value of tag here is only a default. For production, avoid committing secrets (e.g. DB_URI with password) in this file; use Kubernetes Secrets or a secrets manager (e.g. HashiCorp Vault) and reference them in the chart. For Ingress TLS, see How to Configure Ingress TLS/SSL in Kubernetes.
Running the Pipeline
- Commit and push
bitbucket-pipelines.yml(anddeploy/helm/dev.ymlif needed) to themainbranch. - Bitbucket Pipelines will run the pipeline automatically on push.
- Watch progress under Pipelines in the repo. If the deploy step has
trigger: manual, run that step from the Pipelines UI when you want to deploy.
After a successful run, the new image tag will be deployed to the dev namespace (or whatever namespace and values you use).
Troubleshooting
- Docker login failed – Check
DOCKERHUB_USERNAMEandDOCKERHUB_PASSWORD. Use a Docker Hub access token and ensure the variable is not truncated (no newlines in the base64 if you ever encode something else). - Helm / kubectl: permission denied or 403 – The kubeconfig in
KUBECONFIGmust have RBAC permissions to create/update resources in the target namespace. Test locally with the same kubeconfig. - Image pull back-off – The cluster must be able to pull the image (e.g. from Docker Hub). If the repo is private, create an imagePullSecret and reference it in the Helm chart.
- Pipeline variable not set – Ensure the variable is defined under Repository variables (or Workspace/Deployment variables if you use those) and that the pipeline runs in a context where those variables are available.
Summary
You now have a Bitbucket Pipelines setup that:
- Builds a Docker image and pushes it to Docker Hub (or another registry) with a tag like
main-<commit-sha>. - Deploys to Kubernetes with Helm, using a values file and overriding the image tag.
Store Docker and Kubernetes credentials as secured repository variables, and prefer Kubernetes Secrets or a secrets manager for application secrets (e.g. DB credentials) instead of putting them in the values file in the repo. For more advanced Kubernetes deployment (e.g. GitOps with Argo CD), see How to Deploy and Configure Argo CD in Kubernetes.