Alternar tema

Mapeamento de portas no Docker: não deixe a mensagem port is already allocated acabar com sua sexta-feira à noite

Easton editorial illustration: before-after repair bench

São sete e meia da noite de uma sexta-feira, e você já está se preparando para ir embora. De repente, o gerente de produto manda uma mensagem: “Dá para subir rapidamente um ambiente de testes? O cliente quer ver a demo amanhã cedo.”

Tudo bem. Você abre o terminal e digita o conhecido comando docker run:

docker run -d -p 8080:80 nginx

Então pressiona Enter. Uma mensagem de erro vermelha aparece na tela:

Error response from daemon: driver failed programming external connectivity on endpoint romantic_euler:
Bind for 0.0.0.0:8080 failed: port is already allocated.

O coração aperta. A porta 8080 está ocupada? Por quem? Por quê? E agora?

Essa situação parece familiar? Aposto que pelo menos metade das pessoas que usam Docker já arrancou os cabelos diante dessa mensagem. Pior: você só queria executar um contêiner simples, mas acaba tendo de investigar portas, procurar processos e revisar configurações de firewall. Uma tarefa de cinco minutos se transforma em meia hora.

Afinal, o que é mapeamento de portas?

Para falar a verdade, mapeamento de portas pode parecer complicado, mas é bem simples de entender.

Imagine um contêiner Docker como um prédio de apartamentos. Dentro dele, cada serviço tem seu próprio “número de apartamento” — uma porta. O nginx, por exemplo, escuta a porta 80 por padrão. O problema é que esse prédio está isolado: quem está do lado de fora não sabe quais apartamentos existem lá dentro nem consegue entrar.

O mapeamento de portas funciona como um “conversor de números” na entrada do prédio. Alguém do lado de fora chama a porta 3000, e o conversor direciona essa pessoa automaticamente para a porta 80 dentro do contêiner. É exatamente isso que -p 3000:80 faz: mapeia a porta 3000 do host para a porta 80 do contêiner.

O formato é simples: -p porta_do_host:porta_do_contêiner. Quando comecei a aprender Docker, eu sempre invertia a ordem desses dois números. Depois passei a pensar assim: “de fora para dentro” — primeiro vem a porta externa, depois a interna.

Qual é a diferença entre -p e -P?

Essas duas opções costumam causar confusão. -p minúsculo define manualmente o mapeamento: você escolhe exatamente qual porta mapear. Já -P maiúsculo é o modo automático: o Docker mapeia todas as portas expostas pelo contêiner para portas altas aleatórias do host, normalmente entre 32768 e 61000.

Ao usar -P, você precisa consultar docker ps ou docker port para descobrir qual porta o Docker atribuiu:

docker run -d -P nginx
docker port <container_id>

A saída pode ser assim:

80/tcp -> 0.0.0.0:32768

Isso significa que a porta 80 do contêiner foi mapeada para a porta 32768 do host. É prático, mas não recomendo para produção: como a porta não é fixa, a configuração fica mais trabalhosa.

Quando a porta está ocupada: três formas de encontrar o culpado

Voltemos ao cenário do início: a porta já está em uso. O que fazer?

Primeira: verifique se o próprio Docker está usando a porta

Às vezes, você reinicia um contêiner, mas o antigo não foi encerrado por completo e continua ocupando a porta. Primeiro, use docker ps -a para verificar se há algum contêiner antigo:

docker ps -a | grep 8080

Se encontrar um, remova-o diretamente:

docker rm -f <container_id>

Segunda: descubra qual processo do host usa a porta

Se não for o Docker, então algum processo no host está usando a porta. Os comandos variam conforme o sistema operacional.

No Linux ou macOS:

# Método 1: usar lsof
sudo lsof -i :8080

# Método 2: usar netstat
sudo netstat -tulnp | grep 8080

# Método 3: usar ss (mais rápido)
sudo ss -tulnp | grep 8080

A saída será parecida com esta:

COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    1234  odensu   21u  IPv4  0x1234      0t0  TCP *:8080 (LISTEN)

