Files
oam/knowledge base/gitlab
2025-09-24 00:24:42 +02:00
..
2025-09-24 00:24:42 +02:00
2025-09-24 00:24:42 +02:00

GitLab

  1. TL;DR
  2. Package
  3. Kubernetes
    1. Helm chart
    2. Operator
  4. Create resources in GitLab using Pulumi
  5. Forking
  6. Repository management
    1. Different owners for parts of the code base
    2. Get the version of the helper image to use for a runner
  7. Manage kubernetes clusters
  8. Maintenance mode
  9. Runners
  10. CI/CD pipelines
  11. Artifacts
    1. Default artifacts expiration
    2. Keep the latest artifacts for all jobs in the latest successful pipelines
  12. Environments
  13. Login via Google, Github or other services
  14. Troubleshooting
    1. Use access tokens to clone projects
    2. GitLab keeps answering with code 502
  15. Further readings
    1. Sources

TL;DR

Using -H 'PRIVATE-TOKEN: glpat-m-…' in API calls is the same as using -H 'Authorization: bearer glpat-m-…'.

Use deploy tokens instead of personal access tokens to access repositories in pipelines as they do not expire.

# List the current application settings of the GitLab instance.
curl -H 'PRIVATE-TOKEN: glpat-m-…' 'https://gitlab.fqdn/api/v4/application/settings'

# Enable maintenance mode.
curl -X 'PUT' -H 'PRIVATE-TOKEN: glpat-m-…' 'https://gitlab.fqdn/api/v4/application/settings?maintenance_mode=true'

# Disable maintenance mode.
curl -X 'PUT' -H 'PRIVATE-TOKEN: glpat-m-…' 'https://gitlab.fqdn/api/v4/application/settings?maintenance_mode=false'

GitLab uses GitLab Flavored Markdown (GLFM) to render Markdown files in its UI.
Since v17.10, one can use Alerts to highlight or call attention to something in GitHub-like fashion.

Package

Previously known as 'Omnibus'.

Default backup location: /var/opt/gitlab/backups.

Installation

Refer Install self-managed GitLab.

sudo dnf install 'gitlab-ee-16.11.6'
sudo EXTERNAL_URL='http://gitlab.example.com' GITLAB_ROOT_PASSWORD='smthng_Strong_0r_it_llfail' apt install 'gitlab-ee'

sudo gitlab-rake 'gitlab:env:info'
Configuration

Template

The application of configuration changes is handled by Chef Infra.
It runs checks, ensures directories, permissions, and services are in place and working, and restarts components if any of their configuration files have changed.

# Change application settings.
# Useful to reach those ones not available in the configuration file.
sudo gitlab-rails runner '
  ::Gitlab::CurrentSettings.update!(gravatar_enabled: false);
  ::Gitlab::CurrentSettings.update!(remember_me_enabled: false);
  ::Gitlab::CurrentSettings.update!(email_confirmation_setting: "hard");
'

# Disable public registration.
sudo gitlab-rails runner '::Gitlab::CurrentSettings.update!(signup_enabled: false)'
# Validate.
# Just makes sure the file is readable from a ruby app.
# GitLab's internal checks do not really do anything.
sudo vim '/etc/gitlab/gitlab.rb'
sudo ruby -c '/etc/gitlab/gitlab.rb'
sudo gitlab-ctl show-config

# Check if there are any configuration in the configuration file that is removed in specified versions.
# Useless by experience.
sudo gitlab-ctl check-config
sudo gitlab-ctl check-config -v '16.11.0'

# Make GitLab aware of the changes.
sudo gitlab-ctl reconfigure

Backup settings for AWS buckets.
See Back up GitLab using Amazon S3:

# If using an IAM Profile, don't configure 'aws_access_key_id' and 'aws_secret_access_key'.
# Set "'use_iam_profile' => true" instead.
gitlab_rails['backup_upload_connection'] = {
  'provider' => 'AWS',
  'region' => 'eu-west-1',
  'aws_access_key_id' => 'AKIAKIAKI',
  'aws_secret_access_key' => 'secret123'
}

# It appears one can use prefixes by appending them to the bucket name.
# See https://gitlab.com/gitlab-org/charts/gitlab/-/issues/3376.
gitlab_rails['backup_upload_remote_directory'] = 'bucket-name/prefix'

