# Docker

Daemon do Docker no VPS e apps como projetos Compose: imagem, registro privado, repo ou Compose, com HTTPS opcional.

Fonte: https://ardumaker.com/pt/docs/docker/

- Categoria: Servidores e infraestrutura
- Estado: Disponível
- Requisitos: Um VPS ativo com a função `docker` disponível (o Ubuntu 22.04 tem); Pelo menos 256 MB de RAM livre e 1 GB de disco livre medidos; Ser membro com acesso ao VPS para instalar; admin para desinstalar
- Ferramentas MCP (Só leem): `ver_catalogo_apps`, `ver_preflight_app`, `listar_apps_empresa`, `ver_app`, `ver_operacion_app`
- Ferramentas MCP (Escrevem ou modificam): `instalar_app`, `controlar_app`, `reintentar_operacion_app`, `refrescar_apps`
- Ferramentas MCP (Destrutivas): `desinstalar_app`

## O que permite fazer?

O Docker na ArduMaker tem duas partes: o daemon, que é uma capacidade do VPS, e os apps Docker, cada um um projeto Compose próprio que a plataforma escreve, sobe, observa e remove.

- Instalar o daemon com um clique (ou deixar que o primeiro app que precisar o instale).
- Publicar uma imagem pública, uma imagem de um registro privado com token, ou um repo do GitHub com Dockerfile.
- Publicar um Compose avançado (como objeto JSON) com vários serviços.
- Iniciar, parar e reiniciar o projeto, e publicá-lo com HTTPS se expuser uma porta web.
- Pela aba Docker do VPS: listar contêineres, ver seus logs, pará-los, reiniciá-los ou apagá-los, e ver imagens, volumes e redes.

## Quando convém usar?

