Quick Start¶
Goal: go from zero to a browser-accessible GitLab Community Edition with managed PostgreSQL and Redis in roughly 15 minutes.
This is the golden path — one GitlabInstance, managed backends, one admin login. For the full configuration surface, see the Guides section.
Prerequisites¶
You need a cluster with the following already installed. Fix any missing items first — the operator assumes these exist.
| Requirement | Why | Check |
|---|---|---|
| Kubernetes 1.25+ | CRD + status subresource support | kubectl version |
| Flux CD 2.3.x (source-controller + helm-controller) | The operator emits HelmRelease resources; Flux applies them |
flux check |
Percona PG Operator (pgv2.percona.com) |
Required for postgres.managed: true |
kubectl get crd perconapgclusters.pgv2.percona.com |
OT-Container-Kit redis-operator (redis.redis.opstreelabs.in) |
Required for redis.managed: true |
kubectl get crd redis.redis.opstreelabs.in |
| Ingress controller (NGINX, Traefik, etc.) | External access to the GitLab URL | kubectl get ingressclass |
Default StorageClass |
PVCs for managed databases | kubectl get sc |
| A DNS name that resolves to your ingress | So you can reach GitLab in a browser | dig git.example.com |
The Installation page covers installing the operator itself and the backend operators.
Step 1 — Apply the default GitlabVersionMap¶
The operator always looks up the cluster-scoped GitlabVersionMap named default to resolve spec.version to a Helm chart version. Apply it once per cluster:
kubectl apply -f https://raw.githubusercontent.com/bnerd/bnerd-gitlab-operator/main/examples/versionmap-default.yaml
# or from a local clone:
kubectl apply -f examples/versionmap-default.yaml
Verify:
Step 2 — Create a namespace and apply a GitlabInstance¶
Replace git.example.com with your real DNS name. This example uses managed Postgres and Redis so the operator provisions those clusters for you.
# gitlab-ce-demo.yaml
apiVersion: k8s.bnerd.com/v1alpha1
kind: GitlabInstance
metadata:
name: gitlab-demo
namespace: gitlab-demo
spec:
version: "18" # resolves to latest 18.x via GitlabVersionMap
edition: ce
domains:
gitlab: git.example.com
registry: registry.example.com
postgres:
managed: true
topology: standalone # use "ha" for production (3-node Percona cluster)
redis:
managed: true
topology: standalone
objectStorage:
credentialsSecret: gitlab-demo-s3 # see Step 3
Object storage is required for GitLab 19+
GitLab 19 (chart 10) removed bundled MinIO. If you are deploying version 19 or later, an S3 credentials secret is mandatory. For testing on version 18 or earlier you may omit objectStorage and rely on in-chart storage — though this is not recommended for production.
Create the namespace and apply:
Step 3 — Provide an S3 credentials Secret (required for v19+)¶
If you are deploying GitLab 18 for the quick start you can skip this step. For version 19+, create the Secret before applying the CR:
apiVersion: v1
kind: Secret
metadata:
name: gitlab-demo-s3
namespace: gitlab-demo
stringData:
accessKey: YOUR_ACCESS_KEY
secretKey: YOUR_SECRET_KEY
endpoint: https://s3.example.com
region: default
bucket.registry: gitlab-demo-registry
bucket.lfs: gitlab-demo-lfs
bucket.artifacts: gitlab-demo-artifacts
bucket.uploads: gitlab-demo-uploads
bucket.packages: gitlab-demo-packages
bucket.mr-diffs: gitlab-demo-mr-diffs
bucket.terraform: gitlab-demo-terraform
bucket.ci-secure-files: gitlab-demo-ci-secure-files
bucket.dependency-proxy: gitlab-demo-dependency-proxy
bucket.backups: gitlab-demo-backups
bucket.pages: gitlab-demo-pages
See Object Storage for the full key reference.
Step 4 — Watch the instance come up¶
kubectl get gli -n gitlab-demo -w
# NAME PHASE HOST VERSION AGE
# gitlab-demo Provisioning 30s
# gitlab-demo Deploying https://git.example.com 18.11.6 4m
# gitlab-demo Ready https://git.example.com 18.11.6 8m
The phase sequence is Pending → Provisioning (managed backends starting) → Deploying (HelmRelease emitted, Flux installing) → Ready.
The first run takes 5–10 minutes because the managed PostgreSQL cluster must initialise. If it stays in Provisioning beyond 15 minutes, see Troubleshooting.
Step 5 — Verify the deployment¶
# Status and conditions
kubectl describe gli gitlab-demo -n gitlab-demo
# Flux HelmRelease (the actual chart install)
kubectl get helmrelease -n gitlab-demo
# GitLab pods
kubectl get pods -n gitlab-demo
# Managed Postgres cluster
kubectl get perconapgcluster -n gitlab-demo
# Managed Redis
kubectl get redis -n gitlab-demo 2>/dev/null || kubectl get redisreplication -n gitlab-demo
Step 6 — Log in as root¶
The initial root password is stored in a Secret generated by the upstream GitLab chart:
kubectl get secret gitlab-demo-gitlab-initial-root-password \
-n gitlab-demo \
-o jsonpath='{.data.password}' | base64 -d; echo
Open https://git.example.com in your browser and log in with username root and the password above. Change it immediately after first login.
Change the initial root password
The auto-generated root password is stored in a Kubernetes Secret. Copy it, log in, and set a strong password in GitLab's user settings before giving anyone else access.
What's next¶
- Production topology (HA backends)? → Managed Backends shows HA Postgres and Redis Sentinel configuration.
- Enterprise Edition? → Editions & Licensing covers the
licenseSecretshape and what EE unlocks. - Upgrading? → Version Management explains the required upgrade stop sequence (do not skip stops).
- Object storage? → Object Storage describes the full bucket-class mapping.
- Custom node scheduling? → set
spec.placement.nodeSelectorandtolerationson theGitlabInstance.