Deploying production-ready GitLab on Google Kubernetes Engine

This document describes how to deploy a scalable, reliable, and observable GitLab instance on Google Kubernetes Engine (GKE). GitLab is an open source application that helps its users plan, store, test, and deploy their source code. Its core functionality is that of a source code management platform, but it also includes features for project management, continuous integration, and continuous deployment.

In this tutorial, you deploy the following architecture. You use GKE for GitLab's application components and Google Cloud managed services where possible to decrease the operational burden of running GitLab. You use Helm as the mechanism to install and configure the GitLab application components in GKE.

Architecture that uses GKE for GitLab's application components and Google Cloud
managed services to decrease the operational burden of running GitLab

The following table maps the Google Cloud products used in this tutorial to their use case in GitLab.

Datastore Use case
Cloud Monitoring Durable monitoring metric storage
Metric dashboarding
System logs
Cloud Storage Backups
Large file storage
Build artifacts
Cloud SQL for PostgreSQL Application metadata
User information
Memorystore for Redis Temporary data
Session data
Background job queues

This tutorial assumes an understanding of Identity and Access Management (IAM), Google Kubernetes Engine, and Cloud SQL.

If you are looking for a more automated approach to installation, use the GitLab on GKE Terraform module on GitHub.


  • Create backing datastores to host GitLab data.
  • Install GitLab in a GKE cluster.
  • Connect to GitLab.


This tutorial uses the following billable components of Google Cloud:

  • Compute Engine
  • Google Kubernetes Engine
  • Cloud Load Balancing
  • Cloud SQL
  • Memorystore
  • Container Registry
  • Cloud Storage
  • Cloud Monitoring

To generate a cost estimate based on your projected usage, use the pricing calculator. New Google Cloud users might be eligible for a free trial.

Before you begin

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud Console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Cloud project. Learn how to confirm that billing is enabled for your project.

When you finish this tutorial, you can avoid continued billing by deleting the resources you created. For more information, see Cleaning up.

Creating prerequisite resources

Enable APIs

  1. Open Cloud Shell:

    Open Cloud Shell

  2. In Cloud Shell, enable the Google Kubernetes Engine, Service Networking, Resource Manager, and Redis APIs:

    gcloud services enable \

Configure IAM

  • Create an IAM service account for GitLab. Then add the storage.admin role to it so that it can access Cloud Storage.

    export PROJECT_ID=$(gcloud config get-value project)
    gcloud iam service-accounts create gitlab-gcs \
        --display-name "GitLab Cloud Storage"
    gcloud iam service-accounts keys create --iam-account \
        gitlab-gcs@${PROJECT_ID} gcs-key.json
    gcloud projects add-iam-policy-binding --role roles/storage.admin ${PROJECT_ID} \

Create Cloud Storage buckets

  • Use the gsutil command-line tool to create the buckets used by GitLab:

    export PROJECT_ID=$(gcloud config get-value project)
    gsutil mb gs://${PROJECT_ID}-gitlab-backups
    gsutil mb gs://${PROJECT_ID}-git-lfs
    gsutil mb gs://${PROJECT_ID}-gitlab-artifacts
    gsutil mb gs://${PROJECT_ID}-gitlab-uploads
    gsutil mb gs://${PROJECT_ID}-gitlab-packages
    gsutil mb gs://${PROJECT_ID}-gitlab-pseudo
    gsutil mb gs://${PROJECT_ID}-runner-cache
    gsutil mb gs://${PROJECT_ID}-registry

Configure networking

  1. Create an external IP address that can be used to reach your GitLab instance:

    gcloud compute addresses create gitlab --region us-central1 \
        --description "Gitlab Ingress IP"
  2. Create a private IP address range that can be assigned to your Cloud SQL for PostgreSQL database instance so that it can't be reached from outside of your VPC network:

    export PROJECT_ID=$(gcloud config get-value project)
    gcloud compute addresses create gitlab-sql --global --prefix-length 20 \
        --description="Gitlab Cloud SQL range" --network=default
    gcloud services vpc-peerings connect \ --ranges=gitlab-sql \
        --network=default --project ${PROJECT_ID}

Create the PostgreSQL instance and database

  1. Create the Cloud SQL database that GitLab will use to store most of its metadata:

    gcloud beta sql instances create gitlab-db --network default \
        --database-version=POSTGRES_12 --cpu 4 --memory 15 --no-assign-ip \
        --storage-auto-increase --zone us-central1-a

    This command creates a privately accessible PostgreSQL database in the default network, with 4 CPU cores and 15 GB of RAM. The disk size of the database is set to increase automatically as needed.

  2. Create a database user and password for GitLab to authenticate to the database:

    export PASSWORD=$(openssl rand -base64 18)
    gcloud sql users create gitlab --instance gitlab-db --password ${PASSWORD}
  3. Create the database that GitLab will use in your PostgreSQL instance:

    gcloud sql databases create --instance gitlab-db gitlabhq_production

Create the Redis instance

  • Create the Redis instance. For more information on sizing the Redis instance, see the GitLab requirements documentation.

    gcloud redis instances create gitlab --size=2 --region=us-central1 \
        --zone=us-central1-a --tier standard

