<!-- review: reviewed -->

<a id="http-docker"></a>

# Docker

O módulo fornece configuração dinâmica de grupos de servidores proxy
em contextos [HTTP](https://pt.angie.software//angie/docs/configuration/modules/http/http_upstream.md#u-upstream) e [stream](https://pt.angie.software//angie/docs/configuration/modules/stream/stream_upstream.md#s-u-upstream)
baseada em labels de contêineres Docker.
Para que a funcionalidade funcione, uma zona de memória compartilhada deve ser configurada
no grupo (veja a descrição de `zone` para [http](https://pt.angie.software//angie/docs/configuration/modules/http/http_upstream.md#u-zone) e [stream](https://pt.angie.software//angie/docs/configuration/modules/stream/stream_upstream.md#s-u-zone)).

#### NOTE
O módulo suporta trabalhar tanto com Docker quanto com suas alternativas,
como Podman, que implementam uma API compatível.

O módulo conecta-se ao daemon Docker via API,
o método de interação com o qual é especificado pela diretiva [docker_endpoint](#docker-endpoint).
Após obter uma lista de contêineres em execução,
o Angie os analisa para verificar a presença de [labels](#docker-labels) adequados.
Se uma descrição de contêiner contém um label com uma porta,
então o endereço e porta de tal contêiner,
bem como parâmetros de outros labels deste contêiner,
são automaticamente adicionados ao bloco `upstream` correspondente
na configuração do Angie.

#### NOTE
O mesmo contêiner pode ser adicionado a múltiplos grupos `upstream`.
Para isso, basta especificar múltiplos conjuntos de labels
com diferentes nomes de grupo e portas.

Isso é especialmente útil
se o contêiner executa vários serviços diferentes em portas diferentes —
cada serviço pode ser associado com seu próprio grupo.

O módulo então se inscreve em eventos do ciclo de vida dos contêineres
e começa a atualizar a configuração do servidor proxy sem recarregar o Angie:

- ao iniciar um contêiner com labels adequados,
  seu endereço IP interno é adicionado ao grupo especificado;
- ao parar ou remover um contêiner,
  ele é automaticamente removido do grupo;
- ao pausar um contêiner com o comando **docker pause**,
  o servidor é marcado como `down`,
  e com **docker unpause** — como `up`.

<a id="configuration-example-12"></a>

## Exemplo de Configuração

As diretivas do módulo estão sempre localizadas no contexto `http`,
mas grupos de servidores proxy podem ser definidos
tanto no contexto `http` quanto no contexto `stream`.

Exemplo de configuração para `http`:

```nginx
http {

    # Exemplos de opções de conexão:
    # docker_endpoint http://127.0.0.1:2375;
    # docker_endpoint https://127.0.0.1:2376;
    docker_endpoint unix:/var/run/docker.sock;

    # tamanho máximo do buffer de resposta Docker (opcional)
    # docker_max_object_size 128k;

    upstream u {

        zone z 1m; # zona de memória compartilhada é obrigatória
    }

    server {

        listen 80;
        server_name example.com;

        location / {

            proxy_pass http://u;
        }
    }
}
```

Similarmente no contexto stream:

```nginx
http {

    # Exemplos de opções de conexão:
    # docker_endpoint http://127.0.0.1:2375;
    # docker_endpoint https://127.0.0.1:2376;
    docker_endpoint unix:/var/run/docker.sock;

    # tamanho máximo do buffer de resposta Docker (opcional)
    # docker_max_object_size 128k;
}

stream {

    upstream u {

        zone z 1m;
    }

    server {

        listen 12345;
        proxy_pass u;
    }
}
```

Ao receber um evento para um contêiner,
o Angie procura por labels da forma
`angie.http.upstreams.<name>.port=<port>` (para contexto HTTP)
ou `angie.stream.upstreams.<name>.port=<port>` (para contexto stream).
Quando um label está presente, o endereço do contêiner na rede Docker especificada
(ou a primeira disponível se o label `angie.network` não for especificado)
é adicionado ao grupo de servidores proxy correspondente.

Se um contêiner para ou é removido, o servidor é removido do grupo;
se um contêiner é pausado, o servidor é marcado como `down`.

Fragmento de um arquivo `docker-compose.yml` com labels que o Angie reconhece:

```yaml
services:
  myapp:
    image: myapp:latest
    labels:
      - "angie.http.upstreams.u.port=8080"
      - "angie.network=my_bridge"
      - "angie.http.upstreams.u.weight=2"
      - "angie.http.upstreams.u.max_conns=50"
      - "angie.http.upstreams.u.max_fails=3"
      - "angie.http.upstreams.u.fail_timeout=10s"
      - "angie.http.upstreams.u.backup=true"
```

<a id="docker-labels"></a>

## Labels

Labels especificam parâmetros do servidor no grupo de servidores proxy
similar aos argumentos da diretiva `server`:

| Label                                                               | Propósito                                                                                                       |
|---------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
| `angie.(http|stream).upstreams.<name>.port=<port>`  *(obrigatório)* | Porta do contêiner à qual o Angie se conectará;<br/>o próprio contêiner é adicionado ao grupo nomeado `<name>`. |
| `angie.network=<docker-network>`                                    | Nome da rede Docker da qual obter o endereço IP do contêiner.                                                   |
| `angie.(http|stream).upstreams.<name>.weight=<n>`                   | Valor do parâmetro `weight`.                                                                                    |
| `angie.(http|stream).upstreams.<name>.max_conns=<n>`                | Número máximo de conexões simultâneas (`max_conns`).                                                            |
| `angie.(http|stream).upstreams.<name>.max_fails=<n>`                | Limite para tentativas falhadas (`max_fails`).                                                                  |
| `angie.(http|stream).upstreams.<name>.fail_timeout=<t>`             | Intervalo para contar tentativas falhadas (`fail_timeout`).                                                     |
| `angie.(http|stream).upstreams.<name>.backup=true|false`            | Marca o servidor como `backup`.                                                                                 |
| `angie.(http|stream).upstreams.<name>.sid=<string>`                 | Define um identificador de servidor personalizado (`sid`)<br/>para o servidor proxy.                            |
| `angie.(http|stream).upstreams.<name>.slow_start=<time>`            | Habilita o modo `slow_start` com um período de tempo configurável.                                              |

<a id="directives-13"></a>

## Diretivas

<a id="index-0"></a>

<a id="docker-endpoint"></a>

### docker_endpoint

| [Sintaxe](https://pt.angie.software//angie/docs/configuration/configfile.md#configfile)   | `docker_endpoint` `URL`;   |
|-------------------------------------------------------------------------------------------|----------------------------|
| Padrão                                                                                    | —                          |
| [Contexto](https://pt.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                       |

Especifica o método de conexão com o daemon Docker e habilita o rastreamento
de eventos de contêineres.
As seguintes opções são suportadas:

| `unix:/var/run/docker.sock`             | Conexão via socket Unix (ex., `/var/run/docker.sock`).   |
|-----------------------------------------|----------------------------------------------------------|
| `http://host:port`, `https://host:port` | Conexão via HTTP ou HTTPS para uma API Docker remota.    |

A conexão pode ser adicionalmente configurada usando o contexto [client](https://pt.angie.software//angie/docs/configuration/modules/http/index.md#client),
onde o módulo adiciona dois blocos `location` nomeados:

- `@docker_events` é usado para receber eventos de contêineres;
- `@docker_containers` — para obter informações de contêineres.

Por padrão, eles contêm a diretiva [proxy_pass](https://pt.angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-pass)
com o endereço de conexão e várias outras configurações padrão otimais,
às quais outras configurações do módulo [Proxy](https://pt.angie.software//angie/docs/configuration/modules/http/http_proxy.md#http-proxy) podem ser adicionadas.

Se a diretiva for especificada,
o Angie abre uma conexão com o Docker usando o método especificado,
solicita uma lista de contêineres em execução,
analisa seus labels e processa todos os eventos subsequentes de contêineres,
adicionando ou removendo servidores em grupos de servidores proxy de acordo com os labels.

<a id="index-1"></a>

<a id="docker-max-object-size"></a>

### docker_max_object_size

| [Sintaxe](https://pt.angie.software//angie/docs/configuration/configfile.md#configfile)   | `docker_max_object_size` `<size>`;   |
|-------------------------------------------------------------------------------------------|--------------------------------------|
| Padrão                                                                                    | `64k`                                |
| [Contexto](https://pt.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                                 |

Define o tamanho máximo do buffer
que é usado tanto para respostas JSON a requisições Docker
quanto para o fluxo de eventos de contêineres.

- Para requisições regulares (versão da API, lista de contêineres, informações de contêineres):
  toda a resposta deve caber no buffer, caso contrário ocorre um erro.
- Para eventos de contêineres, processamento em fluxo é usado
  com reutilização de buffer,
  o que permite processar um fluxo ilimitado de eventos.

O valor típico de `64k` é suficiente para aproximadamente 25 contêineres.

Quando ocorrem erros de conexão da API Docker ou erros de processamento de resposta,
o módulo automaticamente tenta novamente em intervalos de tempo específicos.
O número máximo de tentativas de repetição para obter informações
sobre um contêiner específico é limitado a duas tentativas *adicionais*;
depois disso, o módulo para de tentar para aquele contêiner.