Pronto: o PID é 1234, e se trata de um processo Node.js. Você pode:

  1. Encerrá-lo, se tiver certeza de que ele não é necessário: kill -9 1234
  2. Ou executar o contêiner Docker em outra porta

No Windows, o processo exige alguns passos a mais:

# Consultar a porta
netstat -ano | findstr :8080

# Saída semelhante a esta:
# TCP    0.0.0.0:8080    0.0.0.0:0    LISTENING    1234

# Consultar o processo
tasklist | findstr 1234

# Encerrar o processo
taskkill /PID 1234 /F

Terceira: simplesmente use outra porta

Na verdade, muitas vezes não é preciso complicar. A porta 8080 está ocupada? Use a 8081:

docker run -d -p 8081:80 nginx

Ou deixe que o próprio Docker escolha:

docker run -d -p 0:80 nginx

Ao informar 0 como porta do host, o Docker atribui automaticamente uma porta livre. Depois, use docker ps para ver qual foi escolhida.

Mapeamento de várias portas e associação a um endereço IP

Como mapear várias portas?

Às vezes, um contêiner precisa expor várias portas. Imagine uma aplicação full stack com frontend na porta 3000, backend na 8000 e banco de dados na 5432:

docker run -d \
  -p 3000:3000 \
  -p 8000:8000 \
  -p 5432:5432 \
  my-fullstack-app

Basta acrescentar vários parâmetros -p, um após o outro.

Também existe a possibilidade de mapear uma faixa de portas:

docker run -d -p 8000-8010:8000-8010 my-app

Isso mapeia as portas 8000 a 8010 do host para as portas correspondentes no contêiner. Para ser sincero, quase nunca uso esse recurso, porque o gerenciamento pode ficar confuso.

Associação a um endereço IP específico

Por padrão, o Docker associa a porta a 0.0.0.0, o que significa que ela fica acessível por todas as interfaces de rede. Se você quiser permitir acesso apenas pela própria máquina, pode especificar 127.0.0.1:

docker run -d -p 127.0.0.1:8080:80 nginx

Assim, a rede externa não consegue acessar o contêiner; somente o host pode se conectar. Se o servidor tiver várias interfaces de rede, você também pode associar a porta a um IP específico:

docker run -d -p 192.168.1.100:8080:80 nginx

“A porta está mapeada. Por que ainda não consigo acessar?”

Esse é o problema que mais vejo. O mapeamento parece correto, docker ps mostra que tudo funcionou, mas o navegador não consegue acessar o serviço. Veja alguns erros que já encontrei.

Erro 1: o serviço dentro do contêiner não escuta em 0.0.0.0

Esse detalhe é muito fácil de ignorar. Muitas aplicações escutam apenas em 127.0.0.1 — ou localhost — por padrão. Isso significa que elas aceitam somente conexões vindas de dentro do próprio contêiner, e as requisições externas não conseguem chegar ao serviço.

Por exemplo, em uma aplicação Node.js:

// Forma incorreta
app.listen(3000, 'localhost');  // Escuta apenas em 127.0.0.1

// Forma correta
app.listen(3000, '0.0.0.0');    // Escuta em todas as interfaces de rede

O mesmo vale para Python Flask:

# Incorreto
app.run(host='127.0.0.1')

# Correto
app.run(host='0.0.0.0')

Como verificar? Entre no contêiner e confira:

docker exec -it <container_id> netstat -tulnp

Se aparecer 127.0.0.1:3000 em vez de 0.0.0.0:3000 ou :::3000, esse é o problema.

Erro 2: o firewall está bloqueando a conexão

Em servidores Linux, o firewall — firewalld ou ufw — pode bloquear a porta. Já passei por isso no CentOS: o mapeamento do Docker estava correto, mas o acesso externo simplesmente não funcionava.

Verifique o estado do firewall:

# CentOS/RHEL
sudo firewall-cmd --list-all

# Ubuntu/Debian
sudo ufw status

Se o firewall estiver ativo, você precisará liberar a porta:

# CentOS/RHEL
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

