2
votes

Connexion refusée entre les conteneurs

J'ai essayé de lier un conteneur exécutant une application spring boot 2 à un conteneur exécutant mongo, mais la connexion est refusée

fichier docker-compose pour avoir un conteneur pour mongo (ajoutera plus tard un autre conteneur pour spring boot ici également )

version: '3.1'

services:
  springboot:
    build: .
    restart: always
    container_name: springboot
    ports:
      - 8182:8080
    working_dir: /opt/app
    depends_on:
      - mongo

  mongo:
    image: mongo
    container_name: springboot-mongo
    ports:
      - 27017:27017
    volumes:
      - $HOME/data/springboot-mongo-data:/data/db
      - $HOME/data/springboot-mongo-bkp:/data/bkp
    restart: always

dockerfile pour spring boot

FROM openjdk:11
RUN apt-get update && apt-get install bash
RUN mkdir -p /opt/app
ENV PROJECT_HOME /opt/app
COPY build/libs/recipe-book.jar $PROJECT_HOME/recipe-book.jar
WORKDIR $PROJECT_HOME
CMD ["java", "-Dspring.data.mongodb.uri=mongodb://springboot-mongo:27017/recipes", "-jar","./recipe-book.jar"]

J'ai essayé différentes manières d'envoyer la ligne de commande mongo uri: avec localhost au lieu de springboot-mongo, j'ai également essayé comment il est décrit ici https: // www.baeldung.com/spring-boot-command-line-arguments , plus spécifiquement -Dspring-boot.run.arguments = - spring.data.mongodb.uri = mongodb: // springboot- mongo: 27017 / recettes . À chaque fois qu'il semble avoir une connexion refusée.

Comment puis-je connecter le conteneur à ressort à mongo?

Merci

Mise à jour, j'ai également essayé ajouter le deuxième conteneur au fichier docker-compose, en tant que tel

version: '3.1'

services:
  mongo:
    image: mongo
    container_name: springboot-mongo
    ports:
      - 27017:27017
    volumes:
      - $HOME/data/springboot-mongo-data:/data/db
      - $HOME/data/springboot-mongo-bkp:/data/bkp
    restart: always

mise à jour 2:

J'ai réussi à résoudre partiellement le problème en construisant d'abord l'image localement sur mon ordinateur, puis en utilisant l'image créée dans le fichier docker-compose, et en ayant -Dspring.data.mongodb.uri = mongodb: // springboot-mongo: 27017 / recettes comme paramètre, mais toujours pas de chance de le construire directement dans le fichier docker-compose


7 commentaires

avez-vous essayé CMD ["java", "-Dspring.data.mongodb.uri = mongodb: // mongo: 27017 / recettes", "-jar", "./ recette-livre.jar"] ? (en remplacement de springboot-mongo par mongo)


Comment exécutez-vous le deuxième conteneur? L'ajoutez-vous au fichier docker-compose.yml ou exécutez-vous séparément docker run ? mongo (le nom du bloc services: ) fonctionne-t-il?


vous devez ajouter l'autre au fichier docker-compose pour obtenir son nom résolu dans l'autre


J'ai essayé de remplacer springboot-mongo par juste mongo, cela n'a pas fonctionné. J'appelais le deuxième conteneur avec docker run . J'ai essayé d'ajouter le deuxième conteneur au fichier docker-compose, cela ne semblait pas non plus avoir d'effet


@DavidMaze, si j'essaye mongo localhost: 27017 cela fonctionne, mais pas mongo springboot-mongo: 27017


L'application Spring Boot essaie-t-elle de laisser le temps à mongo de démarrer? Avez-vous vérifié que mongo fonctionne?


en commençant par docker-compose up , il dit toujours que le conteneur mongo est terminé avant même de démarrer le conteneur à ressort


3 Réponses :


3
votes

Si vous voulez que deux conteneurs se parlent, vous devez les placer dans le même réseau docker

mettez à jour votre fichier docker-compose.yml comme ceci:

version: '3.1'
services:
  springboot:
    build: .
    restart: always
    container_name: springboot
    ports:
      - 8182:8080
    working_dir: /opt/app
    depends_on:
      - mongo
    networks:
      - local

  mongo:
    image: mongo
    container_name: springboot-mongo
    ports:
      - 27017:27017
    volumes:
      - $HOME/data/springboot-mongo-data:/data/db
      - $HOME/data/springboot-mongo-bkp:/data/bkp
    restart: always
    networks:
      - local
networks:
  local:
    driver: bridge


3 commentaires

Et en effet cela fonctionne. Il faudra cependant examiner plus en détail le fonctionnement de docker et de son réseau. Merci beaucoup


Il n'est pas nécessaire de spécifier un réseau avec v2 et v3 de la syntaxe de fichier de composition. Les modes docker-compose et swarm créent un réseau par défaut pour le projet / la pile dont vous ne spécifiez pas un. Si vous essayez d'exécuter le même fichier de composition en mode essaim, la tentative de communication sur plusieurs nœuds sera interrompue car le réseau de superposition par défaut qui serait créé est désactivé.


J'ai le même réseau pour tous les conteneurs, mais j'obtiens toujours "connexion refusée"



0
votes

Si vous êtes

  • obtention de Connexion refusée lors d'une tentative de communication entre deux conteneurs
  • essayant de communiquer entre deux conteneurs de projets docker-compose différents et ne veulent pas utiliser le même réseau (car disons qu'ils auraient un conteneur PostgreSQL ou Redis sur le même port et vous préféreriez ne pas changer ces ports et ne pas l'utiliser sur le même réseau)
  • développer localement et vouloir imiter la communication entre deux projets de composition de docker
  • exécution de deux projets docker-compose sur localhost
  • développer en particulier des applications Django ou l'API Django Rest Framework (drf) et exécuter l'application dans un conteneur sur un port exposé

Et vous voulez

  • conteneur api_a communiquer avec api_b (ou vice versa) sans le même "réseau docker"

(exemple ci-dessous)

vous pouvez utiliser "hôte" du deuxième conteneur comme adresse IP de votre ordinateur et port qui est mappé depuis l'intérieur du conteneur Docker. Vous pouvez obtenir l'adresse IP de votre ordinateur avec ce script (à partir de: Recherche d'adresses IP locales en utilisant Python's stdlib ):

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_b
    image: api_b:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

Exemple:

project_api_a / docker-compose.yml : p >

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_a
    image: api_a:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

dans le conteneur api_a , vous exécutez l'application Django: manage.py runserver 0.0.0.0:8000

et deuxième docker-compose.yml d'un autre projet:

project_api_b / docker-compose- yml :

import socket
def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

dans le conteneur api_b , vous exécutez l'application Django: manage.py runserver 0.0.0.0:8001

Et en essayant de se connecter du conteneur api_a à api_b puis URL de api_b conteneur sera: http://:8001/

Cela peut être particulièrement utile si vous utilisez encore plus de deux (trois ou plus) projets docker-compose et qu'il est difficile de fournir un réseau commun pour tout cela - c'est une bonne solution de contournement et de solution


0 commentaires

0
votes

Si vous utilisez une référence à localhost dans le conteneur, utilisez --network = "host" lors de l'exécution de docker.


0 commentaires