Deployment Guide

Before running helm install, you need to make some decisions about how you will run GitLab. Options can be specified using Helm’s --set command line option. A complete list of command line options can be found here. This guide will cover required values and common options.

Selecting configuration options

In each section collect the options that will be combined to use with helm install.


There are some secrets that need to be created (e.g. SSH keys). By default they will be generated automatically, but if you want to specify them, you can follow the secrets guide.

Networking and DNS

By default, the chart relies on Kubernetes Service objects of type: LoadBalancer to expose GitLab services using name-based virtual servers configured withIngress objects. You’ll need to specify a domain which will contain records to resolve gitlab, registry, and minio (if enabled) to the appropriate IP for your chart.

Include these options in your Helm install command:


Dynamic IPs with external-dns

If you plan to use an automatic DNS registration service like external-dns, you won’t need any additional configuration for GitLab, but you will need to deploy it to your cluster. If external-dns is your choice, the project page has a comprehensive guide for each supported provider.

If you provisioned a GKE cluster using the scripts in this repo, external-dns is already installed in your cluster.

Static IP

If you plan to manually configure your DNS records they should all point to a static IP. For example if you choose and you have a static IP of, then, and (if using MinIO) should all resolve to

If you are using GKE, there is some documentation here for configuring static IPs and DNS. Consult your Cloud and/or DNS provider’s documentation for more help on this process.

Include these options in your Helm install command:

--set global.hosts.externalIP=


By default the chart will create Volume Claims with the expectation that a dynamic provisioner will create the underlying Persistent Volumes. If you would like to customize the storageClass or manually create and assign volumes, please review the storage documentation.

Important: After initial installation, making changes to your storage settings requires manually editing Kubernetes objects, so it’s best to plan ahead before installing your production instance of GitLab to avoid extra storage migration work.

TLS certificates

You should be running GitLab using https which requires TLS certificates. By default the chart will install and configure cert-manager to obtain free TLS certificates. If you have your own wildcard certificate, you already have cert-manager installed, or you have some other way of obtaining TLS certificates, read about more TLS options here.

For the default configuration, you must specify an email address to register your TLS certificates.

Include these options in your Helm install command:



By default this chart provides an in-cluster PostgreSQL database, for trial purposes only.

NOTE: This configuration is not recommended for use in production.

  • The container runs as root
  • A single, non-resilient Deployment is used

You can read more about setting up your production-ready database in the advanced database docs.

If you have an external PostgreSQL database ready, the chart can be configured to use it as shown below.

Include these options in your Helm install command:

--set postgresql.install=false
--set global.psql.password.secret=kubernetes_secret_name
--set global.psql.password.key=key_that_contains_postgres_password


By default we use an single, non-replicated Redis instance. If desired, a highly available Redis can be deployed instead. To install an HA Redis cluster one needs to set redis.cluster.enabled=true when the GitLab chart is installed.

You can bring an external Redis instance by setting redis.install=false, and following our advanced documentation for configuration.

The installation of an HA Redis cluster from the GitLab chart does not support using sentinels. If sentinel support is desired, a Redis cluster needs to be created separately from the GitLab chart install. This can be done inside or outside the Kubernetes cluster. Sentinel settings can be found in the Unicorn chart.

An issue to track the supporting of sentinels in a GitLab deployed Redis cluster has been created for tracking purposes.


By default this chart provides an in-cluster MinIO deployment to provide an object storage API. This configuration should not be used in production.

You can read more about setting up your production-ready object storage in the external object storage


We use the upstream Prometheus chart, and do not override values from our own defaults. We do, however, default disable alertmanager, nodeExporter, and pushgateway.

Refer to the Prometheus chart documentation for the exhaustive list of configuration options and ensure they are sub-keys to prometheus, as we use this as requirement chart.

For instance, the requests for persistent storage can be controlled with:

    enabled: false
      enabled: false
      size: 2Gi
    enabled: false
      enabled: false
      size: 2Gi
      enabled: true
      size: 8Gi

Outgoing email

By default outgoing email is disabled. To enable it, provide details for your SMTP server using the global.smtp and settings. You can find details for these settings in the command line options.