# Ubuntu/Debian
sudo ufw allow 8080/tcp

Se tiver certeza de que o ambiente é seguro — por exemplo, uma máquina de desenvolvimento —, também pode desativar o firewall temporariamente para testar:

# CentOS/RHEL
sudo systemctl stop firewalld

# Ubuntu/Debian
sudo ufw disable

Mas nunca faça isso em produção.

Erro 3: o grupo de segurança do servidor em nuvem não está configurado

Ao usar servidores em nuvem como Alibaba Cloud, AWS ou Tencent Cloud, além do firewall do sistema existe o chamado “grupo de segurança”. Ele funciona como um firewall no nível da plataforma de nuvem e tem prioridade sobre o firewall do sistema.

Na primeira vez que usei uma instância ECS da Alibaba Cloud, caí nessa armadilha: o firewall do sistema estava desativado e a configuração do Docker estava correta, mas o serviço continuava inacessível. No fim, descobri que faltava uma regra de entrada no grupo de segurança.

A solução é acessar o console da plataforma, localizar a configuração do grupo de segurança e adicionar uma regra de entrada liberando a porta necessária. O procedimento varia um pouco entre plataformas, mas a lógica é praticamente a mesma.

Erro 4: o modo de rede do Docker está incorreto

O Docker oferece vários modos de rede: bridge, que é o padrão, host, none e container. Se você usar --network host, os parâmetros de mapeamento de portas serão ignorados, pois o contêiner utilizará diretamente a pilha de rede do host:

# Neste caso, o parâmetro -p será ignorado
docker run -d --network host -p 8080:80 nginx

No modo host, a porta que o serviço escuta dentro do contêiner é a mesma usada no host, sem necessidade de mapeamento. Esse modo oferece o melhor desempenho, mas aumenta o risco de conflitos de portas.

Fluxo rápido de diagnóstico

Quando uma porta não responde, normalmente verifico nesta ordem:

  1. docker ps — confirme se o mapeamento de portas está correto
  2. docker logs <container_id> — veja se o contêiner falhou durante a inicialização
  3. docker exec -it <container_id> netstat -tulnp — confira se o serviço dentro do contêiner escuta em 0.0.0.0
  4. curl localhost:8080 — teste no host para descartar problemas de rede
  5. Verifique as regras do firewall do sistema
  6. Verifique a configuração do grupo de segurança do provedor de nuvem

Ao seguir esse fluxo, quase sempre é possível encontrar a causa.

O mapeamento de portas reduz o desempenho?

Sendo sincero, sim. Mas o impacto depende do cenário.

O mapeamento de portas do Docker se baseia em iptables no Linux ou no userland proxy, usado como modo de compatibilidade entre plataformas. Cada pacote de rede que passa pelo mapeamento percorre uma lógica de encaminhamento, então inevitavelmente há algum custo.

Fiz um teste simples com ab — Apache Bench — em um contêiner nginx:

  • Acesso direto ao IP do contêiner, sem mapeamento de portas: cerca de 50.000 requisições por segundo
  • Acesso por meio do mapeamento de portas: cerca de 45.000 requisições por segundo

A diferença foi de aproximadamente 10%. Para a maioria das aplicações, essa perda é aceitável. Mas, se o serviço for especialmente sensível a desempenho, como sistemas de negociação de alta frequência ou servidores de jogos, talvez seja necessário otimizar.

Opção de otimização 1: use o modo de rede host

Como mencionado antes, no modo --network host o contêiner utiliza diretamente a pilha de rede do host, sem o custo do mapeamento de portas:

docker run -d --network host nginx

Ele oferece o melhor desempenho, mas tem dois custos:

  1. As portas do contêiner podem entrar em conflito com as do host
  2. Você perde o isolamento de rede

Use com cautela em produção.

Opção de otimização 2: desative o userland proxy

Por padrão, o Docker utiliza tanto iptables quanto o userland proxy. Este último é um programa de proxy escrito em Go que oferece boa compatibilidade, mas tem desempenho inferior. Se você tiver certeza de que o sistema oferece suporte a iptables — como acontece na maioria das distribuições Linux —, pode desativá-lo.

