Skip to content

Deploying from Git

Instead of running kubectl apply yourself, you can point your namespace at a Git repository. The platform watches it and applies whatever is there, so deploying becomes a push.

You set it up in the Kubernetes section of the portal, under Git. Four fields:

FieldWhat it is
Repository URLWhere your manifests live
PathThe directory inside the repository to apply. The whole repository if empty
RevisionBranch, tag or commit to track
Self-healWhether to undo changes made directly with kubectl

Everything in that path is applied into your namespace. There is nothing to install and no credential to hand out.

Before you start, four things to know

The repository must be reachable without credentials. There is no field for a username, token or deploy key, so in practice the repository has to be publicly readable. A private repository will not sync.

Only https:// and ssh:// URLs are accepted. Not a bare IP address, and not a host inside the cluster.

Pruning is always on. It is not a setting. Anything you remove from the repository is deleted from your namespace on the next sync. That is the point of deploying this way, but it means the repository is the whole truth: an object that exists only because someone once applied it by hand will be removed.

Self-heal is the one thing you choose. With it on, a change made with kubectl is reverted to what the repository says. With it off, your change stands until the next time that file changes in Git. Leave it on unless you have a reason: half the value of deploying from Git is that the cluster cannot drift.

What you can deploy this way

Most of what your namespace can create, but not quite all of it. These work with kubectl and are refused through Git:

  • Vertical pod autoscalers
  • Client settings policies

If a manifest applies by hand and never appears after a sync, check whether it is one of those before looking anywhere else. Everything else on Permissions and policies is accepted, including Deployments, Services, ConfigMaps, Secrets, PVCs, Jobs, CronJobs, HPAs, routes, and all three database operators.

Cluster-scoped objects are refused, as they are with kubectl.

A repository layout that works

text
my-app/
  k8s/
    deployment.yaml
    service.yaml
    httproute.yaml

Point Path at k8s, Revision at main, and you are done. Nothing about the manifests changes: they are the same files from Your first deployment.

Do not commit secrets in plaintext. A Secret in Git is readable by anyone who can read the repository, and this repository is public. Create secrets with kubectl and leave them out of the path you sync, or reference values your application reads from elsewhere.

Deploying with kubectl from CI instead

If you would rather drive deployment from your own pipeline, use the kubeconfig as a CI secret and run kubectl apply from the pipeline.

Two things to plan for:

The kubeconfig expires after a year. Nothing in your pipeline warns you. You get an email before it lapses; put the renewal somewhere you will see it, or the pipeline will start failing to authenticate roughly a year after you set it up.

Treat the kubeconfig as a long-lived credential

Downloading a new kubeconfig does not invalidate the old one, and you cannot revoke one yourself. A leaked file keeps working for the rest of its year, and containing that needs support to cut off namespace access.

Store it as a masked CI secret, never in the repository, and never print it in job output.

See Access and kubectl for both points in full.

What's next