DEBOPS.DOCKER_REGISTRY(5)

NAME
debops.docker_registry - Manage Docker Registry service using Ansible

SYNOPSIS

debops service/docker_registry [--limit group,host,...] [--diff] [--check] [--tags tag1,tag2,...] [--skip-tags tag1,tag2,...] [<ansible-playbook options>] ...

DESCRIPTION

The debops.docker_registry Ansible role can be used to install and manage a Docker Registry instance. A Docker Registry <https://docs.docker.com/registry/> is a service which allows you to publish and distribute Docker container images. It can be used to create a private, local alternative to a Docker Hub.

By default the role installs the Registry using an OS package on supported OS releases; on older OS releases without the Registry packaged in the repositories the role can download the official upstream release from GitHub and build a Go docker-registry binary automatically.

The role integrates with the debops.gitlab and debops.redis_server Ansible roles to provide backend support for the GitLab Container Registry <https://gitlab.com/help/user/project/container_registry> service. Docker Registry can be installed as standalone service, in which case it will be secured using HTTP Basic Authentication provided by the debops.nginx role.

GETTING STARTED

  Example inventory

To install Docker Registry on a host, you need to add it to the [debops_service_docker_registry] Ansible inventory group:

[debops_all_hosts]
hostname
[debops_service_redis_server]
hostname
[debops_service_docker_registry]
hostname

The support for Redis Server is optional, and not required on the same host.

The debops.docker_registry role is designed to integrate well with the debops.gitlab role, to provide backend support for the GitLab Container Registry service. See the role documentation for more details.

  Example playbook

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

---
- name: Manage Docker Registry
  collections: [ 'debops.debops', 'debops.roles01',
                 'debops.roles02', 'debops.roles03' ]
  hosts: [ 'debops_service_docker_registry' ]
  become: True
  environment: '{{ inventory__environment | d({})
                   | combine(inventory__group_environment | d({}))
                   | combine(inventory__host_environment  | d({})) }}'
  roles:
    - role: keyring
      tags: [ 'role::keyring', 'skip::keyring',
              'role::nginx', 'role::docker_registry' ]
      keyring__dependent_apt_keys:
        - '{{ nginx__keyring__dependent_apt_keys }}'
      keyring__dependent_gpg_keys:
        - '{{ docker_registry__keyring__dependent_gpg_keys }}'
    - role: apt_preferences
      tags: [ 'role::apt_preferences', 'skip::apt_preferences' ]
      apt_preferences__dependent_list:
        - '{{ golang__apt_preferences__dependent_list | d([]) }}'
        - '{{ nginx__apt_preferences__dependent_list }}'
    - role: etc_services
      tags: [ 'role::etc_services', 'skip::etc_services' ]
      etc_services__dependent_list:
        - '{{ docker_registry__etc_services__dependent_list }}'
    - role: python
      tags: [ 'role::python', 'skip::python', 'role::ldap', 'role::docker_registry' ]
      python__dependent_packages3:
        - '{{ ldap__python__dependent_packages3 }}'
        - '{{ docker_registry__python__dependent_packages3 }}'
        - '{{ nginx__python__dependent_packages3 }}'
      python__dependent_packages2:
        - '{{ ldap__python__dependent_packages2 }}'
        - '{{ docker_registry__python__dependent_packages2 }}'
        - '{{ nginx__python__dependent_packages2 }}'
    - role: ldap
      tags: [ 'role::ldap', 'skip::ldap' ]
      ldap__dependent_tasks:
        - '{{ sudo__ldap__dependent_tasks }}'
    - role: sudo
      tags: [ 'role::sudo', 'skip::sudo' ]
    - role: ferm
      tags: [ 'role::ferm', 'skip::ferm' ]
      ferm__dependent_rules:
        - '{{ nginx__ferm__dependent_rules }}'
    - role: nginx
      tags: [ 'role::nginx', 'skip::nginx' ]
      nginx__dependent_maps:
        - '{{ docker_registry__nginx__dependent_maps }}'
      nginx__dependent_upstreams:
        - '{{ docker_registry__nginx__dependent_upstreams }}'
      nginx__dependent_htpasswd:
        - '{{ docker_registry__nginx__dependent_htpasswd }}'
      nginx__dependent_servers:
        - '{{ docker_registry__nginx__dependent_servers }}'
    - role: golang
      tags: [ 'role::golang', 'skip::golang' ]
      when: docker_registry__upstream|bool
    - role: docker_registry
      tags: [ 'role::docker_registry', 'skip::docker_registry' ]

  Authentication