# Use multipart uploads when the archive's size exceeds 100MB.
gitlab_rails['backup_multipart_chunk_size'] = 104857600

# Only keep 7 days worth of backups.
gitlab_rails['backup_keep_time'] = 604800

The package's included nginx generates keys and a self-signed certificate for the external URL upon start if the given URL's schema is HTTPS.
The Let's Encrypt account key is in OpenSSL format, while the certificate's key is in OpenSSH format. Both are not password protected.

The certificate used by GitLab's nginx should include the full chain.
The leaf-only certificate works normally, but runners seem to require the full chain to connect properly.

Maintenance
# Check the components' state.
sudo gitlab-ctl status

# Get the services' logs.
sudo gitlab-ctl tail
sudo gitlab-ctl tail 'nginx'

# Restart services.
sudo gitlab-ctl restart
sudo gitlab-ctl restart 'nginx'

# Run checks for the whole system.
sudo gitlab-rake 'gitlab:check'

# Create backups.
sudo gitlab-backup create
sudo gitlab-backup create BACKUP='prefix_override' STRATEGY='copy'

# Skip creating tar files during a backup.
# It is *not* possible to skip the tar creation when using object storage for backups.
sudo gitlab-backup create … SKIP='tar'

# Create empty backup archives for testing purposes.
# See https://docs.gitlab.com/ee/administration/backup_restore/backup_gitlab.html#excluding-specific-data-from-the-backup
sudo gitlab-backup create … \
  SKIP='db,repositories,uploads,builds,artifacts,pages,lfs,terraform_state,registry,packages,ci_secure_files'

# Skip backups during upgrades.
sudo touch '/etc/gitlab/skip-auto-backup'

# Create backups of the configuration.
sudo gitlab-ctl backup-etc
sudo gitlab-ctl backup-etc && ls -t '/etc/gitlab/config_backup/' | head -n '1'

# Restore backups.
sudo aws s3 cp 's3://backups/gitlab/gitlab-secrets.json' '/etc/gitlab/gitlab-secrets.json' \
&& sudo aws s3 cp 's3://backups/gitlab/gitlab.rb' '/etc/gitlab/gitlab.rb' \
&& sudo aws s3 cp \
  's3://backups/gitlab/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar' \
  '/var/opt/gitlab/backups/' \
&& sudo gitlab-ctl stop 'puma' \
&& sudo gitlab-ctl stop 'sidekiq' \
&& sudo GITLAB_ASSUME_YES=1 gitlab-backup restore BACKUP='11493107454_2018_04_25_10.6.4-ce' \
&& sudo gitlab-ctl restart \
&& sudo gitlab-rake 'gitlab:check' SANITIZE=true \
&& sudo gitlab-rake 'gitlab:doctor:secrets' \
&& sudo gitlab-rake 'gitlab:artifacts:check' \
&& sudo gitlab-rake 'gitlab:lfs:check' \
&& sudo gitlab-rake 'gitlab:uploads:check'

# Upgrade the package.
sudo yum check-update
sudo gitlab-backup create
tmux new-session -As 'gitlab-upgrade' "sudo yum update 'gitlab-ee'"

# DB version upgrade
sudo gitlab-ctl pg-upgrade
sudo gitlab-ctl pg-upgrade -V '16'
# Check there is enough disk space for two copies of the database
test $(( $(sudo du -s '/var/opt/gitlab/postgresql/data' | awk '{print $1}') * 2 )) -lt \
  $(sudo df --output='avail' --direct '/var/opt/gitlab/postgresql/data' | tail -n 1) \
&& sudo gitlab-ctl pg-upgrade -V '16'

# Reset the root user's password.
sudo gitlab-rake 'gitlab:password:reset[root]'
sudo gitlab-rails console
  # --> user = User.find_by_username 'root'
  # --> user.password = 'QwerTy184'
  # --> user.password_confirmation = 'QwerTy184'
  # --> user.password_automatically_set = false
  # --> user.save!
  # --> quit
sudo gitlab-rails runner '
  user = User.find_by_username "anUsernameHere";
  new_password = "QwerTy184";
  user.password = new_password;
  user.password_confirmation = new_password;
  user.password_automatically_set = false;
  user.save!
'

# Disable users' two factor authentication.
sudo gitlab-rails runner 'User.where(username: "anUsernameHere").each(&:disable_two_factor!)'