If your SMTP server requires authentication make sure to read the section on providing your password in the secrets documentation. You can disable authentication settings with --set global.smtp.authentication="".

If your Kubernetes cluster is on GKE, be aware that SMTP port 25 is blocked.

Incoming email

By default incoming email is disabled. To enable it, provide details of your IMAP server and access credentials using the global.appConfig.incomingEmail settings. You can find details for these settings in the command line options. You will also have to create a Kubernetes secret containing IMAP password as described in the secrets guide.

To use reply-by-email feature, where users can reply to notification emails to comment on issues and MRs, you need to configure both outgoing email and incoming email settings.

Deploy the Community Edition

By default, the Helm charts use the Enterprise Edition of GitLab. If desired, you can instead use the Community Edition. Learn more about the difference between the two.

To deploy the Community Edition, include this option in your Helm install command:

--set global.edition=ce


This chart defaults to creating and using RBAC. If your cluster does not have RBAC enabled, you will need to disable these settings:

--set certmanager.rbac.create=false
--set nginx-ingress.rbac.createRole=false
--set prometheus.rbac.create=false
--set gitlab-runner.rbac.create=false

CPU and RAM Resource Requirements

The resource requests, and number of replicas for the GitLab components (not PostgreSQL, Redis, or MinIO) in this Chart are set by default to be adequate for a small production deployment. This is intended to fit in a cluster with at least 8vCPU and 30gb of RAM. If you are trying to deploy a non-production instance, you can reduce the defaults in order to fit into a smaller cluster.

The minimal GKE example values file provides an example of tuning the resources to fit within a 3vCPU 12gb cluster.

The minimal Minikube example values file provides an example of tuning the resources to fit within a 2vCPU, 4gb Minikube instance.

Deploy using Helm

Once you have all of your configuration options collected, we can get any dependencies and run Helm. In this example, we’ve named our Helm release gitlab.

helm repo add gitlab
helm repo update
helm upgrade --install gitlab gitlab/gitlab \
  --timeout 600s \
  --set \
  --set global.hosts.externalIP= \
Note: All Helm commands are specified using Helm v3 syntax. If the Helm v2 syntax differs every effort is made to provide a note that details the difference.
Note: If helm install is used there is a slight difference in the way that Helm v2 and Helm v3 operate. When using Helm v2 if a release name was not specified with the --name option it would randomly generate the release name. Helm v3 requires that the release name be specified as a positional argument on the command line unless the --generate-name option is used.
Note: The timeout option above is handled differently between Helm v2 and Helm v3. With Helm v3 allows one to specify a duration with a unit appended to the value (e.g. 120s = 2m and 210s = 3m30s). The --timeout option is handled as the number of seconds without the unit specification.
Note: The use of the --timeout option is deceptive in that there are multiple components that are deployed during an Helm install or upgrade in which the --timeout is applied. The --timeout value is applied to the installation of each component individually and not applied for the installation of all the components. So intending to abort the Helm install after 3 minutes by using --timeout=3m may result in the install completing after 5 minutes because none of the installed components took longer than 3 minutes to install.

You can also use --version <installation version> option if you would like to install a specific version of GitLab.

Mappings between chart versions and GitLab versions can be found here.

Instructions for installing a development branch rather than a tagged release can be found in the developer deploy documentation.

GitLab Operator (experimental)

If you would like to use GitLab Operator to achieve zero downtime upgrades, please follow the documentation for using the operator.

Monitoring the Deployment

This will output the list of resources installed once the deployment finishes which may take 5-10 minutes.

The status of the deployment can be checked by running helm status gitlab which can also be done while the deployment is taking place if you run the command in another terminal.

Initial login

You can access the GitLab instance by visiting the domain specified during installation. If you manually created the secret for initial root password, you can use that to sign in as root user. If not, GitLab would’ve automatically created a random password for root user. This can be extracted by the following command (replace <name> by name of the release - which is gitlab if you used the command above).

kubectl get secret <name>-gitlab-initial-root-password -ojsonpath='{.data.password}' | base64 --decode ; echo