docker-compose ne parvient pas à créer le composant Web car il ne peut pas se connecter au composant db précédemment créé
Mac OSX 10.13.6, conda 4.5.11, Python 3.6.8, Docker version 18.09.1, docker-compose version 1.23.2
django 1.8.3 est installé avec requirements.txt depuis Dockerfile. Pas la liberté de mettre à jour.
Plusieurs discussions très similaires sur SO n'ont pas aidé (comme celle-ci: Docker-compose avec django n'a pas pu traduire le nom d'hôte" db "en adresse: nom ou service inconnu ).
J'ai un docker-compose.yml
avec un réseau et deux composants:
docker build -t myapp-web .
Dans mes paramètres .py
J'ai la section DATABASES:
$ docker container ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c110e8361cda postgres:10 "docker-entrypoint.sâ¦" 4 hours ago Up 4 hours 0.0.0.0:5432->5432/tcp myapp-db
Quand j'exécute $ docker-compose up -d
,
la première image (db) est créée et son conteneur démarre.
Peut voir qu'il est en cours d'exécution et à l'écoute sur le port 5432 avec docker ps
et lsof
. La même chose se produit si je supprime le composant web:
du fichier docker-compose.yml
Maintenant, le deuxième composant (web) a Dockerfile qui contient ces deux lignes (parmi beaucoup d'autres):
expose: - "5432"
Le "migrate" comme meurt avec cette erreur:
Traceback (most recent call last): File "/usr/local/lib/python3.6/site-packages/django/db/backends/base/base.py", line 130, in ensure_connection self.connect() File "/usr/local/lib/python3.6/site-packages/django/db/backends/base/base.py", line 119, in connect self.connection = self.get_new_connection(conn_params) File "/usr/local/lib/python3.6/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 176, in get_new_connection connection = Database.connect(**conn_params) File "/usr/local/lib/python3.6/site-packages/psycopg2/__init__.py", line 130, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: could not connect to server: Connection refused Is the server running on host "db" (37.34.32.51) and accepting TCP/IP connections on port 5432?
fatigué à plusieurs ajustements.
* a changé la version '3.7'
* ajouté à la section db
RUN python manage.py makemigrations myapp RUN python manage.py migrate
dépend de:
- "db"
liens:
- "db"
environnement:
PRODUCTION: 'faux'
settings.py
en nom de conteneur, en nom d'image, en balises, en identifiant de conteneur, en «localhost», en «127.0.0.1», etc. l'erreur est le idem, en mentionnant simplement le nouveau nom HOST au lieu de "db" --build
( docker-compose up -d --build
) élagué le système docker
et exécuté à nouveau C'est la même erreur.
MISE À JOUR: Après avoir suggéré que docker-compose ne fonctionne pas de cette façon, j'ai essayé de le diviser en deux tâches distinctes. Je construis d'abord mon conteneur myapp-db et je m'assure qu'il fonctionne sur le bon port:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': INSTANCE_NAME, 'USER': 'postgres', 'PASSWORD': 'postgres', 'HOST': 'db', 'PORT': '5432' }, }
Ensuite, je construis myapp-web:
version: '3' networks: bridge: driver: bridge services: db: image: postgres:10 container_name: myapp-db volumes: - ./postgres_data:/var/lib/postgresql/data/ ports: - "5432:5432" environment: POSTGRES_DB: actionability-master POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres networks: - bridge web: restart: unless-stopped container_name: myapp-web build: . command: /start_gunicorn.sh ports: - "8080:8080" environment: PRODUCTION: 'true' networks: - bridge
3 Réponses :
Je sais que cela peut sembler très basique, mais pourquoi ne pas envisager une convention de dénomination légèrement plus sophistiquée, puis ajouter simplement ces noms à votre service DNS sur l'hôte, ou du moins aux enregistrements A?
Ensuite, le système peut accéder à la base de données par nom ou par IP. Juste une pensée.
Grands choix et combinaison de plate-forme et de langages btw, Django + PostgreSQL sont mes préférés. Je recommanderais également Bootstrap, surtout si vous recherchez des capacités de déploiement rapide d'outils.
vous voulez dire au lieu de «db» et «web», appelez-les quelque chose de plus descriptif? Désolé, je n'ai pas compris comment cela va aider le fait que le Web ne voit pas la base de données? L'entrée 'HOST': 'db'
dans le fichier settings.py doit pouvoir être résolue.
Les systèmes doivent encore pouvoir communiquer entre eux. C'est peut-être un problème IP, mais une approche basée sur le DNS peut le résoudre. J'ai vu cela auparavant à partir d'autres problèmes avec docker dans le passé, y compris d'autres messages ici.
Comme note supplémentaire, Id recommande de créer des nœuds physiques de vos bases de données au lieu de conteneurs docker. Les bases de données subissent une baisse des performances lorsqu'elles sont ancrées. Ce sera mieux pour eux en termes de performances à long terme si vous créez simplement des clusters physiques et que vous les exécutez Master-Slave ou Master-Master.
J'utilise la liste depend_on
pour démarrer le conteneur db avant le conteneur Web et les liens
pour m'assurer que les noms d'hôte peuvent être résolus.
J'ajoute le suivant sur le Web:
services: db: # ... web: links: - "db:db" # resolve the hostname "db" with the ip of the db container depends_on: - db # start db before web
Vous pouvez essayer cette configuration avec des alias de réseau.
version: '3.5' services: db: image: postgres:10 container_name: myapp-db volumes: - ./postgres_data:/var/lib/postgresql/data/ expose: - "5432" environment: POSTGRES_DB: actionability-master POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres networks: services-network: aliases: - db web: restart: unless-stopped container_name: myapp-web build: . command: /start_gunicorn.sh ports: - "8080:8080" environment: PRODUCTION: 'true' depends_on: - db networks: services-network: aliases: - web networks: services-network: name: services-network driver: bridge
le deuxième composant (web) a Dockerfile qui contient ces deux lignes
, est-ce un Dockerfile dans le conteneur Web en cours d'exécution, ou le Dockerfile de le conteneur Web?Vos commandes RUN sont toujours exécutées au moment de BUILD, pas au moment de l'exécution. Par conséquent, votre base de données n'existera pas lorsque vous créez l'image car il n'y a pas de base de données. Donc tu ne peux pas le faire de cette façon
Merci @SvenHakvoort, je pense que je l'ai compris. docker-compose ne fonctionne pas de cette façon, le fait que le composant db soit avant le conteneur Web dans le fichier docker-compose.yml ne signifie pas que son conteneur est déjà opérationnel lorsque le conteneur Web est en cours de construction, non?
@bluescores c'est Dockerfile du composant Web qui fait construire son image et démarrer son conteneur (si cela fonctionne :-)) par docker-compose