Automate Kubernetes Deployments with GitLab CI/CD and Dynamic Image Tags

Continuous deployment to Kubernetes clusters doesn’t have to be complex. In this guide, you’ll learn how to fully automate Docker image builds, pushes to a GitLab container registry, and Kubernetes deployments using a clean and efficient GitLab CI/CD pipeline.

Whether you’re working with a production-grade app or a side project, this pipeline template will help you:

  • Build and push container images using Podman (or Docker).
  • Create Kubernetes secrets for private registry access.
  • Automatically update your deployment files with dynamic image tags.
  • Apply your manifests to a Kubernetes cluster using kubectl.

✅ Why Automate Kubernetes Deployments?

Manual deployments are slow, error-prone, and don’t scale well with agile development. By automating the process, you ensure:

  • Consistency across environments
  • Speed in releasing new features
  • Security by handling secrets and credentials cleanly
  • Visibility into each stage of deployment via GitLab CI pipelines

🧱 Prerequisites

To follow this guide, you’ll need:

  • A running Kubernetes cluster (e.g., K3s, Minikube, EKS, GKE, etc.)
  • GitLab Runners with access to your cluster (via kubectl and configured KUBECONFIG)
  • A GitLab project with Container Registry enabled
  • kubectl and envsubst installed in your GitLab Runner environment

🧾 Step-by-Step GitLab CI/CD Example for Kubernetes Deployment

Below is a complete working .gitlab-ci.yml template that handles everything from building to deploying your app.

🔧 .gitlab-ci.yml

stages:
  - build
  - push
  - deploy

variables:
  IMAGE_TAG: $CI_COMMIT_SHORT_SHA
  IMAGE_NAME: registry.src.yellowgnu.net/internal/e2bvalidator

before_script:
  - echo "Running job on $(hostname)"

build:
  stage: build
  script:
    - podman build -t $IMAGE_NAME:$IMAGE_TAG .

push:
  stage: push
  script:
    - echo "$CI_REGISTRY_PASSWORD" | podman login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
    - podman push $IMAGE_NAME:$IMAGE_TAG

create-regcred:
  stage: deploy
  script:
    - mkdir -p ~/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(echo -n $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD | base64 | tr -d '\n')\"}}}" > ~/.docker/config.json
    - kubectl create secret generic regcred \
        --from-file=.dockerconfigjson=$HOME/.docker/config.json \
        --type=kubernetes.io/dockerconfigjson \
        --dry-run=client -o yaml | kubectl apply -f -

deploy:
  stage: deploy
  script:
    - export IMAGE_TAG=$CI_COMMIT_SHORT_SHA
    - envsubst < k8s/deployment.yaml > k8s/deployment.generated.yaml
    - kubectl apply -f k8s/deployment.generated.yaml
    - kubectl apply -f k8s/service.yaml
  only:
    - master

🧩 Kubernetes Deployment Template

Use environment variable substitution in your Kubernetes manifest to dynamically inject the image tag.

🔧 k8s/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: e2bvalidator
spec:
  replicas: 1
  selector:
    matchLabels:
      app: e2bvalidator
  template:
    metadata:
      labels:
        app: e2bvalidator
    spec:
      containers:
        - name: e2bvalidator
          image: registry.src.yellowgnu.net/internal/e2bvalidator:${IMAGE_TAG}
          ports:
            - containerPort: 8080
      imagePullSecrets:
        - name: regcred

🔐 How regcred Works

The create-regcred job securely creates a Kubernetes secret of type kubernetes.io/dockerconfigjson. This allows Kubernetes to pull private images from the GitLab Container Registry without manual intervention.

Tip: This step uses base64 encoding and tr -d '\n' to ensure your credentials are stored in a valid JSON string.


🧪 Best Practices

  • Use short commit SHA ($CI_COMMIT_SHORT_SHA) as your image tag to make rollback easier.
  • Use envsubst rather than sed to prevent syntax issues with YAML and shell variables.
  • Separate configuration files (e.g., deployment.yaml, service.yaml, ingress.yaml) for modularity.
  • Consider using Helm for more advanced templating and values injection.

📌 Conclusion

This GitLab CI/CD setup empowers your team to deploy automatically and consistently with every push to master. By combining Podman, GitLab Registry, Kubernetes secrets, and dynamic tag substitution, you can maintain clean, secure, and production-ready pipelines.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back