Getting started

Role design

The debops.gitlab role is designed to install the GitLab services using the source installation method. This method, instead of GitLab Omnibus packages, was chosen to allow use of other services managed by DebOps, like Redis, nginx, a SQL database, and so on. To support monthly GitLab releases, the role tracks currently installed version of GitLab and can perform an automatic upgrade when an older version is detected. Latest changes to the active GitLab branch are also automatically applied on Ansible runs, to support updates.

The installation or upgrade process is not ideal - role performs installation or an upgrade when new changes are detected in the git repositories, but if there are errors during this process, role cannot recover from that state automatically. It is advisable to keep a separate staging environment to check for any issues with an upgrade of the currently installed production environment before performing the production upgrade.

If a failed install or upgrade occurs, the easiest recovery method is usually to completely reset the affected host (perform a new deployment) after fixing the issue. The more involved method would be to remove the source git repositories and checked out directories and re-run the role again.

SQL database support

The debops.gitlab role automatically detects the available PostgreSQL database using the Ansible local facts. If the database service should be present on the same host as the GitLab service, adding the corresponding database server group in the Ansible inventory should be enough. If the database server is on a different host, you should use the corresponding database client role to configure the relevant Ansible local facts before running the debops.gitlab role.

Installation of a new GitLab environment with existing database is currently not tested and may result in a broken installation or data corruption.

You can install the PostgreSQL database using its DebOps role. See the debops.postgresql_server role documentation for more details.

Redis support

Currently the debops.gitlab role expects a Redis Server instance installed on the host, for example by the debops.redis_server Ansible role. Support for distributed Redis Server service managed by Redis Sentinel is planned for a future release.

Docker Registry support

The debops.docker_registry Ansible role can be used as a backend to the GitLab Container Registry service. The debops.gitlab playbook will import the debops.docker_registry playbook to facilitate configuration synchronization between the two services. The installation process with Docker Registry role enabled will be:

  • Install PostgreSQL server, Redis Server
  • Install Docker Registry service
  • Install GitLab, using facts from Docker Registry role
  • Update Docker Registry service with facts from GitLab role

This should avoid issue with circular dependencies in the configuration of both services. The Docker Registry requires PKI support, therefore it's good practice to apply the common.yml DebOps playbook, or at least the debops.pki role, before the GitLab installation begins.

Support for other services

The debops.gitlab role depends on other DebOps roles to configure various services used by GitLab and provide the required environment for installation. The default role playbook is designed to install the services on the same host as the GitLab service, however it should be possible to move them to other, remote hosts if necessary.

The role provides its own set of systemd unit files that allow management of different GitLab services as one "unit" using systemd slice. The new units will be enabled automatically on all new installations on hosts that use the systemd service manager; on other, older hosts the role should fallback to the init script provided by the upstream.

Example inventory

To enable GitLab service on a host, it needs to be included in the [debops_service_gitlab] Ansible inventory group. You should also enable a suitable PostgreSQL database and Redis Server service.

Example Ansible inventory:






Example playbook

If you are using this role without DebOps, here's an example Ansible playbook that uses the debops.gitlab role:


- name: Manage GitLab service
  collections: [ 'debops.debops', 'debops.roles01',
                 'debops.roles02', 'debops.roles03' ]
  hosts: [ 'debops_service_gitlab' ]
  become: True

  environment: '{{ inventory__environment | d({})
                   | combine(inventory__group_environment | d({}))
                   | combine(inventory__host_environment  | d({})) }}'


    - name: Prepare gitlab environment
        name: 'gitlab'
        tasks_from: 'main_env'
      tags: [ 'role::gitlab', 'role::postgresql' ]


    - role: keyring
      tags: [ 'role::keyring', 'skip::keyring',
              'role::nodejs', 'role::postgresql', 'role::nginx' ]
        - '{{ nodejs__keyring__dependent_apt_keys }}'
        - '{{ postgresql__keyring__dependent_apt_keys }}'
        - '{{ nginx__keyring__dependent_apt_keys }}'

    - role: system_groups
      tags: [ 'role::system_groups', 'skip::system_groups' ]

    - role: apt_preferences
      tags: [ 'role::apt_preferences', 'skip::apt_preferences' ]
        - '{{ golang__apt_preferences__dependent_list }}'
        - '{{ nginx__apt_preferences__dependent_list }}'
        - '{{ nodejs__apt_preferences__dependent_list }}'
        - '{{ postgresql__apt_preferences__dependent_list }}'
        - '{{ ruby__apt_preferences__dependent_list }}'
        - '{{ gitlab__apt_preferences__dependent_list }}'

    - role: python
      tags: [ 'role::python', 'skip::python', 'role::mariadb', 'role::postgresql', 'role::ldap' ]
        - '{{ gitlab__python__dependent_packages3 }}'
        - '{{ nginx__python__dependent_packages3 }}'
        - '{{ postgresql__python__dependent_packages3 if gitlab__database == "postgresql" else [] }}'
        - '{{ ldap__python__dependent_packages3 }}'
        - '{{ gitlab__python__dependent_packages2 }}'
        - '{{ nginx__python__dependent_packages2 }}'
        - '{{ postgresql__python__dependent_packages2 if gitlab__database == "postgresql" else [] }}'
        - '{{ ldap__python__dependent_packages2 }}'

    - role: golang
      tags: [ 'role::golang', 'skip::golang' ]

    - role: nodejs
      tags: [ 'role::nodejs', 'skip::nodejs' ]

    - role: etc_services
      tags: [ 'role::etc_services', 'skip::etc_services' ]
        - '{{ gitlab__etc_services__dependent_list }}'

    - role: cron
      tags: [ 'role::cron', 'skip::cron' ]

    - role: logrotate
      tags: [ 'role::logrotate', 'skip::logrotate' ]
        - '{{ gitlab__logrotate__dependent_config }}'

    - role: ferm
      tags: [ 'role::ferm', 'skip::ferm' ]
        - '{{ nginx__ferm__dependent_rules }}'

    - role: ruby
      tags: [ 'role::ruby', 'skip::ruby' ]
      ruby__dev_support: True

    - role: postgresql
      tags: [ 'role::postgresql', 'skip::postgresql' ]
        - '{{ gitlab__postgresql__dependent_roles }}'
        - '{{ gitlab__postgresql__dependent_groups }}'
        - '{{ gitlab__postgresql__dependent_databases }}'
        - '{{ gitlab__postgresql__dependent_extensions }}'
        - '{{ gitlab__postgresql__dependent_pgpass }}'
      when: gitlab__database == 'postgresql'

    - role: ldap
      tags: [ 'role::ldap', 'skip::ldap' ]
        - '{{ gitlab__ldap__dependent_tasks }}'

    - role: nginx
      tags: [ 'role::nginx', 'skip::nginx' ]
        - '{{ gitlab__nginx__dependent_servers }}'
        - '{{ gitlab__nginx__dependent_upstreams }}'

    - role: gitlab
      tags: [ 'role::gitlab', 'skip::gitlab' ]

# Import the 'debops.docker_registry' playbook to apply configuration of the
# Docker Registry that is defined by the 'debops.gitlab' role. This has an
# effect only when the 'debops.docker_registry' role is enabled on the host via
# its corresponding Ansible inventory group.
- import_playbook: 'docker_registry.yml'