NodeJS Docker容器连接WSL SSH报ECONNREFUSED 127.0.0.1:22如何解决
问题描述
我在NodeJS中使用node-ssh模块发起SSH连接,运行环境为WSL Ubuntu 18,使用docker-compose编排服务。我已经在/etc/ssh/sshd_config中将PasswordAuthentication设为yes,在WSL Ubuntu内部可以正常连接SSH,但从容器化的NodeJS项目中发起连接时,报错ECONNREFUSED 127.0.0.1:22。
相关配置
NodeJS连接代码
const Client = require('node-ssh').NodeSSH; var client = new Client(); client.connect({ host : 'localhost', port : 22, username : req.body.username, password : req.body.password, keepaliveInterval : 30 * 1000, // 闲置30分钟,单位毫秒 keepaliveCountMax : 1, }).then(()=>{ // 登录成功 }).catch((e)=>{ console.log(e); // ECONNREFUSED 错误 // 登录失败 });
docker-compose.yml配置
version: '3.8' services: api: build: dockerfile: Dockerfile context: "./server" ports: - "3030:3030" depends_on: - mysql_db volumes: - /app/node_modules - ./server:/app ...
初始API服务Dockerfile
FROM node:alpine WORKDIR /app COPY package.json ./ COPY package-lock.json ./ COPY ./ ./ RUN npm i RUN apk update \ && apk add openssh-server COPY sshd_config /etc/ssh/ EXPOSE 22 CMD ["npm", "run", "start"]
第一次更新Dockerfile
FROM node:alpine WORKDIR /app COPY package.json ./ COPY package-lock.json ./ COPY ./ ./ RUN npm i \ && apk add --update openssh \ && rm -rf /tmp/* /var/cache/apk/* COPY sshd_config /etc/ssh/ # 添加入口点脚本 ADD ./docker-entrypoint.sh /usr/local/bin # 清理旧密钥生成新密钥 RUN rm -rf /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key EXPOSE 22 ENTRYPOINT ["docker-entrypoint.sh"] CMD ["/usr/sbin/sshd","-D"]
第二次更新Dockerfile
FROM node:alpine WORKDIR /app COPY package.json ./ COPY package-lock.json ./ COPY ./ ./ RUN npm i RUN apk update && \ apk add openssh-client \ && rm -rf /tmp/* /var/cache/apk/* EXPOSE 22 CMD ["npm", "run", "start"]
解决方案
修改Dockerfile和NodeJS代码即可解决:将连接host改为host.docker.internal(WSL2环境下生效),同时将Docker基础镜像从node:alpine替换为node:latest,即可从容器内成功连接WSL的SSH服务。
修复后代码
NodeJS连接代码
const Client = require('node-ssh').NodeSSH; var client = new Client(); client.connect({ host : 'host.docker.internal', // WSL2环境下生效 port : 22, username : req.body.username, password : req.body.password, keepaliveInterval : 30 * 1000, // 闲置30分钟,单位毫秒 keepaliveCountMax : 1, }).then(()=>{ // 登录成功 }).catch((e)=>{ console.log(e); // ECONNREFUSED 错误 // 登录失败 });
修复后Dockerfile
FROM node:latest WORKDIR /app COPY package.json ./ COPY package-lock.json ./ COPY ./ ./ RUN npm i RUN apt-get update EXPOSE 22 CMD ["npm", "run", "start"]
内容的提问来源于stack exchange,提问作者rewrewty1
相关产品推荐
相关产品推荐