Create and configure the GKE cluster

  1. Create the GKE cluster that you will use to host the GitLab application's components. The Alias IP feature must be enabled in the cluster so that it can talk to the Redis instance.

    gcloud container clusters create gitlab --machine-type n1-standard-4 \
        --zone us-central1-a --enable-ip-alias
  2. Create a Storage Class so that GitLab can store its Git repositories on SSD Persistent Disks:

    cat > pd-ssd-storage.yaml <<EOF
    kind: StorageClass
      name: pd-ssd
      type: pd-ssd
    kubectl apply -f pd-ssd-storage.yaml
  3. Use kubectl to create a secret in your cluster that holds the PostgreSQL password:

    kubectl create secret generic gitlab-pg --from-literal=password=${PASSWORD}
  4. Create a secret to hold your Cloud Storage credentials:

    kubectl create secret generic google-application-credentials \
  5. Create a secret to hold the additional parameters that Rails needs in order to configure the large file storage, artifacts, upload, and packages features:

    export PROJECT_ID=$(gcloud config get-value project)
    cat > rails.yaml <<EOF
    provider: Google
    google_project: ${PROJECT_ID}
    google_client_email: gitlab-gcs@${PROJECT_ID}
    google_json_key_string: '$(cat gcs-key.json)'
    kubectl create secret generic gitlab-rails-storage --from-file=connection=rails.yaml
  6. Create a secret to hold your GitLab registry parameters and Cloud Storage credentials:

    cat > registry.gcs.yaml <<EOF
      bucket: ${PROJECT_ID}-gitlab-registry-storage
      keyfile: /etc/docker/registry/storage/gcs.json
    kubectl create secret generic gitlab-registry-storage \
      --from-file=storage=registry.gcs.yaml \

    Configuring and installing GitLab

In this section, you use Helm to deploy GitLab from the GitLab Chart repository. Helm is a package manager you can use to configure and deploy Kubernetes apps.

Verify Helm is installed

  1. Verify that Helm is installed on Cloud Shell:

    helm version

    If Helm is correctly installed, v3.2.1 or later appears:

    Client: version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}
  2. If you don't see the a version number that's v3.2.1 or later, follow the instructions in the Helm guide to install Helm.

Install the GitLab chart

The GitLab chart requires custom configuration so that it can leverage the external datastores that you previously provisioned.

  1. Download the configuration file template:

  2. Create the configuration file:

    export PROJECT_ID=$(gcloud config get-value project)
    export INGRESS_IP=$(gcloud compute addresses describe gitlab \
        --region us-central1 --format 'value(address)')
    export DOMAIN=${INGRESS_IP}
    export DB_PRIVATE_IP=$(gcloud sql instances describe gitlab-db \
        --format 'value(ipAddresses[0].ipAddress)')
    export REDIS_PRIVATE_IP=$(gcloud redis instances describe gitlab \
        --region=us-central1  --format 'value(host)')
    export CERT_MANAGER_EMAIL=$(gcloud config get-value account)
    cat values.yaml.tpl | envsubst > values.yaml
  3. Install the chart by using Helm:

    helm repo add gitlab
    helm install -f values.yaml gitlab gitlab/gitlab

Configure monitoring

You can monitor the GitLab installation by using the Prometheus integration. This integration deploys a Prometheus server to scrape metrics from GitLab. A sidecar container then sends metrics from Prometheus to Cloud Monitoring for longer term storage, dashboarding, and alerting.

  1. Clone the Prometheus integration source code:

    git clone
    cd stackdriver-prometheus-sidecar/kube/full
  2. Configure the installation by setting the following environment variables:

    export KUBE_NAMESPACE=default
    export KUBE_CLUSTER=gitlab
    export GCP_REGION=us-central1
    export GCP_PROJECT=$(gcloud config get-value project)
    export SIDECAR_IMAGE_TAG=release-0.4.2
  3. Install the Prometheus integration:


    Your metrics from GitLab will now be added automatically to Monitoring.

Using GitLab

Now that GitLab is up and running, connect to it and set up the initial user password.

Initial login

  1. Get the URL for your GitLab server:

    export GITLAB_HOSTNAME=$(kubectl get ingresses.extensions gitlab-webservice-default \
        -o jsonpath='{.spec.rules[0].host}')
    echo "Your GitLab URL is: https://${GITLAB_HOSTNAME}"
  2. Get the initial root account password:

    kubectl get secret gitlab-gitlab-initial-root-password \
        -o go-template='{{.data.password}}' | base64 -d && echo

    The 64-character string printed to the console is the password. Store it for later.

  3. Ensure that all pods have reached the healthy state:

    kubectl get pods

    It can take 3–5 minutes for all pods to reach the intended state.

  4. Visit the GitLab URL in your browser from step 1 and log in as the root user with the password from step 2. The following screenshot shows the login page.

    GitLab login page

Set up your first user account

When you are logged in, we recommend that you change the username and password of the root account.

  1. In the top navigation bar, click the Admin Area button:

    GitLab Admin Area

  2. In the left navigation bar, click Users:.

    Left navigation bar of GitLab

  3. Click the Edit button on the Administrator row to configure the account details:

    Edit button on Administrator row

  4. In the form that is presented, change the Name, Username, Email, and Password fields, and then click the Save changes button at the bottom.

    You are signed out.

  5. Log in with your new username and password.

You are now ready to use GitLab. Visit the GitLab documentation to learn more about how to interact with it.

For more information on customizing your installation and adding additional layers of security such as mutual TLS database connections, visit the GitLab Chart documentation.

Cleaning up

  1. In the Cloud Console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

What's next

  • Try out other Google Cloud features for yourself. Have a look at our tutorials.