Edite /etc/docker/daemon.json:

{
  "userland-proxy": false
}

Reinicie o Docker:

sudo systemctl restart docker

Isso pode reduzir parte do custo, embora o ganho não seja muito grande — talvez cerca de 5%.

Opção de otimização 3: reduza os mapeamentos desnecessários

Alguns serviços são usados apenas por outros contêineres e não precisam ser expostos no host. Um contêiner de banco de dados acessado somente pela aplicação, por exemplo, não precisa mapear portas:

# Sem mapear portas; a comunicação ocorre apenas dentro da rede do Docker
docker run -d --name postgres --network mynet postgres

# O contêiner da aplicação acessa o banco pelo nome do contêiner
docker run -d --name app --network mynet -p 3000:3000 my-app

A comunicação entre contêineres pela rede do Docker é muito mais rápida do que por mapeamento de portas.

Quando vale a pena se preocupar com desempenho?

Na maioria dos cenários, o custo do mapeamento de portas é irrelevante. O que realmente merece atenção é:

  1. Gargalos da própria aplicação, como consultas ao banco de dados e lógica do código
  2. Limites de recursos do contêiner, como CPU e memória
  3. I/O de disco e largura de banda da rede

O custo do mapeamento de portas geralmente fica bem atrás desses fatores. A menos que seu serviço processe dezenas de milhares de requisições por segundo, otimize primeiro o código da aplicação.

Para concluir

Voltemos ao cenário do início: são sete e meia de uma sexta-feira, e o gerente de produto pede que você suba rapidamente um ambiente de testes. Agora você sabe o que fazer.

Ao encontrar o erro port already allocated, use primeiro docker ps -a para verificar se algum contêiner antigo continua ativo. Depois, use lsof ou netstat para descobrir quem ocupa a porta do host. Se necessário, escolha outra porta ou deixe o Docker atribuir uma automaticamente com -p 0:80.

Se a porta estiver mapeada, mas o serviço continuar inacessível, verifique nesta ordem: endereço em que o serviço escuta dentro do contêiner → firewall do host → grupo de segurança da nuvem → modo de rede do Docker. Na grande maioria dos casos, você encontrará a causa.

O mapeamento de portas é um dos recursos mais básicos do Docker e também um dos que mais causam problemas. Depois de entender o princípio e dominar o diagnóstico, você não precisará mais perder tempo com isso.

Da próxima vez que surgir um problema de porta, não entre em pânico. Respire fundo, siga o fluxo de diagnóstico e você encontrará a solução. Assim, poderá sair no horário e aproveitar sua sexta-feira à noite.

E não se esqueça de salvar este artigo. Se a situação voltar a acontecer, uma consulta rápida pode economizar bastante tempo. É isso que eu mesmo faço.

Fluxo completo para diagnosticar o mapeamento de portas no Docker

Do diagnóstico de portas ocupadas à otimização de desempenho, resolva de forma sistemática os principais problemas de mapeamento de portas no Docker

