Sebelum menandakan soalan ini sebagai pendua, sila ambil perhatian bahawa saya telah membaca jawapan yang lain, tetapi ia tidak menyelesaikan masalah saya.
Saya mempunyai fail karang Docker yang mengandungi dua perkhidmatan:
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" ]
Selepas docker-compose up --build
perkhidmatan bermula, tetapi skrip "wait-for-it.sh" tamat masa sementara menunggu mySQL bermula (jadi saya tidak menggunakannya buat masa ini semasa menguji sambungan DB), saya hanya tunggu sehingga konsol menunjukkan bahawa MySQL bersedia untuk menerima pemindahan masuk)
Apabila MySQL dijalankan daripada hos, saya boleh menggunakan Sequel Pro untuk log masuk dan menanyakan pangkalan data dan mendapatkan rekod sampel daripada ./mysql/migrations
Saya juga boleh SSH ke dalam bekas MySQL yang sedang berjalan dan melakukan operasi yang sama.
Walau bagaimanapun, apl Node.js saya menjana ECONNREFUSED 127.0.0.1:3307
Pemulaan 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);
Pertanyaan 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) }) }
Laluan dipanggil apabila url diklik /
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 }); });
Ini tidak mungkin menjadi syarat perlumbaan kerana pada masa yang sama Node.js gagal, saya boleh menanyakan bekas Docker yang sedang berjalan menggunakan Sequel Pro atau SSH dan menanyakannya. Jadi ini mungkin kes Node.js tidak dapat mengakses bekas MySQL?
{ error: connect ECONNREFUSED 127.0.0.1:3307 code: 'ECONNREFUSED', errno: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 3307, fatal: true }
Ini:
menunjukkan bahawa Docker akan menyambungkan
3307
端口映射到容器的3306
port hos. Jadi anda boleh mengakses localhost:3307 dari Sequel.Namun, ini tidak bermakna bekas itu mendengar
3307
;事实上容器仍在监听3306
。当其他容器尝试访问mysql
DNS 时,它会被转换为内部容器 IP,因此您必须连接到3306
.Jadi konfigurasi nod anda sepatutnya kelihatan seperti ini:
Ini ada dalam docker-compose.yml anda:
Nota:
wait-for-it.sh
Skrip daripada: https://github.com/vishnubob/wait-for-it