docker_registry__basic_auth_except_get allows an easy yet auditable write access control to the registry. To use it, set the variable to True. Additionally, you need to define the hosts or networks to require authentication for. This is basically a workaround because the Docker Server first does a GET request and if it goes though, it will not provide authentication. But we always allow read only requests without authentication so we need to force authentication like this:

nginx__custom_config:
  - name: 'geo_force_authentication'
    custom: |
      ## This is not security related. It just triggers Docker that it may authenticate itself.
      geo $force_authentication {
        default 0;
        2001:db8:2342::/64 1;
      }

Then define the users which should be created and allowed write access:

docker_registry__basic_auth_users:
  - 'build-docker-debian-base-image'

Refer to debops.secret for details.

You can then use docker login docker-registry.example.net to login. This step is manually for now.

  Ansible tags

You can use Ansible --tags or --skip-tags parameters to limit what tasks are performed during Ansible run. This can be used after a host was first configured to speed up playbook execution, when you are sure that most of the configuration is already in the desired state.

Available role tags:

role::docker_registry
    Main role tag, should be used in the playbook to execute all of the role tasks as well as role dependencies.

  Other resources

List of other useful resources related to the debops.docker_registry Ansible role:

•   Docker Registry configuration <https://docs.docker.com/registry/configuration/> documentation

•   GitLab Container Registry <https://gitlab.com/help/user/project/container_registry> documentation

DEFAULT VARIABLE DETAILS

Some of debops.docker_registry default variables have more extensive configuration than simple strings or lists, here you can find documentation and examples for them.

  docker_registry__config

The docker_registry__*_config variables contain configuration for the Docker Registry service. The Docker Registry uses a YAML configuration file with multiple level of configuration keys. To allow for better control over the configuration file contents, the role uses a list of YAML dictionaries with named entries which are recursively merged during configuration file generation.

  Examples

Switch the Docker Registry to an Amazon Simple Storage Service (S3) backend, based on the example configuration <https://docs.docker.com/registry/storage-drivers/s3/>:

docker_registry__config:
  # Disable default local filesystem storage
  - name: 'default-storage'
    state: 'absent'
  - name: 'storage-s3'
    config:
      storage:
        s3:
          region: 'us-east-1'
          bucket: 'registry.example.org'
      middleware:
        storage:
          - name: 'cloudfront'
            options:
              baseurl: 'https://example.cloudfront.net/'
              privatekey: '/etc/docker/cloudfront/pk-example.pem'
              keypairid: 'example'

You should also see the docker_registry__original_config and docker_registry__default_config variables for useful configuration examples.

  Syntax

Each entry in the list is a YAML dictionary with specific parameters:

name
    Required. An identifier of this configuration entry, not used otherwise. Configuration entries with the same identifier are merged together, entries later on the list can affect the earlier ones.

config
    Required. An YAML dictionary with Docker Registry configuration options. Each config dictionary will be merged recursively in the final configuration file. You have to specify the entire dictionary structure from the "base" of the configuration file. Refer to the Docker Registry documentation <https://docs.docker.com/registry/configuration/> for details about supported parameters and their values.

state
    Optional. If not specified or present, a given configuration entry will be included in the final configuration file. If absent, the entry will not be included in the final configuration file - this can be used to disable configuration entries with specific identifiers. If ignore, a given configuration entry will not be evaluated by the role.

AUTHOR
Maciej Delmanowski

COPYRIGHT
2014-2022, Maciej Delmanowski, Nick Janetakis, Robin Schneider and others