Avant de marquer cette question comme doublon, veuillez noter que j'ai lu l'autre réponse et que cela n'a pas résolu mon problème.
J'ai un fichier de composition Docker contenant deux services :
version: "3" services: mysql: image: mysql:5.7 environment: MYSQL_HOST: localhost MYSQL_DATABASE: mydb MYSQL_USER: mysql MYSQL_PASSWORD: 1234 MYSQL_ROOT_PASSWORD: root ports: - "3307:3306" expose: - 3307 volumes: - /var/lib/mysql - ./mysql/migrations:/docker-entrypoint-initdb.d restart: unless-stopped web: build: context: . dockerfile: web/Dockerfile volumes: - ./:/web ports: - "3000:3000" environment: NODE_ENV: development PORT: 3000 links: - mysql:mysql depends_on: - mysql expose: - 3000 command: ["./wait-for-it.sh", "mysql:3307"]
/web/Dockerfile:
FROM node:6.11.1 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY package.json /usr/src/app/ RUN npm install COPY . /usr/src/app CMD [ "npm", "start" ]
Après docker-compose up --build
le service démarre, mais le script "wait-for-it.sh" expire en attendant le démarrage de MySQL (donc je ne l'utilise pas pour l'instant pendant le test de la base de données), j'attends juste que le la console montre que MySQL est prêt à accepter le transfert)
Lorsque MySQL est exécuté à partir de l'hôte, je peux utiliser Sequel Pro pour me connecter, interroger la base de données et obtenir des exemples d'enregistrements de ./mysql/migrations
Je peux également me connecter en SSH au conteneur MySQL en cours d'exécution et effectuer la même opération.
Cependant, mon application Node.js génère ECONNREFUSED 127.0.0.1:3307
Initialisation MySQL :
import * as mysql from 'promise-mysql' const config = { host: 'localhost', database: 'mydb', port: '3307', user: 'mysql', password: '1234', connectionLimit: 10 } export let db = mysql.createPool(config);
Requête MySQL :
import { db } from '../db/client' export let get = () => { return db.query('SELECT * FROM users', []) .then((results) => { return results }) .catch((e) => { return Promise.reject(e) }) }
La route appelée lorsque l'on clique sur l'url /
import { Router } from 'express'; import * as repository from '../repository' export let router = Router(); router.get('/', async (req, res) => { let users; try{ users = await repository.users.get(); } catch(e){ // ECONNREFUSED 127.0.0.1:3307 } res.render('index', { users: users }); });
Il est peu probable qu'il s'agisse d'une condition de concurrence car, en même temps que Node.js échoue, je peux interroger le conteneur Docker en cours d'exécution à l'aide de Sequel Pro ou SSH et l'interroger. Cela pourrait donc être le cas où Node.js ne peut pas accéder au conteneur MySQL ?
{ error: connect ECONNREFUSED 127.0.0.1:3307 code: 'ECONNREFUSED', errno: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 3307, fatal: true }
Ceci :
indique que Docker connectera le port
3307
端口映射到容器的3306
de l'hôte. Vous pouvez donc accéder à localhost:3307 depuis Sequel.Cependant, cela ne signifie pas que le conteneur écoute
3307
;事实上容器仍在监听3306
。当其他容器尝试访问mysql
DNS 时,它会被转换为内部容器 IP,因此您必须连接到3306
.La configuration de votre nœud devrait donc ressembler à ceci :
C'est dans votre docker-compose.yml :
Remarque :
wait-for-it.sh
Script de : https://github.com/vishnubob/wait-for-it