Migration procedure:

  1. Put the old instance in maintenance mode
  2. Take a full backup of the old instance
  3. Copy the configuration and secrets from the old instance to the new one
  4. Change the DNS to the new instance
  5. Reconfigure the new instance
  6. Restore the full backup on the new instance

Check the Upgrade Path tool before upgrading.

Upgrade procedure:

  1. Upgrade to the latest patch version of the current minor first.
  2. Upgrade to the latest patch version of every mandatory step.
  3. Upgrade runners to the nearest minor version of the main instance.
Removal

Refer Uninstall the Linux Package (Omnibus).

# Remove all users and groups created by the package.
sudo gitlab-ctl stop && sudo gitlab-ctl remove-accounts

# Remove all data.
sudo gitlab-ctl cleanse && sudo rm -r '/opt/gitlab'

# Uninstall the package.
sudo apt remove 'gitlab-ce'
sudo dnf remove 'gitlab-ee'

Kubernetes

Helm chart

GitLab offers an official helm chart to to allow for deployments on kubernetes clusters.

Follow the deployment guide for details and updated information.

Deployment
  1. Prepare the environment:

    export \
      ENVIRONMENT='minikube' \
      NAMESPACE='gitlab' \
      VALUES_DIR="$(git rev-parse --show-toplevel)/kubernetes/helm/gitlab"
    
  2. Validate the values and install the chart.

    The installation took > 20m on a MacBook Pro 16-inch 2019 with Intel i7 and 16GB RAM.

    # validation
    helm upgrade --install \
      --namespace "${NAMESPACE}" \
      --values "${VALUES_DIR}/values.${ENVIRONMENT}.yaml" \
      'gitlab' \
      'gitlab/gitlab' \
      --dry-run
    
    # installation
    helm upgrade --install \
      --atomic \
      --create-namespace \
      --namespace "${NAMESPACE}" \
      --timeout 0 \
      --values "${VALUES_DIR}/values.${ENVIRONMENT}.yaml" \
      'gitlab' \
      'gitlab/gitlab' \
      --debug
    
  3. Keep an eye on the installation:

    kubectl get events \
      --namespace "${NAMESPACE}" \
      --sort-by '.metadata.creationTimestamp' \
      --watch
    
    # requires `watch` from 'procps-ng'
    # `brew install watch`
    watch kubectl get all --namespace "${NAMESPACE}"
    
    # requires `k9s`
    # `brew install k9s`
    k9s --namespace "${NAMESPACE}"
    
  4. Get the login password for the root user:

    kubectl get secret 'gitlab-gitlab-initial-root-password' \
      --namespace "${NAMESPACE}" \
      -o jsonpath='{.data.password}' \
    | base64 --decode
    
  5. Open the login page:

    export URL="https://$(kubectl get ingresses --namespace 'gitlab' | grep 'webservice' | awk '{print $2}')"
    
    xdg-open "${URL}"   # on linux
    open "${URL}"       # on mac os x
    
  6. Have fun!

To delete everything:

helm uninstall --namespace "${NAMESPACE}" 'gitlab'
kubectl delete --ignore-not-found namespace "${NAMESPACE}"
Maintenance
  • Add and update GitLab's helm repository:

    helm repo add 'gitlab' 'https://charts.gitlab.io/'
    helm repo update
    
  • Look up the chart's version:

    $ helm search repo 'gitlab/gitlab'
    NAME             CHART VERSION   APP VERSION     DESCRIPTION
    gitlab/gitlab    4.9.3           13.9.3          Web-based Git-repository manager with wiki and ...
    
  • Fetch the chart:

    helm fetch 'gitlab/gitlab' --untar --untardir "$CHART_DIR"
    helm fetch 'gitlab/gitlab' --untar --untardir "$CHART_DIR" --version "$CHART_VERSION"
    
  • Get the default values for the chart:

    helm inspect values 'gitlab/gitlab' > "${VALUES_DIR}/values.yaml"
    helm inspect values --version "$CHART_VERSION" 'gitlab/gitlab' > "${VALUES_DIR}/values-${CHART_VERSION}.yaml"
    
    export VALUES_DIR="$(git rev-parse --show-toplevel)/kubernetes/helm/gitlab"
    helm inspect values 'gitlab/gitlab' > "${VALUES_DIR}/values.yaml"
    
  • Create a dedicated values file with the changes one needs (see the helm chart gotchas below):

    global:
      edition: ce
      ingress:
        configureCertmanager: false
      time_zone: UTC
    certmanager:
      install: false
    gitlab-runner:
      install: false
    
  • Upgrade the stored chart to a new version:

    helm repo update
    rm -r "${CHART_DIR}/gitlab"
    helm fetch 'gitlab/gitlab' --untar --untardir "$CHART_DIR" --version "$CHART_VERSION"
    