- Uma aplicação já empacotada como imagem (um painel, uma ferramenta interna, um serviço de terceiros).
- Vários serviços que sobem juntos com Compose.
- Para código próprio no GitHub com um processo que não é Docker, o [deploy do GitHub](https://ardumaker.com/pt/docs/github-deploy) é mais adequado.

## Como funciona na ArduMaker?

### O daemon

Os VPS novos nascem com as permissões de contêiner que o Docker precisa, sem serem privilegiados. Um VPS antigo que não as tem as recebe ao instalar o Docker e precisa de um reinício (o preflight avisa com `requiere_reinicio_vps`). O daemon é instalado com o pacote `docker.io` e `fuse-overlayfs`, com `userns-remap` ativado: os processos dos contêineres não rodam como o `root` real do VPS.

### Um app Docker

1. A configuração e o preflight são validados (função do sistema, Docker possível no host, memória e disco).
2. Se o daemon faltar, é instalado; se outra instalação estiver em andamento, a operação aguarda e é tentada de novo.
3. É escrito `/opt/ardumaker-apps/app<id>/docker-compose.yml` (com cópia do anterior) e validado com `docker compose config`; se não validar, o anterior é restaurado.
4. É executado `docker compose -p app<id> up -d --remove-orphans` como passo longo, assim um download pesado não estoura o tempo.
5. Se houver `port`, é publicado com HTTPS e o link é verificado.

Todos os contêineres levam o rótulo `ardumaker.app_id` e o projeto se chama `app<id>`: o nome não é escolhido pelo usuário e a plataforma nunca toca nada fora dele. Repetir o deploy é idempotente: o mesmo arquivo e `up -d` não recriam o que não mudou.

## O que muda realmente?

| O quê | Onde |
| --- | --- |
| Arquivo Compose | `/opt/ardumaker-apps/app<id>/docker-compose.yml` |
| Código clonado (modo repo) | `/opt/ardumaker-apps/app<id>/src` |
| Dados com caminho relativo | `/opt/ardumaker-apps/app<id>/datos` |
| Volumes com nome | Do próprio projeto (`data<i>` no modo simples) |
| Token de registro privado | Criptografado na plataforma; o VPS faz `docker login` com o token por stdin |

## Configuração de um app Docker

| Modo | Chaves |
| --- | --- |
| Imagem | `image`, `port`, `container_port`, `env` (hasta 50), `volumes`, `health_path`, `registry` |
| Repo do GitHub | `repo_id`, `branch`, `port`, `container_port`, `env`, `volumes`, `health_path` |
| Compose avançado | `compose` (objeto JSON, não YAML) e `port` opcional |

- `image`, `compose` e `repo_id` são mutuamente exclusivos.
- `port` é a porta do VPS (a partir de 1024 e nunca uma protegida); com `port` é preciso `container_port`. `"auto"` escolhe uma livre.
- As portas são publicadas só em `127.0.0.1`: um contêiner nunca fica aberto direto para a internet.
- `env` não aceita nomes de segredo (`*_PASSWORD`, `*_TOKEN`…): a configuração não guarda segredos.

## O que um Compose recusa

Cada serviço aceita uma lista branca de chaves (`image`, `command`, `entrypoint`, `environment`, `ports`, `volumes`, `restart`, `depends_on`, `healthcheck`, `working_dir`, `user`, `expose`, `networks`, `mem_limit`, `cpus`, `labels`, `tmpfs`, `stop_grace_period`, `read_only`, `init`). As recusas vêm com um código por caminho (`compose.services.<serviço>.<chave>`):

| Código | O que dispara |
| --- | --- |
| `privileged` | `privileged`, `devices`, `security_opt`, `userns_mode` |
| `network_mode_host` | `network_mode: host` |
| `pid_host` | `pid` ou `ipc` do host |
| `cap_add` | Capacidades extras |
| `docker_socket` | Montar `docker.sock`, `/run` ou `/var/run` |
| `host_mount` | Caminhos absolutos, `~` ou `..` (só `./algo` dentro da pasta própria) |
| `puerto_publico` | Qualquer porta que não seja `127.0.0.1:H:C` |

Também não são aceitos `build`, `container_name`, `env_file`, `configs`, `secrets`, `extends` nem `name`, nem rótulos `com.docker.*` ou `ardumaker.*`.

## Desinstalar e dados

A desinstalação roda `docker compose down --remove-orphans`, força a remoção dos contêineres com o rótulo do projeto e apaga o arquivo Compose. Os volumes e a pasta `./datos` ficam, salvo se for pedido apagar os dados: então roda `down -v` e a pasta do projeto é apagada. Nada fora de `app<id>` é tocado.

> **PELIGRO:** Com `delete_data` a desinstalação é irreversível: os volumes do projeto se perdem.

## Esquema

**Um app Docker publicado**

```text
Internet (HTTPS em `docker-<id>` ou um domínio próprio)
  ↓
nginx do VPS (server block do domínio)
  ↓
`127.0.0.1:<port>` (única porta publicada pelo contêiner)
  ↓
Projeto Compose `app<id>` (contêineres com rótulo `ardumaker.app_id`)
  ↓
Volumes (persistem até que se peça para apagar os dados)
```

Sem `port` não há URL: o app é administrado pela aba Docker.

## Resultado esperado

O app aparece em Apps com o estado observado: `running` se todos os contêineres rodam, `stopped` se todos estão parados, `degraded` se há mistura e `missing` se não sobra nenhum. Com `port`, a URL HTTPS aparece só quando o link respondeu sem erro 5xx.

```bash
docker compose -p app<id> ps
docker ps --filter label=com.docker.compose.project=app<id>
```

## Erros e resolução

| Erro | Causa | Tentar de novo? |
| --- | --- | --- |
| `requiere_docker` | O host não suporta Docker | Não |
| `requiere_reinicio_vps` | Faltam permissões de contêiner e é preciso reiniciar o VPS | Após reiniciar |
| `recursos_insuficientes` | Menos de 256 MB de RAM ou 1 GB de disco livres | Após liberar recursos |
| `docker_instalandose` / `docker_no_instalado` | O daemon está sendo instalado ou não conseguiu iniciar | Sim |
| `compose_no_disponible` / `despliegue_fallido` / `baja_fallida` | Não foi possível preparar o Compose, o pull ou a inicialização falharam, ou o `down` não terminou | Sim (`up -d` e `down` são idempotentes) |
| `compose_invalido` | `docker compose config` recusou o arquivo; o anterior foi restaurado | Não, é preciso corrigir |
| `puerto_ocupado` | Outro app do VPS publica ou declara essa porta | Com outra porta |
| `config_invalida` | Chave não permitida ou segredo em `env`; `fields` diz qual | Corrigindo o pedido |

> **PRECAUCION:** Os contêineres do stack do n8n (`n8n-main`, `n8n-postgres`, `n8n-redis`, workers e runners) são protegidos na aba Docker: apagá-los responde 409. São operados pelo [n8n](https://ardumaker.com/pt/docs/n8n).

## Relação com MCP

Os apps Docker são operados via MCP com as ferramentas de Apps; a referência está em [/mcp/docs](https://ardumaker.com/pt/mcp/docs) e [/mcp/servicios](https://ardumaker.com/pt/mcp/servicios).

- Leitura: `ver_catalogo_apps`, `ver_preflight_app` (valida a `config` exata antes de instalar), `listar_apps_empresa`, `ver_app`, `ver_operacion_app`.
- Modificam: `instalar_app` com `app_type: docker` (exige `idempotency_key`), `controlar_app` (`start`, `stop`, `restart`), `reintentar_operacion_app`, `refrescar_apps`.
- Destrutiva: `desinstalar_app` (só admin, `confirm=true`; os volumes só são apagados com `delete_data` e `confirm_delete_data`).

> **INFO:** Não há ferramentas MCP para a aba Docker (contêineres soltos, imagens, redes). Instalar o Docker ou um contêiner à mão com `ejecutar_comando_vps` deixa algo que a plataforma não lista, não reinicia nem faz backup.

## Funcionalidades relacionadas

- [Servidores VPS](https://ardumaker.com/pt/docs/vps/)
- [n8n](https://ardumaker.com/pt/docs/n8n/)
- [Deploy do GitHub](https://ardumaker.com/pt/docs/github-deploy/)
- [Nginx](https://ardumaker.com/pt/docs/nginx/)
- [Certificados SSL](https://ardumaker.com/pt/docs/ssl/)
