Installation

This document describes how to deploy the GitLab Operator via manifests in your Kubernetes or OpenShift cluster.

If using OpenShift, these steps are usually handled by OLM (the Operator Lifecycle Manager) once an operator is bundle published. However, to test the most recent operator images, users may need to install the operator using the deployment manifests available in the operator repository.

Prerequisites

Please consult the “Prerequisites” section of the installation page.

Clone the GitLab Operator repository to your local system:

git clone https://gitlab.com/gitlab-org/cloud-native/gitlab-operator.git
cd gitlab-operator

External dependencies

The GitLab Operator requires external PostgreSQL, Redis, and object storage services. Use scripts/dev_dependencies.sh to quickly provision externally managed replacements (CloudNativePG, Valkey, and Garage) in your cluster.

The script downloads its CI library from the GitLab Charts repository at runtime, which is the same library used by scripts/test.sh in CI. This ensures that local and CI environments are consistent.

After setup, the script generates an external-deps.yaml file containing only the connection values for Redis, PostgreSQL, and object storage. Merge those values into your own mygitlab.yaml under spec.chart.values before applying the CR.

The script requires approximately 2 CPU cores, 4 GiB of memory, and 12 GiB of persistent storage.

The Garage setup adds a Helm repository named garage to your local Helm configuration. If you already have a garage repository registered with a different version, the setup fails. Remove it first, then re-run setup:

helm repo remove garage
bash scripts/dev_dependencies.sh setup

Quick start

  1. From the root of the operator repository, run:

    bash scripts/dev_dependencies.sh setup

    To use a different namespace:

    NAMESPACE=my-namespace bash scripts/dev_dependencies.sh setup

    The script deploys the external services and writes an external-deps.yaml file containing the Redis, PostgreSQL, and object storage connection values.

  2. Merge the contents of external-deps.yaml under spec.chart.values in your mygitlab.yaml.

  3. Deploy the operator, then apply your CR:

    kubectl -n gitlab-system apply -f mygitlab.yaml

What the script does

  1. Valkey - deploys a standalone instance with authentication and a persistent volume. A random password is auto-generated and stored in a Kubernetes Secret on first run; subsequent runs reuse the existing secret.
  2. CloudNativePG - installs the operator (namespace-scoped) and creates a single-instance PostgreSQL cluster with the gitlabhq_production database.
  3. Garage - installs the object storage service, creates the GitLab buckets, and writes three Kubernetes Secrets (dev-garage-gitlab-object-storage, dev-garage-gitlab-object-storage-s3cmd, dev-garage-gitlab-registry-storage).

Managing the setup

Check status:

bash scripts/dev_dependencies.sh status

Remove the external dependencies (does not affect the operator or GitLab CR):

bash scripts/dev_dependencies.sh teardown

Remove the operator release as well:

helm uninstall gitlab-operator --namespace gitlab-system

Configuration

Variable Default Description
NAMESPACE gitlab-system Kubernetes namespace for all services
OUTPUT_FILE external-deps.yaml Output path for the generated external deps CR
GARAGE_APP_VERSION 2.2.0 Garage version to install
CNPG_POSTGRESQL_TAG 17 PostgreSQL image tag used by CloudNativePG
CHART_REPO_URL https://gitlab.com/gitlab-org/charts/gitlab GitLab Charts repository for CI library scripts
CHART_CI_LIB_REF master Git ref for downloading CI library scripts

Installing the GitLab Operator

  1. Deploy the GitLab Operator.

    kubectl create namespace gitlab-system
    task deploy_operator # or "task deploy_operator_openshift"

    This command first deploys the service accounts, roles and role bindings used by the operator, and then the operator itself.

    When working on a merge request, override the default latest tag used by the deploy_operator by setting the TAG environment variable to the name of your branch. For example: TAG=my-mr-branch-name task deploy_operator.

    When working on a forked MR, the branch name might result in a malformed image name, as this pipeline ran in the fork. After you have assessed that the code poses no security risk to our pipelines, trigger a manual pipeline in our project, and use the commit sha as the TAG. For example: TAG=7f954ee1 task deploy_operator.

    You must deploy GitLab to the operator namespace. Other namespaces aren’t supported.

  2. Create a GitLab custom resource (CR).

    Create a new file mygitlab.yaml based on the external-deps.yaml generated by the dev_dependencies.sh script and add environment specific settings.

    An example of common additional settings are:

    apiVersion: apps.gitlab.com/v1beta1
    kind: GitLab
    metadata:
      name: gitlab
    spec:
      chart:
        version: "X.Y.Z" # select a version from the CHART_VERSIONS file in the root of this project
        values:
          global:
            hosts:
              domain: example.com # use a real domain here
            ingress:
              configureCertmanager: true
          certmanager-issuer:
            email: youremail@example.com # use your real email address here

    For more details on configuration options to use under spec.chart.values, see our GitLab Helm Chart documentation.

  3. Deploy a GitLab instance using your new GitLab CR.

    kubectl -n gitlab-system apply -f mygitlab.yaml

    This command sends your GitLab CR up to the cluster for the GitLab Operator to reconcile. You can watch the progress by tailing the logs from the controller pod:

    kubectl -n gitlab-system logs deployment/gitlab-controller-manager -c manager -f

    You can also list GitLab resources and check their status:

    kubectl get gitlabs -n gitlab-system

    When the CR is reconciled (the status of the GitLab resource will be RUNNING), you can access GitLab in your browser at https://gitlab.example.com.

Updating the GitLab Operator

It’s the same command for installing, but you might have to add --force to override any previously-cached results.

task --force deploy_operator

Cleanup

Certain operations like file removal under config/ directory may not trigger rebuild/redeploy, in which cases one should employ:

task clean

This will remove all of the build artifacts and the install record.

Uninstall

Follow the steps below to remove the GitLab Operator and its associated resources.

Items to note prior to uninstalling the operator:

  • The operator does not delete the Persistent Volume Claims or Secrets when a GitLab instance is deleted.
  • When deleting the Operator, the namespace where it is installed (gitlab-system by default) will not be deleted automatically. This is to ensure persistent volumes are not lost unintentionally.

Uninstall an instance of GitLab

kubectl -n gitlab-system delete -f mygitlab.yaml

This will remove the GitLab instance, and all associated objects except for (PVCs as noted above).

Uninstall the GitLab Operator

task delete_operator

This will delete the Operator’s resources, including the running Deployment. It will not delete objects associated with a GitLab instance.