⏱️ Estimated time: 15 min

  1. 1

    Step 1: Entenda a sintaxe do mapeamento de portas e os erros mais comuns

    Sintaxe do mapeamento de portas:
    • -p host_port:container_port (mapeia uma porta específica, como -p 8080:80)
    • -p container_port (mapeia para uma porta aleatória, como -p 80)
    • -P (mapeia todas as portas expostas)
    • --publish-all (equivalente a -P)

    Erro comum:
    • A porta já está em uso (Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated)
    • O contêiner não consegue iniciar, então é necessário descobrir quem está ocupando a porta
  2. 2

    Step 2: Diagnostique a porta ocupada e aplique a solução

    Como diagnosticar:
    • Use lsof -i :8080 para identificar quem ocupa a porta
    • Use netstat -tuln | grep 8080 para verificar o estado da porta
    • Use docker ps para conferir os mapeamentos de portas dos contêineres
    • Use docker port container-name para consultar as portas do contêiner

    Soluções:
    • Encerre o processo que ocupa a porta (kill -9 PID)
    • Pare o contêiner que ocupa a porta (docker stop container-name)
    • Altere o mapeamento de portas (-p 8081:80)
    • Use uma porta dinâmica (não especifique a porta do host e deixe o Docker escolher automaticamente)
  3. 3

    Step 3: Adote boas práticas e otimize o desempenho

    Boas práticas:
    • Use docker-compose para gerenciar os mapeamentos de portas
    • Configure faixas de portas para evitar conflitos
    • Verifique periodicamente quais portas estão em uso
    • Use uma ferramenta de varredura de portas para encontrar portas disponíveis

    Otimização de desempenho:
    • O mapeamento de portas, por si só, tem pouco custo de desempenho
    • Se houver problemas de desempenho, verifique os gargalos da própria aplicação, como consultas ao banco de dados e lógica do código
    • Confira os limites de recursos do contêiner, como CPU e memória
    • Verifique o I/O de disco e a largura de banda da rede

    O mapeamento de portas é um dos recursos mais básicos do Docker e também um dos que mais causam problemas. Depois de entender o princípio e dominar o diagnóstico, você não precisará mais perder tempo com isso.

FAQ

Quais são os erros mais comuns no mapeamento de portas do Docker?
O erro mais comum ocorre quando a porta já está em uso (Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated). Isso impede a inicialização do contêiner e exige um diagnóstico da ocupação da porta.

Como diagnosticar:
• Use lsof -i :8080 para identificar quem ocupa a porta
• Use netstat -tuln | grep 8080 para verificar o estado da porta
• Use docker ps para conferir os mapeamentos de portas dos contêineres
• Use docker port container-name para consultar as portas do contêiner
Como diagnosticar uma porta que já está em uso?
Como diagnosticar:
• Use lsof -i :8080 para identificar quem ocupa a porta (lsof -i :8080)
• Use netstat -tuln | grep 8080 para verificar o estado da porta
• Use docker ps para conferir os mapeamentos de portas dos contêineres
• Use docker port container-name para consultar as portas do contêiner

Soluções:
• Encerre o processo que ocupa a porta (kill -9 PID)
• Pare o contêiner que ocupa a porta (docker stop container-name)
• Altere o mapeamento de portas (-p 8081:80)
• Use uma porta dinâmica (não especifique a porta do host e deixe o Docker escolher automaticamente)
Quais são as formas de mapear portas no Docker?
Sintaxe do mapeamento de portas:
• -p host_port:container_port (mapeia uma porta específica, como -p 8080:80)
• -p container_port (mapeia para uma porta aleatória, como -p 80)
• -P (mapeia todas as portas expostas)
• --publish-all (equivalente a -P)

Exemplos:
• docker run -d -p 8080:80 nginx (mapeia a porta 8080 do host para a porta 80 do contêiner)
• docker run -d -p 80 nginx (mapeia a porta 80 do contêiner para uma porta aleatória do host)
• docker run -d -P nginx (mapeia todas as portas expostas)
Quais são as boas práticas para o mapeamento de portas?
Boas práticas:
• Use docker-compose para gerenciar os mapeamentos de portas
• Configure faixas de portas para evitar conflitos
• Verifique periodicamente quais portas estão em uso
• Use uma ferramenta de varredura de portas para encontrar portas disponíveis

Otimização de desempenho:
• O mapeamento de portas, por si só, tem pouco custo de desempenho
• Se houver problemas de desempenho, verifique os gargalos da própria aplicação, como consultas ao banco de dados e lógica do código
• Confira os limites de recursos do contêiner, como CPU e memória
• Verifique o I/O de disco e a largura de banda da rede

O mapeamento de portas é um dos recursos mais básicos do Docker e também um dos que mais causam problemas. Depois de entender o princípio e dominar o diagnóstico, você não precisará mais perder tempo com isso.

11 min de leitura · Publicado em: 17 dez 2025 · Atualizado em: 4 set 2026

Comentários

Entre com GitHub para comentar

Easton BlogEaston Blog