# Using Docker images

> 原文：[https://docs.gitlab.com/ee/ci/docker/using_docker_images.html](https://docs.gitlab.com/ee/ci/docker/using_docker_images.html)

*   [Register Docker Runner](#register-docker-runner)
*   [What is an image](#what-is-an-image)
*   [What is a service](#what-is-a-service)
    *   [How services are linked to the job](#how-services-are-linked-to-the-job)
    *   [How the health check of services works](#how-the-health-check-of-services-works)
    *   [What services are not for](#what-services-are-not-for)
    *   [Accessing the services](#accessing-the-services)
*   [Define `image` and `services` from `.gitlab-ci.yml`](#define-image-and-services-from-gitlab-ciyml)
*   [Passing environment variables to services](#passing-environment-variables-to-services)
*   [Extended Docker configuration options](#extended-docker-configuration-options)
    *   [Available settings for `image`](#available-settings-for-image)
    *   [Available settings for `services`](#available-settings-for-services)
    *   [Starting multiple services from the same image](#starting-multiple-services-from-the-same-image)
    *   [Setting a command for the service](#setting-a-command-for-the-service)
    *   [Overriding the entrypoint of an image](#overriding-the-entrypoint-of-an-image)
*   [Define image and services in `config.toml`](#define-image-and-services-in-configtoml)
*   [Define an image from a private Container Registry](#define-an-image-from-a-private-container-registry)
    *   [Requirements and limitations](#requirements-and-limitations)
    *   [Using statically-defined credentials](#using-statically-defined-credentials)
        *   [Determining your `DOCKER_AUTH_CONFIG` data](#determining-your-docker_auth_config-data)
        *   [Configuring a job](#configuring-a-job)
    *   [Configuring a Runner](#configuring-a-runner)
    *   [Using Credentials Store](#using-credentials-store)
    *   [Using Credential Helpers](#using-credential-helpers)
*   [Configuring services](#configuring-services)
    *   [PostgreSQL service example](#postgresql-service-example)
    *   [MySQL service example](#mysql-service-example)
*   [How Docker integration works](#how-docker-integration-works)
*   [How to debug a job locally](#how-to-debug-a-job-locally)

# Using Docker images[](#using-docker-images "Permalink")

GitLab CI / CD 与[GitLab Runner](../runners/README.html)一起可以使用[Docker Engine](https://www.docker.com/)测试和构建任何应用程序.

Docker 是一个开源项目，它允许您使用预定义的映像在单个 Linux 实例中运行的独立"容器"中运行应用程序. [Docker Hub](https://hub.docker.com/)具有丰富的预构建映像数据库，可用于测试和构建您的应用程序.

与 GitLab CI / CD 一起使用时，Docker 使用[`.gitlab-ci.yml`](../yaml/README.html)设置的预定义映像在单独的隔离容器中运行每个作业.

这使得拥有可以在您的工作站上运行的简单且可复制的构建环境更加容易. 额外的好处是您可以测试稍后将在您的 Shell 中探索的所有命令，而不必在专用的 CI 服务器上对其进行测试.

## Register Docker Runner[](#register-docker-runner "Permalink")

要将 GitLab Runner 与 Docker 一起使用，您需要[注册一个新的 Runner](https://docs.gitlab.com/runner/register/)以使用`docker` executor.

An example can be seen below. First we set up a temporary template to supply the services:

```
cat > /tmp/test-config.template.toml << EOF [[runners]]
[runners.docker]
[[runners.docker.services]]
name = "postgres:latest"
[[runners.docker.services]]
name = "mysql:latest" EOF 
```

然后，我们使用刚刚创建的模板注册跑步者：

```
sudo gitlab-runner register \
  --url "https://gitlab.example.com/" \
  --registration-token "PROJECT_REGISTRATION_TOKEN" \
  --description "docker-ruby:2.6" \
  --executor "docker" \
  --template-config /tmp/test-config.template.toml \
  --docker-image ruby:2.6 
```

注册的运行器将使用`ruby:2.6` Docker 映像，并将运行两个服务`postgres:latest`和`mysql:latest` ，在构建过程中均可访问这两个服务.

## What is an image[](#what-is-an-image "Permalink")

`image`关键字是 Docker 执行程序将运行以执行 CI 任务的 Docker 映像的名称.

默认情况下，执行程序仅从[Docker Hub](https://hub.docker.com/)提取图像，但是可以通过设置[Docker 提取策略](https://docs.gitlab.com/runner/executors/docker.html)以允许使用本地映像在`gitlab-runner/config.toml`进行配置.

有关映像和 Docker Hub 的更多信息，请阅读[Docker Fundamentals](https://s0docs0docker0com.icopy.site/engine/understanding-docker/)文档.

## What is a service[](#what-is-a-service "Permalink")

`services`关键字仅定义在您的工作期间运行的另一个 Docker 映像，并链接到`image`关键字定义的 Docker 映像. 这样，您就可以在构建期间访问服务映像.

服务映像可以运行任何应用程序，但是最常见的用例是运行数据库容器，例如`mysql` . 与每次安装项目时都安装`mysql`相比，使用现有映像并将其作为附加容器运行更容易，更快捷.

您不仅限于仅具有数据库服务. 您可以将所需的服务添加到`.gitlab-ci.yml`或手动修改`config.toml` . 在[Docker Hub](https://hub.docker.com/)或您的私有 Container Registry 中找到的任何映像都可以用作服务.

服务继承与 CI 容器本身相同的 DNS 服务器，搜索域和其他主机.

您可以在[CI 服务示例](../services/README.html)的相关文档中看到一些广泛使用的[服务示例](../services/README.html) .

### How services are linked to the job[](#how-services-are-linked-to-the-job "Permalink")

为了更好地了解容器链接的工作方式，请阅读[将容器链接在一起](https://s0docs0docker0com.icopy.site/engine/userguide/networking/default_network/dockerlinks/) .

总而言之，如果将`mysql`作为服务添加到应用程序，则该映像将用于创建链接到作业容器的容器.

The service container for MySQL will be accessible under the hostname `mysql`. So, in order to access your database service you have to connect to the host named `mysql` instead of a socket or `localhost`. Read more in [accessing the services](#accessing-the-services).

### How the health check of services works[](#how-the-health-check-of-services-works "Permalink")

服务旨在提供可通过**网络访问的**附加功能. 它可能是一个数据库，例如 MySQL 或 Redis，甚至是`docker:stable-dind` ，它允许您在 Docker 中使用 Docker. CI / CD 作业继续进行并可以通过网络进行访问几乎是任何事情.

为确保此方法有效，跑步者：

1.  检查默认情况下哪些端口从容器中暴露出来.
2.  启动一个特殊的容器，等待这些端口可访问.

当检查的第二阶段失败时（由于服务中没有打开的端口，或者由于在超时之前服务未正确启动且端口没有响应），它会显示警告： `*** WARNING: Service XYZ probably didn't start properly` .

在大多数情况下，它将影响作业，但是在某些情况下，即使打印了该警告，作业仍将成功. 例如：

*   发出警告后不久，该服务已启动，并且该作业从一开始就没有使用链接的服务. 在那种情况下，当作业需要访问服务时，它可能已经在那里等待连接.
*   服务容器不提供任何网络服务，但是它正在使用作业的目录（所有服务都将作业目录作为卷挂载在`/builds` ）. 在这种情况下，服务将完成其工作，并且由于该工作未尝试与其连接，因此它不会失败.

### What services are not for[](#what-services-are-not-for "Permalink")

如前所述，此功能旨在提供**网络可访问的**服务. 数据库是此类服务的最简单示例.

**注意：**服务功能并非旨在且不会将已定义的`services`映像中的任何软件添加到作业的容器中.

例如，如果您在作业中定义了以下`services` ，则脚本**无法**使用`php` ， `node`或`go`命令，因此该作业将失败：

```
job:
  services:
    - php:7
    - node:latest
    - golang:1.10
  image: alpine:3.7
  script:
    - php -v
    - node -v
    - go version 
```

如果你需要有`php` ， `node`和`go`供你的脚本，你应该：

*   选择一个包含所有必需工具的现有 Docker 映像.
*   创建您自己的 Docker 映像，它将包含所有必需的工具，并在您的工作中使用它.

### Accessing the services[](#accessing-the-services "Permalink")

假设您需要一个 Wordpress 实例来测试与应用程序的某些 API 集成.

然后，您可以在`.gitlab-ci.yml`使用例如[tutum / wordpress](https://hub.docker.com/r/tutum/wordpress/)图像：

```
services:
  - tutum/wordpress:latest 
```

如果未[指定服务别名](#available-settings-for-services) ，则在运行作业时，将启动`tutum/wordpress` ，您将可以从构建容器中使用以下两个主机名访问它：

*   `tutum-wordpress`
*   `tutum__wordpress`

**注意：**带下划线的主机名是 RFC 无效的，可能会导致第三方应用程序出现问题.

服务主机名的默认别名是根据以下规则从其映像名称创建的：

*   冒号后一切（ `:` ）被剥离.
*   将斜杠（ `/` ）替换为双下划线（ `__` ），并创建主别名.
*   斜杠（ `/` ）替换为单破折号（ `-` ），并创建了辅助别名（需要 GitLab Runner v1.1.0 或更高版本）.

要覆盖默认行为，可以[指定服务别名](#available-settings-for-services) .

## Define `image` and `services` from `.gitlab-ci.yml`[](#define-image-and-services-from-gitlab-ciyml "Permalink")

您可以简单地定义将用于所有作业的映像以及要在构建期间使用的服务列表：

```
default:
  image: ruby:2.6

  services:
    - postgres:11.7

  before_script:
    - bundle install

test:
  script:
    - bundle exec rake spec 
```

图像名称必须采用以下格式之一：

*   `image: <image-name>` （同使用`<image-name>`与`latest`标签）
*   `image: <image-name>:<tag>`
*   `image: <image-name>@<digest>`

还可以为每个作业定义不同的图像和服务：

```
default:
  before_script:
    - bundle install

test:2.6:
  image: ruby:2.6
  services:
    - postgres:11.7
  script:
    - bundle exec rake spec

test:2.7:
  image: ruby:2.7
  services:
    - postgres:12.2
  script:
    - bundle exec rake spec 
```

或者，您可以传递一些[扩展](#extended-docker-configuration-options)的`image`和`services` [配置选项](#extended-docker-configuration-options) ：

```
default:
  image:
    name: ruby:2.6
    entrypoint: ["/bin/bash"]

  services:
    - name: my-postgres:11.7
      alias: db-postgres
      entrypoint: ["/usr/local/bin/db-postgres"]
      command: ["start"]

  before_script:
    - bundle install

test:
  script:
    - bundle exec rake spec 
```

## Passing environment variables to services[](#passing-environment-variables-to-services "Permalink")

您还可以传递自定义环境[变量，](../variables/README.html)以直接在`.gitlab-ci.yml`文件中微调 Docker `images`和`services` . 有关更多信息，请参见[自定义环境变量.](../variables/README.html#gitlab-ciyml-defined-variables)

```
# The following variables will automatically be passed down to the Postgres container
# as well as the Ruby container and available within each.
variables:
  HTTPS_PROXY: "https://10.1.1.1:8090"
  HTTP_PROXY: "https://10.1.1.1:8090"
  POSTGRES_DB: "my_custom_db"
  POSTGRES_USER: "postgres"
  POSTGRES_PASSWORD: "example"
  PGDATA: "/var/lib/postgresql/data"
  POSTGRES_INITDB_ARGS: "--encoding=UTF8  --data-checksums"

services:
  - name: postgres:11.7
    alias: db
    entrypoint: ["docker-entrypoint.sh"]
    command: ["postgres"]

image:
  name: ruby:2.6
  entrypoint: ["/bin/bash"]

before_script:
  - bundle install

test:
  script:
    - bundle exec rake spec 
```

## Extended Docker configuration options[](#extended-docker-configuration-options "Permalink")

在 GitLab 和 GitLab Runner 9.4 中引入.

配置`image`或`services`条目时，可以使用字符串或地图作为选项：

*   使用字符串作为选项时，它必须是要使用的映像的全名（如果要从 Docker Hub 以外的注册表中下载映像，则应包括注册表部分）
*   使用地图作为选项时，它必须至少包含`name`选项，该名称与用于字符串设置的图像名称相同

例如，以下两个定义相等：

1.  使用字符串作为`image`和`services`的选项：

    ```
    image: "registry.example.com/my/image:latest"

    services:
      - postgresql:9.4
      - redis:latest 
    ```

2.  使用地图作为`image`和`services`的选项. 必须使用`image:name` ：

    ```
    image:
      name: "registry.example.com/my/image:latest"

    services:
      - name: postgresql:9.4
      - name: redis:latest 
    ```

### Available settings for `image`[](#available-settings-for-image "Permalink")

在 GitLab 和 GitLab Runner 9.4 中引入.

| Setting | Required | GitLab 版本 | Description |
| --- | --- | --- | --- |
| `name` | 是的，当与任何其他选项一起使用时 | 9.4 | 应使用的图像的全名. 如果需要，它应包含注册表部分. |
| `entrypoint` | no | 9.4 | 应该作为容器的入口点执行的命令或脚本. 创建容器时，它将转换为 Docker 的`--entrypoint`选项. 语法类似于[`Dockerfile`的`ENTRYPOINT`](https://s0docs0docker0com.icopy.site/engine/reference/builder/)指令，其中每个 shell 令牌是数组中的单独字符串. |

### Available settings for `services`[](#available-settings-for-services "Permalink")

在 GitLab 和 GitLab Runner 9.4 中引入.

| Setting | Required | GitLab 版本 | Description |
| --- | --- | --- | --- |
| `name` | 是的，当与任何其他选项一起使用时 | 9.4 | Full name of the image that should be used. It should contain the Registry part if needed. |
| `entrypoint` | no | 9.4 | 应该作为容器的入口点执行的命令或脚本. 创建容器时，它将转换为 Docker 的`--entrypoint`选项. 语法类似于[`Dockerfile`的`ENTRYPOINT`](https://s0docs0docker0com.icopy.site/engine/reference/builder/)指令，其中每个 shell 令牌是数组中的单独字符串. |
| `command` | no | 9.4 | 应该用作容器命令的命令或脚本. 它将转换为映像名称后传递给 Docker 的参数. 语法类似于[`Dockerfile`的`CMD`](https://s0docs0docker0com.icopy.site/engine/reference/builder/)指令，其中每个 shell 令牌是数组中的单独字符串. |
| `alias` | no | 9.4 | 可用于从作业的容器访问服务的其他别名. 请阅读[访问服务](#accessing-the-services)以获取更多信息. |

**注意：** GitLab Runner 12.8 [引入](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2229)了对 Kubernetes 执行器的别名支持，并且仅对 Kubernetes 1.7 或更高版本可用.

### Starting multiple services from the same image[](#starting-multiple-services-from-the-same-image "Permalink")

在 GitLab 和 GitLab Runner 9.4 中引入. 阅读有关[扩展配置选项的](#extended-docker-configuration-options)更多信息.

在使用新的扩展 Docker 配置选项之前，以下配置将无法正常工作：

```
services:
  - mysql:latest
  - mysql:latest 
```

The Runner would start two containers using the `mysql:latest` image, but both of them would be added to the job’s container with the `mysql` alias based on the [default hostname naming](#accessing-the-services). This would end with one of the services not being accessible.

在新的扩展 Docker 配置选项之后，以上示例将如下所示：

```
services:
  - name: mysql:latest
    alias: mysql-1
  - name: mysql:latest
    alias: mysql-2 
```

Runner 仍将使用`mysql:latest`映像启动两个容器，但是现在每个容器也可以使用`.gitlab-ci.yml`文件中配置的别名进行访问.

### Setting a command for the service[](#setting-a-command-for-the-service "Permalink")

在 GitLab 和 GitLab Runner 9.4 中引入. 阅读有关[扩展配置选项的](#extended-docker-configuration-options)更多信息.

假设您有一个`super/sql:latest`映像，其中包含一些 SQL 数据库，并且想将其用作您的工作服务. 我们还假设该映像在启动容器时不会启动数据库进程，并且用户需要手动使用`/usr/bin/super-sql run`作为命令来启动数据库.

在使用新的扩展 Docker 配置选项之前，您需要基于`super/sql:latest`映像创建自己的映像，添加默认命令，然后在作业的配置中使用它，例如：

```
# my-super-sql:latest image's Dockerfile

FROM super/sql:latest
CMD ["/usr/bin/super-sql", "run"] 
```

```
# .gitlab-ci.yml

services:
  - my-super-sql:latest 
```

在新的扩展 Docker 配置选项之后，您现在可以简单地在`.gitlab-ci.yml`设置`command` ，例如：

```
# .gitlab-ci.yml

services:
  - name: super/sql:latest
    command: ["/usr/bin/super-sql", "run"] 
```

如您所见， `command`的语法类似于[Dockerfile 的`CMD`](https://s0docs0docker0com.icopy.site/engine/reference/builder/) .

### Overriding the entrypoint of an image[](#overriding-the-entrypoint-of-an-image "Permalink")

在 GitLab 和 GitLab Runner 9.4 中引入. 阅读有关[扩展配置选项的](#extended-docker-configuration-options)更多信息.

在显示可用的入口点覆盖方法之前，让我们简要介绍一下 Runner 如何启动以及如何将 Docker 映像用于 CI 作业中使用的容器：

1.  Runner 使用定义的入口点启动 Docker 容器（ `Dockerfile`中的默认值，该文件可能会在`.gitlab-ci.yml`覆盖）
2.  跑步者将自己附加到正在运行的容器上.
3.  跑步者准备一个脚本（ [`before_script`](../yaml/README.html#before_script-and-after_script) ， [`script`](../yaml/README.html#script)和[`after_script`](../yaml/README.html#before_script-and-after_script)的组合）.
4.  运行程序将脚本发送到容器的外壳 STDIN 并接收输出.

要覆盖 Docker 映像的入口点，建议的解决方案是在`.gitlab-ci.yml`定义一个空`entrypoint` `.gitlab-ci.yml` ，以便 Runner 不会启动无用的 shell 层. 但是，这不适用于所有 Docker 版本，因此您应检查 Runner 使用的是哪个版本. 特别：

*   如果使用 Docker 17.06 或更高版本，则`entrypoint`可以设置为空值.
*   如果使用 Docker 17.03 或更早版本，则`entrypoint`可以设置为`/bin/sh -c` ， `/bin/bash -c`或映像中可用的等效 shell.

`image:entrypoint`的语法类似于[Dockerfile 的`ENTRYPOINT`](https://s0docs0docker0com.icopy.site/engine/reference/builder/) .

假设您有一个`super/sql:experimental`映像，其中包含一些 SQL 数据库，并且您想将其用作工作的基础映像，因为您想使用此数据库二进制文件执行一些测试. 我们还假设此映像是使用`/usr/bin/super-sql run`作为入口点配置的. 这意味着在启动没有其他选项的容器时，它将运行数据库的进程，而 Runner 希望映像没有入口点，或者入口点已准备好启动 Shell 命令.

使用扩展的 Docker 配置选项，而不是基于`super/sql:experimental`创建自己的映像，将`ENTRYPOINT`设置为 shell，然后在 CI 作业中使用新映像，您现在只需在`.gitlab-ci.yml`定义一个`entrypoint` `.gitlab-ci.yml` .

**对于 Docker 17.06+：**

```
image:
  name: super/sql:experimental
  entrypoint: [""] 
```

**对于 Docker = <17.03：**

```
image:
  name: super/sql:experimental
  entrypoint: ["/bin/sh", "-c"] 
```

## Define image and services in `config.toml`[](#define-image-and-services-in-configtoml "Permalink")

查找`[runners.docker]`部分：

```
[runners.docker]
  image = "ruby:latest"
  services = ["mysql:latest", "postgres:latest"] 
```

以这种方式定义的图像和服务将添加到该运行程序运行的所有作业中.

## Define an image from a private Container Registry[](#define-an-image-from-a-private-container-registry "Permalink")

要访问私有容器注册表，GitLab Runner 进程可以使用：

*   [静态定义的凭证](#using-statically-defined-credentials) . 也就是说，特定注册表的用户名和密码.
*   [凭证存储](#using-credentials-store) . 有关更多信息，请参阅[相关的 Docker 文档](https://docs.docker.com/engine/reference/commandline/login/#credentials-store) .
*   [凭证助手](#using-credential-helpers) . 有关更多信息，请参阅[相关的 Docker 文档](https://docs.docker.com/engine/reference/commandline/login/#credential-helpers) .

为了定义应该使用哪个，GitLab Runner 进程按以下顺序读取配置：

*   `DOCKER_AUTH_CONFIG`变量提供为：
    *   `.gitlab-ci.yml` [变量](../variables/README.html#gitlab-cicd-environment-variables) .
    *   项目的变量存储在项目的**"设置">" CI / CD"**页面上.
*   Runner 的`config.toml`中提供了`DOCKER_AUTH_CONFIG`变量作为环境变量.
*   `config.json`文件放置在运行 GitLab Runner 进程的用户的`$HOME/.docker`目录中. 如果提供了`--user`标志以非特权用户身份运行 GitLab Runner 子进程，则将使用 GitLab Runner 主进程用户的主目录.

**注意：** GitLab Runner **仅从** `config.toml`读取此配置，并且如果它是作为环境变量提供的，则忽略它. 这是因为 GitLab Runner **仅**使用`config.toml`配置，并且不会在运行时内插**任何**环境变量.

### Requirements and limitations[](#requirements-and-limitations "Permalink")

*   此功能需要 GitLab Runner **1.8**或更高版本.
*   对于**> = 0.6，<1.8 的** GitLab Runner 版本**，**部分支持使用私有注册表，这要求在运行者的主机上手动配置凭据. 如果要使用私人注册表，建议将 Runner 至少升级到**1.8**版.
*   在 GitLab Runner 13.1 和更高版本中适用于[Kubernetes 执行器](https://docs.gitlab.com/runner/executors/kubernetes.html) .

### Using statically-defined credentials[](#using-statically-defined-credentials "Permalink")

您可以采用两种方法来访问私有注册表. 两者都需要使用适当的身份验证信息设置环境变量`DOCKER_AUTH_CONFIG` .

1.  每个作业：要配置一个作业以访问专用注册表，请添加`DOCKER_AUTH_CONFIG`作为作业变量.
2.  每个运行者：要配置 Runner 以便其所有作业都可以访问私有注册表，请在 Runner 的配置中将`DOCKER_AUTH_CONFIG`添加到环境中.

请参阅下面的示例.

#### Determining your `DOCKER_AUTH_CONFIG` data[](#determining-your-docker_auth_config-data "Permalink")

例如，假设您要使用`registry.example.com:5000/private/image:latest`映像，该映像是私有映像，需要您登录到私有容器注册表.

我们还假设这些是登录凭据：

| Key | Value |
| --- | --- |
| registry | `registry.example.com:5000` |
| username | `my_username` |
| password | `my_password` |

有两种方法可以确定`DOCKER_AUTH_CONFIG`的值：

*   **第一种方法-**在本地计算机上进行`docker login` ：

    ```
    docker login registry.example.com:5000 --username my_username --password my_password 
    ```

    然后复制`~/.docker/config.json` .

    如果您不需要从计算机访问注册表，则可以执行`docker logout` ：

    ```
    docker logout registry.example.com:5000 
    ```

*   **第二种方式-**在某些设置中，Docker 客户端可能会使用可用的系统密钥存储区来存储`docker login`的结果. 在这种情况下，无法读取`~/.docker/config.json` ，因此您将需要准备所需的`${username}:${password}` base64 编码版本，并手动创建 Docker 配置 JSON. 打开一个终端并执行以下命令：

    ```
    # Note the use of "-n" - it prevents encoding a newline in the password.
    echo -n "my_username:my_password" | base64

    # Example output to copy
    bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ= 
    ```

    创建 Docker JSON 配置内容，如下所示：

    ```
    {  "auths":  {  "registry.example.com:5000":  {  "auth":  "(Base64 content from above)"  }  }  } 
    ```

#### Configuring a job[](#configuring-a-job "Permalink")

要配置具有对`registry.example.com:5000`访问权限的单个作业，请按照下列步骤操作：

1.  创建一个[变量](../variables/README.html#gitlab-cicd-environment-variables) `DOCKER_AUTH_CONFIG` ，并将 Docker 配置文件的内容作为值：

    ```
    {  "auths":  {  "registry.example.com:5000":  {  "auth":  "bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ="  }  }  } 
    ```

2.  现在，您可以使用`.gitlab-ci.yml`文件中`image`和/或`services`中定义的`registry.example.com:5000`任何私有图像：

    ```
    image: registry.example.com:5000/namespace/image:tag 
    ```

    在上面的例子，GitLab 转轮会看`registry.example.com:5000`用于图像`namespace/image:tag` .

您可以根据需要添加任意数量的注册表配置，如上所述，将更多注册表添加到`"auths"`哈希中.

**注意：** Runner 到处都需要完整的`hostname:port`组合，以使其与`DOCKER_AUTH_CONFIG`相匹配. 例如，如果`registry.example.com:5000/namespace/image:tag`中指定`.gitlab-ci.yml` ，则`DOCKER_AUTH_CONFIG`还必须指定`registry.example.com:5000` . 仅指定`registry.example.com`将不起作用.

### Configuring a Runner[](#configuring-a-runner "Permalink")

如果您有许多访问同一注册表的管道，最好在运行程序级别设置注册表访问. 这使管道作者仅通过在适当的运行程序上运行作业即可访问私有注册表. 这也使注册表更改和凭据轮换更加简单.

当然，这意味着该运行程序上的任何作业都可以使用相同的特权访问注册表，即使在整个项目中也是如此. 如果需要控制对注册表的访问，则需要确保控制对运行器的访问.

要将`DOCKER_AUTH_CONFIG`添加到运行器：

1.  修改 Runner 的`config.toml`文件，如下所示：

    ```
    [[runners]]
      environment = ["DOCKER_AUTH_CONFIG={\"auths\":{\"registry.example.com:5000\":{\"auth\":\"bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ=\"}}}"] 
    ```

2.  重新启动 Runner 服务.

**注意：** `DOCKER_AUTH_CONFIG`数据中包含的双引号必须使用反斜杠转义. 这样可以防止将它们解释为 TOML.**注意：** `environment`选项是一个列表. 因此，您的跑步者可能已有条目，您应该将其添加到列表中，而不是替换它.

### Using Credentials Store[](#using-credentials-store "Permalink")

> 在 GitLab Runner 9.5 中添加了对使用凭据存储的支持.

要配置凭据存储，请按照下列步骤操作：

1.  要使用凭据存储，您需要一个外部帮助程序来与特定的钥匙串或外部存储进行交互. 确保 GitLab Runner `$PATH`有可用的帮助程序.

2.  使 GitLab Runner 使用它. 有两种方法可以完成此操作. 要么：

    *   创建一个[变量](../variables/README.html#gitlab-cicd-environment-variables) `DOCKER_AUTH_CONFIG` ，并将 Docker 配置文件的内容作为值：

        ```
         {  "credsStore":  "osxkeychain"  } 
        ```

    *   或者，如果您正在运行自我管理的`${GITLAB_RUNNER_HOME}/.docker/config.json` ，请将上面的 JSON 添加到`${GITLAB_RUNNER_HOME}/.docker/config.json` . GitLab Runner 将读取此配置文件，并将使用此特定存储库所需的帮助程序.

**注意：** `credsStore`用于访问所有注册表. 如果要同时使用私有注册表中的映像和 DockerHub 中的公共映像，则从 DockerHub 提取将失败，因为 Docker 守护程序将尝试对**所有**注册表使用相同的凭据.

### Using Credential Helpers[](#using-credential-helpers "Permalink")

> 在 GitLab Runner 12.0 中添加了对使用凭据助手的支持

作为示例，假设您要使用`aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest`映像，该映像是私有的，需要您登录到私有容器注册表.

要配置`aws_account_id.dkr.ecr.region.amazonaws.com`访问`aws_account_id.dkr.ecr.region.amazonaws.com` ，请按照以下步骤操作：

1.  确保`docker-credential-ecr-login`在 GitLab Runner 的`$PATH`可用.

2.  具有以下任何[AWS 凭证设置](https://github.com/awslabs/amazon-ecr-credential-helper#aws-credentials) . 确保 GitLab Runner 可以访问凭据.

3.  使 GitLab Runner 使用它. 有两种方法可以完成此操作. 要么：

    *   创建一个[变量](../variables/README.html#gitlab-cicd-environment-variables) `DOCKER_AUTH_CONFIG` ，并将 Docker 配置文件的内容作为值：

        ```
        {  "credHelpers":  {  "aws_account_id.dkr.ecr.region.amazonaws.com":  "ecr-login"  }  } 
        ```

        这会将 Docker 配置为对特定注册表使用凭据帮助器.

        or

        ```
        {  "credsStore":  "ecr-login"  } 
        ```

        这会将 Docker 配置为对所有 Amazon ECR 注册表使用凭证帮助器.

    *   或者，如果您正在运行自我管理的`${GITLAB_RUNNER_HOME}/.docker/config.json` ，请将上面的 JSON 添加到`${GITLAB_RUNNER_HOME}/.docker/config.json` . GitLab Runner 将读取此配置文件，并将使用此特定存储库所需的帮助程序.

4.  现在，您可以使用`.gitlab-ci.yml`文件中`image`和/或`services`中定义的`aws_account_id.dkr.ecr.region.amazonaws.com`任何私有图像：

    ```
    image: aws_account_id.dkr.ecr.region.amazonaws.com/private/image:latest 
    ```

    在上面的示例中，GitLab Runner 将查看`aws_account_id.dkr.ecr.region.amazonaws.com`中的图像`private/image:latest` .

您可以根据需要添加`"credHelpers"`数量的注册表配置，如上所述，将更多注册表添加到`"credHelpers"`哈希中.

## Configuring services[](#configuring-services "Permalink")

许多服务接受环境变量，这些变量使您可以根据环境轻松更改数据库名称或设置帐户名称.

GitLab Runner 0.5.0 及更高版本将所有 YAML 定义的变量传递到创建的服务容器.

For all possible configuration variables check the documentation of each image provided in their corresponding Docker hub page.

**注意：**所有变量都将传递到所有服务容器. 它并非旨在区分哪个变量应该放在哪里.

### PostgreSQL service example[](#postgresql-service-example "Permalink")

请参阅有关将[PostgreSQL 用作服务](../services/postgres.html)的特定文档.

### MySQL service example[](#mysql-service-example "Permalink")

请参阅有关将[MySQL 用作服务](../services/mysql.html)的特定文档.

## How Docker integration works[](#how-docker-integration-works "Permalink")

以下是 Docker 在作业期间执行的步骤的高级概述.

1.  创建任何服务容器： `mysql` ， `postgresql` ， `mongodb` ， `redis` .
2.  创建缓存容器以存储`config.toml`和构建映像的`Dockerfile`中定义的所有卷（如上例中的`ruby:2.6` ）.
3.  创建构建容器并将任何服务容器链接到构建容器.
4.  启动构建容器并将作业脚本发送到该容器.
5.  运行作业脚本.
6.  检出代码： `/builds/group-name/project-name/` .
7.  运行`.gitlab-ci.yml`定义的任何步骤.
8.  检查构建脚本的退出状态.
9.  删除构建容器和所有创建的服务容器.

## How to debug a job locally[](#how-to-debug-a-job-locally "Permalink")

**注意：**以下命令在没有 root 特权的情况下运行. 您应该能够使用常规用户帐户运行 Docker.

首先从创建一个名为`build_script`的文件`build_script` ：

```
cat <<EOF > build_script
git clone https://gitlab.com/gitlab-org/gitlab-runner.git /builds/gitlab-org/gitlab-runner
cd /builds/gitlab-org/gitlab-runner
make EOF 
```

在这里，我们以包含 Makefile 的 GitLab Runner 存储库为例，因此运行`make`将执行 Makefile 中定义的命令. 您的里程可能会有所不同，所以不是`make`你可以运行它是特定于项目的命令.

然后创建一些服务容器：

```
docker run -d --name service-mysql mysql:latest
docker run -d --name service-postgres postgres:latest 
```

这将创建两个服务容器，分别名为`service-mysql`和`service-postgres` ，它们分别使用最新的 MySQL 和 PostgreSQL 映像. 它们都将在后台（ `-d` ）运行.

最后，通过执行我们之前创建的`build_script`文件来创建构建容器：

```
docker run --name build -i --link=service-mysql:mysql --link=service-postgres:postgres ruby:2.6 /bin/bash < build_script 
```

上面的命令将创建一个名为`build`的容器，该容器是从`ruby:2.6`镜像派生的，并且有两个链接到它的服务. 使用 STDIN 将`build_script`通过管道传输到 bash 解释器，然后 bash 解释器将在`build`容器中执行`build_script` .

完成测试后，不再需要这些容器时，可以使用以下方法删除它们：

```
docker rm -f -v build service-mysql service-postgres 
```

这将强制（ `-f` ）删除`build`容器，两个服务容器以及随容器创建而创建的所有卷（ `-v` ）.