La petite question est: est-ce que je peux exécuter mongo à partir de mongo: dernière image sur un port différent de 27017 (par exemple sur 27018?)
Si oui, comment puis-je faire cela dans un fichier docker-compose.yml afin de pouvoir taper la commande suivante:
docker-compose run
La plus longue histoire:
J'ai une application en cours d'exécution dans l'instance AWS EC2. L'application se compose d'un mongodb et d'une application Web. Maintenant, j'ai décidé de séparer une partie de cette application dans son propre microservice fonctionnant dans le même conteneur AWS à l'intérieur du docker (deux conteneurs, l'un pour un autre mongo et l'autre pour une application Web). Je pense que le problème est que je ne peux pas faire fonctionner mongodb sur le port 27017 et, en même temps, un autre mongodb s'exécutant à l'intérieur d'un conteneur de menu fixe sur le port 27017. Non? J'ai cette hypothèse parce que lorsque j'arrête le premier mongo (mon application mongo), mon docker mongo fonctionne.
J'essaie donc de créer le deuxième mongo (celui qui se trouve dans le conteneur de docker), de l'exécuter sur un port différent et ma deuxième application Web (celle d'un autre conianter de docker), afin d'écouter mongo sur un autre port. Voici ma tentative de changer le fichier docker-compose:
version: '2'
services:
webapp:
image: myimage
ports:
- 3000:3000
mongo:
image: mongo:latest
ports:
- 27018:27018
Et dans ma nouvelle application, j'ai changé l'URL de mongo en:
monog_url = 'mongodb://mongo:27018'
client = MongoClient(monog_url, 27018)
Eh bien, pareil si je dis:
monog_url = 'mongodb://mongo:27018'
client = MongoClient(monog_url)
Mais lorsque je lance l'exécution de docker-compose, cela ne fonctionne toujours pas et j'obtiens les erreurs suivantes:
ERROR: for mongo driver failed programming external
connectivity on endpoint: Error starting userland proxy:
listen tcp 0.0.0.0:27017: bind: address already in use
Ou
pymongo.errors.ServerSelectionTimeoutError:
mongo:27018: [Errno -2] Name or service not known
J'ai résolu le problème, non pas en exécutant le conteneur dans un port différent, mais en apprenant une nouvelle fonctionnalité de docker-compose version 2, à savoir qu'il n'est pas nécessaire de spécifier des liens ou des réseaux. Les conteneurs nouvellement créés par défaut feront partie du réseau docker0 et pourront donc communiquer entre eux.
Comme Matt mentionné, nous pouvons exécuter des processus dans des conteneurs sur le même port. Ils devraient être isolés. Le problème ne peut donc pas être que le conteneur de menu fixe et l'hôte utilisent le même port. Le problème est peut-être qu'il y a une tentative de transfert d'un port utilisé dans l'hôte vers un autre port dans le conteneur.
Vous trouverez ci-dessous un fichier de composition de dockeur en état de fonctionnement:
version: '2'
services:
webapp:
image: myimage
ports:
- 3000:3000
mongo:
image: mongo:latest
J'ai regardé le mongo: le dernier fichier docker dans github et me suis rendu compte qu'ils exposaient 27017. Il n'est donc pas nécessaire de modifier le port ni de transférer les ports de l'hôte au conteneur mongo en cours d'exécution. Et l’URL mongo peut rester sur le même port:
monog_url = 'mongodb://mongo:27017'
client = MongoClient(monog_url, 27017)
Donc, la solution ci-dessus a résolu le problème, mais en ce qui concerne le titre de la question 'Docker lance l'image sur un autre port', la méthode la plus simple consiste simplement à modifier la composition du dock en:
version: '2'
services:
web:
image: myimage
mongo:
image: mongo:latest
command: mongod --port 27018
Mongo fonctionne maintenant sur 27018 et l'URL suivante est toujours accessible sur le Web:
monog_url = 'mongodb://mongo:27018'
client = MongoClient(monog_url, 27018)
Vous pouvez indiquer à MongoDB: écoute sur un autre port dans le fichier de configuration, ou en utilisant un paramètre de ligne de commande:
services:
mongo:
image: 'mongo:latest'
command: mongod --port 27018
ports:
- '27018:27018'
Vous pouvez exécuter des processus à l'intérieur d'un conteneur et à l'extérieur sur le même port. Vous pouvez même exécuter plusieurs conteneurs en utilisant le même port en interne. Ce que vous ne pouvez pas faire est de mapper l'un des ports de l'hôte vers un conteneur. Ou, dans votre, mappez un port déjà utilisé sur un conteneur.
Par exemple, cela fonctionnerait sur votre hôte:
services:
webapp:
image: myimage
ports:
- '3000:3000'
mongo:
image: 'mongo:latest'
ports:
- '27018:27017'
mongo2:
image: mongo:latest
ports:
- '27019:27017'
L'hôte Mongo écoute sur 27017. L'hôte également mappe les ports 27018 et 27019 sur les instances de conteneur mongo, les deux écoutant sur 27017 à l'intérieur du conteneur.
Chaque conteneur a son propre espace de nom de réseau et n'a aucun concept de ce qui est exécuté dans un autre conteneur ou sur l'hôte.
La webapp doit pouvoir se connecter au port interne des conteneurs mongo. Vous pouvez le faire sur un réseau de conteneurs qui autorise les connexions entre le conteneur et la résolution de noms pour chaque service.
services:
webapp:
image: myimage
ports:
- '3000:3000'
networks:
- myapp
depends_on:
- mongo
mongo:
image: 'mongo:latest'
ports:
- '27018:27017'
networks:
- myapp
networks:
myapp:
driver: bridge
Depuis votre application, l'URL mongo://mongo:27017
fonctionnera alors.
De votre hôte devez utiliser le port mappé et une adresse sur l'hôte, qui est normalement localhost
: mongo://localhost:27018