Rede entre containers
localhost dentro de um container não é a mesma coisa que localhost na sua máquina.
A confusão mais comum de quem começa com Docker: um container tentando se conectar em localhost:5432 achando que vai alcançar o Postgres que está rodando noutro container. Não vai — localhost dentro de um container aponta pro próprio container, não pra sua máquina nem pros outros containers.
Por que docker-compose resolve isso sozinho
Quando você sobe serviços via docker-compose.yml, o Compose cria automaticamente uma rede privada e registra cada serviço nela com um DNS interno — o nome do serviço vira um hostname que os outros containers da mesma rede conseguem resolver.
services:
api:
build: .
environment:
DATABASE_URL: postgres://postgres:postgres@db:5432/app # "db", não "localhost"
db:
image: postgres:16-alpineping dbdb resolve pro IP interno do container do Postgres — sem você configurar IP nenhum manualmente, porque os dois estão na mesma rede que o Compose criou.
Publicando porta pro mundo externo
Isso é diferente de "publicar" uma porta. ports: ["3000:3000"] expõe a porta do container pra fora do Docker, acessível via localhost:3000 da sua máquina de verdade. Serviços internos (como o banco) normalmente não precisam disso — só a API, que o navegador acessa.
services:
api:
ports:
- "3000:3000" # acessível de fora — o navegador bate aqui
db:
image: postgres:16-alpine
# sem "ports:" — só "api" precisa falar com "db", e eles já se enxergam pela rede internaExercício
Um container "worker" (processamento em background) precisa falar com o Redis do compose, mas ninguém de fora precisa acessar o worker nem o Redis diretamente. O que muda no ports: de cada um?