# MySQL com Docker Compose: guia completo (com correção do erro "Public Key Retrieval is not allowed")

Se você chegou aqui pesquisando o erro **"Public Key Retrieval is not allowed"** ao tentar conectar no MySQL pelo DBeaver, pode pular direto para [essa seção](#erro-public-key-retrieval-is-not-allowed). Se está começando do zero, siga o tutorial completo abaixo.

Neste guia você vai aprender a:

*   Subir um container MySQL com Docker Compose, com dados persistidos na sua máquina
    
*   Evitar os dois erros mais comuns dessa configuração
    
*   Conectar no banco usando o DBeaver
    

## Pré-requisitos

*   Docker instalado (`docker --version` para conferir)
    
*   Docker Compose instalado, de preferência a versão mais recente, integrada como plugin (`docker compose version`, sem hífen)
    
*   DBeaver instalado (ou qualquer outro cliente MySQL de sua preferência)
    

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Atenção à versão do Compose.</strong> Existem duas versões: a legada <code>docker-compose</code> (Python, standalone, descontinuada) e a atual <code>docker compose</code> (plugin oficial, sem hífen). Se <code>docker compose version</code> não funcionar, instale com <code>sudo apt install docker-compose-plugin</code>.</div>
</div>

## Passo 1: criando o docker-compose.yml

Crie uma pasta para o projeto e, dentro dela, um arquivo `docker-compose.yml`:

```dockerfile
services:
  mysql_knex:
    container_name: mysql_knex
    hostname: mysql_knex
    image: mysql:8.0
    restart: always
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --innodb_force_recovery=0
    volumes:
      - ~/.MySQLDBData/mysqlonly/mysql_knex:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: senha
      MYSQL_DATABASE: base_de_dados
      MYSQL_USER: usuario
      MYSQL_PASSWORD: senha
      TZ: America/Sao_Paulo
```

Alguns pontos importantes desse arquivo:

**Fixe a versão da imagem.** Usar `image: mysql` sem tag puxa sempre a versão mais recente disponível no Docker Hub. Isso é perigoso: uma versão nova pode remover flags que seu comando usa, quebrando a inicialização do container. Fixando `mysql:8.0`, você garante um comportamento previsível.

**O volume persiste os dados no seu host.** A linha abaixo é o que garante que, se você derrubar o container, os dados não somem:

```dockerfile
volumes:
  - ~/.MySQLDBData/mysqlonly/mysql_knex:/var/lib/mysql
```

Você pode confirmar seu caminho com `echo $HOME`. Se quiser evitar qualquer ambiguidade (por exemplo, ao rodar com `sudo`, onde `~` viraria `/root`), use o caminho absoluto direto no lugar do `~`.

## Passo 2: subindo o container

Na pasta onde está o `docker-compose.yml`, rode:

```dockerfile
docker compose up -d
```

Confirme que subiu com:

```dockerfile
docker ps
```

![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/60df260c-978e-4e25-ab9b-4ff71f6c0311.png align="center")

O container `mysql_knex` deve aparecer com status `Up`. Se aparecer `Restarting`, o processo está travando em loop — siga para a próxima seção.

## Erro: unknown variable 'default-authentication-plugin'

Se você usou algum tutorial mais antigo como referência, é comum ver a flag `--default-authentication-plugin=mysql_native_password` no `command:` do compose. Em versões recentes do MySQL, essa flag **não existe mais**, e o servidor recusa iniciar, entrando em crash loop.

Para confirmar que é esse o problema, veja os logs:

```dockerfile
docker logs mysql_knex --tail 50
```

Se aparecer algo como:

```dockerfile
[ERROR] [MY-000067] [Server] unknown variable 'default-authentication-plugin=mysql_native_password'.
[ERROR] [MY-010119] [Server] Aborting
```

A solução é remover essa flag do `command:` (como já está no `docker-compose.yml` deste tutorial) e deixar o MySQL 8 usar seu método de autenticação padrão, o `caching_sha2_password`.

Se o container já tentou subir e crashou antes de terminar a inicialização, é seguro resetar o volume, já que nenhum dado real chegou a ser gravado:

```dockerfile
docker compose down
sudo rm -rf ~/.MySQLDBData/mysqlonly/mysql_knex
docker compose up -d
```

Depois disso, confira os logs de novo e espere aparecer a linha:  

```dockerfile
[Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.43' ...
```

Isso confirma que o MySQL subiu corretamente e está pronto para aceitar conexões.

## Passo 3: conectando pelo DBeaver  

![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/3335355c-1ff0-42f9-843f-517a666e3543.png align="center")

Abra o DBeaver e crie uma nova conexão MySQL, com os dados do seu `docker-compose.yml`:

*   **Host:** `localhost`
    
*   **Port:** `3306`
    
*   **Database:** o valor de `MYSQL_DATABASE`
    
*   **Username:** o valor de `MYSQL_USER`
    
*   **Password:** o valor de `MYSQL_PASSWORD`
    

![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/a43c9757-1ec2-4dde-9836-509b4a9d615a.png align="center")

## Erro: Public Key Retrieval is not allowed

Ao testar a conexão, é bem provável que apareça este erro:

![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/2abd8d50-d963-40cd-9fd2-b9f453046c8d.png align="center")

```dockerfile
Public Key Retrieval is not allowed
```

Isso acontece porque o MySQL 8 usa o plugin de autenticação `caching_sha2_password`, que exige buscar uma chave pública RSA do servidor para autenticar com segurança. Por padrão, o driver JDBC bloqueia essa busca automática — é uma proteção contra ataques man-in-the-middle. Em ambiente de desenvolvimento local, é seguro habilitar manualmente.

**Como resolver no DBeaver:**

1.  Abra a conexão em **Edit Connection**.
    
2.  Vá até a aba **Driver properties**.
    
3.  Localize a propriedade `allowPublicKeyRetrieval` e defina como `true`. Se não existir na lista, adicione manualmente clicando no ícone **+**.
    
    ![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/af6287c1-9623-4d2a-8a79-10e563cb7363.png align="center")
    
4.  Confirme também que `useSSL` está como `false`, já que não há certificado SSL configurado para produção nesse ambiente local.
    
    ![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/77f33161-ba33-48dc-b1b9-cea0ba9aa1fd.png align="center")
    
5.  Clique em **OK** e teste a conexão novamente.
    

**Alternativa mais rápida:** editar direto a URL JDBC, na aba **Main**:

![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/702b9905-aeae-47a5-8ab3-8898b4dfaf64.png align="center")

```plaintext
jdbc:mysql://localhost:3306/base_de_dados?allowPublicKeyRetrieval=true&useSSL=false
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Essas duas flags são aceitáveis em desenvolvimento local. Em produção, o recomendado é configurar SSL de verdade em vez de desabilitar essas proteções.</div>
</div>

## TCP/IP vs Unix socket: por que a porta importa

Um detalhe que gera confusão: nos logs do MySQL você vai ver uma linha assim:

![](https://cdn.hashnode.com/uploads/covers/66507d33fab6e38c4d7339d6/c5473096-77e8-4399-ace5-0241cdf9fadc.png align="center")

```dockerfile
ready for connections. ... socket: '/var/run/mysqld/mysqld.sock' port: 3306
```

O MySQL aceita conexões de duas formas:

*   **TCP/IP**, via `localhost:3306` — é o que o DBeaver usa, mesmo estando na mesma máquina, porque ele roda fora do container e precisa atravessar a rede até o processo do MySQL.
    
*   **Unix socket**, via o arquivo `mysqld.sock` — só acessível por processos dentro do mesmo container, como quando você entra nele diretamente com `docker exec -it mysql_knex mysql -u root -p`.
    

Por isso, garantir que a porta `3306:3306` esteja mapeada corretamente no `docker-compose.yml` é essencial para qualquer cliente externo, como o DBeaver, conseguir se conectar.

## Bônus: comandos úteis para o dia a dia

**Parar o container sem apagar dados:**

```dockerfile
docker compose stop
```

**Voltar a subir depois de parado:**

```dockerfile
docker compose start
```

**Ver logs em tempo real:**

```dockerfile
docker logs -f mysql_knex
```

**Fazer backup do banco (dump):**

```dockerfile
docker exec mysql_knex mysqldump -u root -p base_de_dados > backup.sql
```

**Restaurar um backup:**

```dockerfile
docker exec -i mysql_knex mysql -u root -p base_de_dados < backup.sql
```

**Resetar tudo do zero (⚠️ apaga os dados permanentemente):**

```dockerfile
docker compose down
sudo rm -rf ~/.MySQLDBData/mysqlonly/mysql_knex
docker compose up -d
```

## Conclusão

Com esse setup você tem um MySQL rodando em container, com dados persistidos fora dele (então derrubar o container não te faz perder nada), e uma conexão funcional via DBeaver para gerenciar o banco visualmente. Os dois erros cobertos aqui — a flag de autenticação obsoleta e a recuperação de chave pública — são praticamente um rito de passagem para quem sobe MySQL 8 em Docker pela primeira vez, então se você travou neles, está em boa companhia.
