Colocando varios container docker numa só rede

Estou começando a entender melhor como os dockers funcionam, e tive um problema enorme em entender como um container acessa outro. Por exemplo precisei criar um container com PHP 8.1 e um container com PostgreSQL. Ambos são visíveis ao host, porem eles não se comunicam, foi então que entendi que eles precisam estar na mesma rede para que possam ser acessíveis facilmente

Para quem está começando, assim como eu, à usar docker, entender a visibilidade dos container é um problema. Principalmente porque você consegue enxergar o container do host, então seria meio óbvio que 2 containers também tivessem acesso entre eles. Porem não é bem assim.

Consegui começar a entender o funcionamento de forma mais simples, quando comecei a utilizar do docker compose para criar meus containers, e aconselho fortemente você a usa-lo também.

Para que os containers possam se comunicar, você precisa coloca-los na mesma rede, e a forma mais simples que eu achei para fazer isso, é definir o nome da rede que o container vai ingressar. Nada de comandos complexos.

Eu defini que meu serviço entraria na rede dockernet, e defini como essa rede funciona
version: '3.5'
services:

 postgres: 
 container_name: postgres
 image: postgres:11
 environment:
 - PGDATA=/var/lib/postgresql/11
 - POSTGRES_PASSWORD=senha
 - POSTGRES_USERNAME=postgres
 volumes:
 - /var/lib/postgresql/11:/var/lib/postgresql/11
 ports:
 - "5432:5432"
 restart: always
 networks:
 - dockernet

networks:
 dockernet:
 name: dockernet
 driver: bridge
Esse é meu
docker-compose.yml
Veja que defini que o serviço postgres, vai ingressar na rede dockernet, e logo após eu defino o que é essa rede

Agora posso criar outros serviços, por exemplo o PHP
version: '3.5'
services:

 php:
 container_name: php8.1-apache
 build: 
 context: ./php
 dockerfile: Dockerfile
 ports:
 - "80:80"
 - "443:443"
 volumes:
 - ~/www/:/var/www/html/
 environment:
 - ALLOW_OVERRIDE=true
 networks:
 - dockernet

networks:
 dockernet:
 name: dockernet
 driver: bridge
Veja que a definição da rede é a mesma, e eu também ingressei o serviço php à mesma rede.

E prontinho, agora os container conseguem se comunicar, usando o nome do serviço como host, ficando
SERVICO_NOME.NOME_REDE
. No meu caso,
postgres.dockernet
. Ou como eles estão na mesma rede, somente postgres.
$host= 'postgres.dockernet';
$db = 'andor';
$user = 'postgres';
$password = 'senha';
$dsn = "pgsql:host=$host;port=5432;dbname=$db;";
E feito!