Minikube

When testing with a minikube installation with 8GiB RAM, kubernetes complained being out of memory.
Be sure to give your cluster enough resources:

# on linux
minikube start --kubernetes-version "${K8S_VERSION}" --cpus '4' --memory '12GiB'

# on mac os x
minikube start --kubernetes-version "${K8S_VERSION}" --cpus '8' --memory '12GiB'       # docker-desktop (no Ingresses)
minikube start --kubernetes-version "${K8S_VERSION}" --cpus '8' --memory '12GiB' --vm  # hyperkit vm (to be able to use Ingresses)

or consider using the minimal Minikube example values file as reference, as stated in CPU and RAM Resource Requirements

  1. Finish preparing the environment:

    export K8S_VERSION='v1.16.15'
    
  2. Enable the ingress and metrics-server addons:

    minikube addons enable 'ingress'
    minikube addons enable 'metrics-server'
    
  3. When using the LoadBalancer Ingress type (the default), start a tunnel in a different shell to let the installation finish:

    minikube tunnel -c
    
  4. Install the chart as described above.

  5. Add minikube's IP address to the /etc/hosts file:

    kubectl get ingresses --namespace 'gitlab' | grep 'webservice' | awk '{print $3 "  " $2}' | sudo tee -a '/etc/hosts'
    
Gotchas
  • Use self-signed certs and avoid using certmanager setting up the following:

    global:
      ingress:
        configureCertmanager: false
    certmanager:
      install: false
    
  • Avoid using a load balancer (mainly for local testing) setting the ingress type to NodePort:

    nginx-ingress:
      controller:
        service:
          type: NodePort
    
  • As of 2021-01-15, a clean minikube cluster with only gitlab installed takes up about 1 vCPU and 6+ GiB RAM:

    $ kubectl top nodes
    NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
    minikube   965m         12%    6375Mi          53%
    
    $ kubectl get pods --namespace 'gitlab'
    NAMESPACE     NAME                                                   READY   STATUS        RESTARTS   AGE
    gitlab        gitlab-gitaly-0                                        1/1     Running       0          71m
    gitlab        gitlab-gitlab-exporter-547cf7fbff-xzqjp                1/1     Running       0          71m
    gitlab        gitlab-gitlab-shell-5c5b8dd9cd-g4z7b                   1/1     Running       0          71m
    gitlab        gitlab-gitlab-shell-5c5b8dd9cd-ppbtk                   1/1     Running       0          71m
    gitlab        gitlab-migrations-2-j6lt6                              0/1     Completed     0          8m27s
    gitlab        gitlab-minio-6dd7d96ddb-xxq9w                          1/1     Running       0          71m
    gitlab        gitlab-minio-create-buckets-2-q5zfg                    0/1     Completed     0          8m27s
    gitlab        gitlab-nginx-ingress-controller-7fc8cbf49d-b9lqm       1/1     Running       0          71m
    gitlab        gitlab-nginx-ingress-controller-7fc8cbf49d-ng589       1/1     Running       0          71m
    gitlab        gitlab-nginx-ingress-default-backend-7ff88b95f-lv5vt   1/1     Running       0          71m
    gitlab        gitlab-postgresql-0                                    2/2     Running       0          71m
    gitlab        gitlab-prometheus-server-6cfb57f575-cs669              2/2     Running       0          71m
    gitlab        gitlab-redis-master-0                                  2/2     Running       0          71m
    gitlab        gitlab-registry-6c75496fc7-fgbvb                       1/1     Running       0          8m16s
    gitlab        gitlab-registry-6c75496fc7-fhsqs                       1/1     Running       0          8m27s
    gitlab        gitlab-sidekiq-all-in-1-v1-64b9c56675-lf29p            1/1     Running       0          8m27s
    gitlab        gitlab-task-runner-7897bb897d-br5g5                    1/1     Running       0          7m54s
    gitlab        gitlab-webservice-default-7846fb55d6-4pspg             2/2     Running       0          7m37s
    gitlab        gitlab-webservice-default-7846fb55d6-tmjqm             2/2     Running       0          8m27s
    

    with a spike of 5 vCPUs upon installation (specially for sidekiq). Keep this in mind when sizing the test cluster

  • Disable TLS setting up the following values:

    global:
      hosts:
        https: false
      ingress:
        tls:
          enabled: false
    
  • Use a suffix in the ingresses hosts setting up the global.hosts.hostSuffix value:

    $ helm template \
        --namespace "${NAMESPACE}" \
        --values "${VALUES_DIR}/values.${ENVIRONMENT}.yaml" \
        --set global.hosts.hostSuffix='test' \
        'gitlab' \
        'gitlab/gitlab' \
      | yq -r 'select(.kind == "Ingress") | .spec.rules[].host' -
    
    gitlab-test.f.q.dn
    minio-test.f.q.dn
    registry-test.f.q.dn
    

