Estou desenvolvendo um aplicativo django e tentando executá-lo dentro do docker. Tenho um problema que não consegui entender até agora. enquanto executa o aplicativo com docker-compose
, parece que o web
o aplicativo não pode se conectar ao banco de dados quando eu uso estas configurações:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "my_db",
"USER": "my_user",
"PASSWORD": "",
"HOST": "localhost",
"PORT": "5432",
}
mas uma vez que mudo o hospedeiro para postgres
, funciona. como isso
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "my_db",
"USER": "my_user",
"PASSWORD": "",
"HOST": "postgres",
"PORT": "5432",
}
qual é a diferença entre postgres
e localhost
. Um está funcionando sem um problema dentro do docker e não no ambiente de desenvolvimento no meu mac e o outro é o oposto.
# docker-compose.yml
version: "3"
services:
db:
image: postgres
expose:
- "5432"
web:
build: .
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
Respostas:
2 para resposta № 1Na verdade, o Docker Compose adiciona os nomes de host de todos os seus ligado recipientes entre si.
Em sua máquina, o banco de dados postgres está realmente rodando em localhost, é por isso que você tem o localhost
nome de anfitrião.
No Compose, ele está sendo executado no contêiner postgres, com o nome do host postgres
, é por isso que você tem o postgres
nome de anfitrião.
Se desejar, você pode criar uma entrada em seu arquivo host para redirecionar postgres
para localhost
, você só terá que usar postgres
em toda parte.
2 para resposta № 2
Cada contêiner docker vem com seu próprionamespace de rede por padrão. Esse namespace inclui sua própria interface de loopback privada, também conhecida como localhost. E eles também são anexados a redes dentro do docker, onde têm sua própria entrada DNS interna e podem se comunicar com outros contêineres na mesma rede.
Quando você executa seu aplicativo dentro de um contêiner com uma rede de ponte, localhost apontará para o contêiner, não para o host docker em que você está executando. O nome do host a ser usado depende do seu cenário:
- Para se comunicar com outros contêineres, use o nome do contêiner no DNS.
- Se for iniciado por docker-compose, use o nome do serviço para se comunicar com um dos contêineres desse serviço usando o rodízio DNS.
- Se for iniciado dentro do modo de enxame, você pode usar o nome do serviço lá para ir para um VIP que equilibra a carga round robin para todos os contêineres que fornecem esse serviço.
- E se você precisar falar com o próprio host docker, use um endereço IP sem loopback do host docker.