Operator

See the operator guide and the operator code for details.

Create resources in GitLab using Pulumi

Refer Pulumi's GitLab provider installation & configuration and GitLab provider's README.

Before it can be used to create resources, Pulumi's GitLab provider requires:

  • The GitLab instance to be reachable.

  • To be configured with the baseUrl of the correct GitLab instance:

    # The `baseUrl` configuration value *must* end with a slash.
    pulumi config set 'gitlab:baseUrl' 'https://gitlab.example.com/api/v4/'
    
  • To be configured with GitLab administrative credentials.

    A token can be set in the stack's configuration.
    Alternatively, the GITLAB_TOKEN environment variable can be exported before updating the project:

    export GITLAB_TOKEN='glpat-m-Va…zy'
    

Forking

Refer Forks.

Repository management

Different owners for parts of the code base

Refer to Code Owners and CODEOWNERS syntax for more and updated information.

Leverage Code Owners.

Add the CODEOWNERS specifying paths and their relative owner.
Use @ to specify groups and users. Use @@ for roles since GitLab 17.8.

## Default owners
* @@maintainer

## Default owners + users in the 'customer-support' group
/customerSupport/ @@maintainer @customer-support

## Default owners + users in the 'datascience' group
# @lucas is taking care of it for now too
/ds/ @@maintainer @datascience @lucas

Repositories can use a single CODEOWNERS file.
GitLab checks for CODEOWNERS files in each repository in these locations in order; the first one found is the one that is used, all others are ignored:

  • /CODEOWNERS (in the repository's root).
  • /docs/CODEOWNERS.
  • /.gitlab/CODEOWNERS.

Code Owners specified in the file become eligible approvers in the project for MRs that change files in the specified file paths.
Enable the eligible approvers merge request approval rule in the project's Settings > Merge requests.

Require Code Owner approval for protected branches in the project's Settings > Repository > Protected branches.

Gotchas:

  • Specifying owners for paths overwrites the previous owners list.
    There seems to be no way to inherit and add (and not just overwrite) owners that would not require the list being repeated.
  • There is as of 2024-04-10 no way to assign ownership by using aliases for roles (like maintainers or developers); only groups or users are allowed.
    This feature is being added, but it has been open for over 3y now. See Ability to reference Maintainers or Developers from CODEOWNERS.
    Solved in GitLab 17.8, see GitLab 17.8 Release.

Get the version of the helper image to use for a runner

The gitlab/gitlab-runner-helper images are tagged using the runner's os, architecture, and git revision.

One needs to know the version of GitLab and of the runner one wants to use.
Usually, the runner's version is the one most similar to GitLab's version (e.g. GitLab: 13.6.2 → gitlab-runner: 13.6.0).

To get the tag to use for the helper, check the runner's version:

$ docker run --rm --name 'runner' 'gitlab/gitlab-runner:alpine-v13.6.0' --version
Version:      13.6.0
Git revision: 8fa89735
Git branch:   13-6-stable
GO version:   go1.13.8
Built:        2020-11-21T06:16:31+0000
OS/Arch:      linux/amd64

In this case, the os is Linux, the architecture is amd64 and the revision is 8fa89735. So, following their instructions, the tag will be x86_64-8fa89735:

$ docker pull 'gitlab/gitlab-runner-helper:x86_64-8fa89735'
x86_64-8fa89735: Pulling from gitlab/gitlab-runner-helper
a1514ca1e64d: Pull complete
Digest: sha256:4e239257280eb0fa750f1ef30975dacdef5f5346bfaa9e6d60e58d440d8cd0f1
Status: Downloaded newer image for gitlab/gitlab-runner-helper:x86_64-8fa89735
docker.io/gitlab/gitlab-runner-helper:x86_64-8fa89735

Manage kubernetes clusters

See adding and removing kubernetes clusters for more information.

For now the GitLab instance can manage only kubernetes clusters external to the one it is running into.

Maintenance mode

Refer GitLab maintenance mode.

Allows administrators to reduce write operations to a minimum while maintenance tasks are performed.
The main goal is to block all external actions that change the internal state, specially the PostgreSQL database, files, repositories, and the container registry.

When enabled, new actions are forbidden to come in and internal state changes are minimal.
This allows maintenance tasks to execute easier as services can be stopped completely or further degraded for a shorter period of time than might otherwise be needed.

Most external actions that do not change the internal state are allowed. HTTP POST, PUT, PATCH, and DELETE requests are blocked.
See https://docs.gitlab.com/ee/administration/maintenance_mode/#rest-api for a detailed overview of how special cases are handled.

Through Web UI:

  • On the left sidebar, at the bottom, select Admin Area.
  • On the left sidebar, select Settings > General.
  • Expand Maintenance Mode and toggle Enable Maintenance Mode.
    Optionally add a message for the banner.
  • Select Save changes.

Through API calls:

# Enable maintenance mode.
curl -X 'PUT' -H 'PRIVATE-TOKEN: glpat-m-…' 'https://gitlab.fqdn/api/v4/application/settings?maintenance_mode=true'
curl -X 'PUT' -H 'PRIVATE-TOKEN: glpat-m-…' \
  'https://gitlab.fqdn/api/v4/application/settings?maintenance_mode_message=YaBlockedBro'
# Disable maintenance mode.
curl -X 'PUT' -H 'PRIVATE-TOKEN: glpat-m-…' 'https://gitlab.fqdn/api/v4/application/settings?maintenance_mode=false'

Through Rails console:

::Gitlab::CurrentSettings.update!(maintenance_mode: true)
::Gitlab::CurrentSettings.update!(maintenance_mode_message: "New message")
::Gitlab::CurrentSettings.update!(maintenance_mode: false)

Runners

See runners.

CI/CD pipelines

See pipelines.

Artifacts

GitLab allows to configure a instance-wide default expiration for artifacts.
There is currently no way to set up artifacts expiration group-wise or project-wise.

All latest jobs' artifacts are kept by default.
The rest of them expire:

  • As manually configured in the pipeline, or

    default:
      artifacts:
        expire_in: 1 week
    
    someJob:
      artifacts:
        expire_in: 1 month
    
  • As configured instance-wide.

Default artifacts expiration

Job artifacts expiration can be set instance-wide in the Admin area.

If not manually set, it defaults to 30 days.
Set the value to 0 to disable artifacts expiration. The default unit is in seconds.

Path: Admin > Settings > CI/CD > Continuous Integration and Deployment > Default artifacts expiration.
Syntax: artifacts:expire_in.

This setting is set per-job and can be overridden in pipelines.

Any changes to this setting applies to new artifacts only.
The expiration time is not updated retroactively (for artifacts created before this setting was changed).

Keep the latest artifacts for all jobs in the latest successful pipelines

Locks the artifacts of the most recent successful pipeline for each Git ref (branches and tags) against deletion.
Those artifacts are kept regardless of their expiration.

This setting is enabled by default.
When disabled, the latest artifacts for any new successful or fixed pipelines are allowed to expire.

This setting takes precedence over the project's setting.
If disabled for the entire instance, it will not have effect in individual projects.

To disable the setting:

Path: Admin > Settings > CI/CD > Continuous Integration and Deployment > Keep the latest artifacts for all jobs in the latest successful pipelines.

When disabling this feature, the latest artifacts do not immediately expire.
A new pipeline must run before the latest artifacts can expire and be deleted.

Environments

Refer Environments.

Specific deployment targets, e.g. development, staging, or production.
They manage different configurations and code.

One requires the developer or higher role to manage environments.
One must stop an environment before it can be deleted.

Can be either static or dynamic.

Static environments:

  • Have names that do not change nor depend on anything else, e.g. staging or production.
  • Are usually reused in successive deployments.

Dynamic environments:

  • Have names that depend on something, usually based on the value of a CI/CD variable.
  • Are usually created in a CI/CD pipeline.
  • Are usually used only for a single deployment, then are stopped or deleted.

Environment have one of three states, depending on whether its on stop job has run:

  • available: the environment exists; there might be a deployment.
  • stopping: the on stop job has started.
    This state does not apply when there is no on stop job defined.
  • stopped : either the on stop job has run, or a user manually stopped the environment.

One can create static environments in the UI, or in the project's .gitlab-ci.yml file.

GitLab by default automatically stops environments when the associated branch is deleted or merged.
This behavior persists even if no explicit on_stop CI/CD job is defined.

When using the merge request pipelines configuration, the stop trigger is automatically enabled for pipelines.

Environment can be configured to stop automatically after a certain time period by specifying the jobs' environment.auto_stop_in keyword.
When this is the case, the environment.action keyword can be used to reset the time that an environment is scheduled to stop.

Maintainers or higher roles can clean up stale environments in projects by:

  1. Opening the project's page.
  2. Selecting Operate > Environments from the left sidebar.
  3. Selecting Clean up environments on the top right corner.
  4. Selecting a date that will be used to determine which environments to consider stale.
  5. Confirming.

Active environments that have not been updated after the specified date will be stopped.
Protected environments are ignored.

Login via Google, Github or other services

Refer OmniAuth.
See also Password authentication enabled to disable authentication via local user.

Users can sign in a GitLab server by using their credentials from Google, GitHub, and other popular services.

GitLab uses the OmniAuth Rack framework to provide this kind of integration.

When configured, additional sign-in options are displayed on the sign-in page.

When configuring an OmniAuth provider, one should also configure the settings that are common for all providers.
Changes to those values will have no effect until the provider they reference is effectively configured.

Settings of interest
Option Summary
allow_single_sign_on When true, automatically creates GitLab accounts when signing in with OmniAuth.
When false, a GitLab account must be created first.
When an array, limit for what providers to act as it if was true.
auto_link_user Automatically link existing GitLab users to an OmniAuth provider if their emails match when authenticating through the provider.
Does not work with SAML.
block_auto_created_users When true, GitLab puts automatically-created users in a pending approval state until they are approved by an administrator.
In this state, users are unable to sign in.
enabled When true, enable usage of OmniAuth providers.
external_providers Define which OmniAuth providers will not grant access to internal GitLab projects.
providers What providers to enable.
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml', 'google_oauth2']
gitlab_rails['omniauth_block_auto_created_users'] = true
gitlab_rails['omniauth_auto_link_user'] = ['google_oauth2', 'openid_connect']
gitlab_rails['omniauth_allow_bypass_two_factor'] = ['google_oauth2']
gitlab_rails['omniauth_sync_profile_from_provider'] = ['google_oauth2']
gitlab_rails['omniauth_external_providers'] = ['saml']
gitlab_rails['omniauth_providers'] = [{
  name: 'google_oauth2',
  app_id: '012345678901-abcdefghijklmnopqrstuvwxyz012345.apps.googleusercontent.com',
  app_secret: 'GOCSPX-something',
  args: { access_type: 'offline', approval_prompt: '' }
}]

Troubleshooting

Use access tokens to clone projects

git clone "https://oauth2:${ACCESS_TOKEN}@somegitlab.com/vendor/package.git"

GitLab keeps answering with code 502

Refer The docker images for gitlab-ce and gitlab-ee start workhorse with incorrect socket ownership.

Error message example:

==> /var/log/gitlab/nginx/gitlab_error.log <==
2024/05/09 20:57:57 [crit] 617#0: *26 connect() to unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket failed (13: Permission denied) while connecting to upstream, client: 172.21.0.1, server: gitlab.lan, request: "GET / HTTP/2.0", upstream: "http://unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket:/", host: "gitlab.lan:8443"

Context: GitLab 16.11.2 CE running from Docker image.

Root cause: the socket's permissions are mapped incorrectly.

Solution: set the correct ownership with docker exec 'gitlab' chown 'gitlab-www:git' '/var/opt/gitlab/gitlab-workhorse/sockets/socket'.

Further readings

Sources